2 ** libCxClient - Citadel/UX Extensible Client API
3 ** Copyright (c) 2000, Flaming Sword Productions
4 ** Copyright (c) 2001, The Citadel/UX Consortium
9 ** Last Revision: 2000-10-15
10 ** Description: Functions which manipulate (build) message lists.
21 ** CxMsInfo(): Retrieve message information for all of the message id's listed inside
24 CXLIST CxMsInfo(int id, CXLIST msg_list) {
25 CXLIST mp, messages = NULL;
26 char buf[255], *from, *date, *subject;
29 DPF((DFA,"Retreiving information for all messages in 0x%08x",msg_list));
33 sprintf(buf,"MSG0 %s|1",mp->data);
35 rc = CxClRecv(id, buf);
36 if( CHECKRC(rc, RC_LISTING)) {
37 from = date = subject = 0;
40 rc = CxClRecv(id, buf);
41 if(rc && strstr(buf,"from=")) {
42 DPF((DFA, "from: %s",buf));
44 from = (char *)CxMalloc(strlen(buf+5)+1);
47 } else if(rc && strstr(buf,"time=")) {
49 DPF((DFA, "time: %s",buf));
50 date = (char *)CxMalloc(strlen(buf+5)+1);
56 if((from && *from) && (date && *date)) {
57 sprintf(buf,"%s|%s|%s",from,date,subject);
58 DPF((DFA, "insert-> %s",buf));
60 messages = (CXLIST) CxLlInsert(messages,buf);
61 DPF((DFA, "Freeing memory (temp vars)"));
62 if(subject) CxFree(subject);
63 if(from) CxFree(from);
64 if(date) CxFree(date);
75 ** CxMsList(): Retrieve a list of messages in the current room.
77 CXLIST CxMsList(int id, int list_type, int number_messages) {
79 char buf[255], *malleable;
82 DPF((DFA,"Retrieving list of messages from the server."));
90 CxClSend( id, "MSGS NEW");
94 CxClSend( id, "MSGS");
97 rc = CxClRecv( id, buf );
99 if( CHECKRC(rc, RC_LISTING) ) {
102 rc = CxClRecv(id, buf);
105 malleable = (char *)CxMalloc(strlen(buf) + 1);
106 strcpy(malleable,buf);
107 DPF((DFA,"%s",malleable));
109 msgs = (CXLIST) CxLlInsert(msgs,malleable);
121 ** CxMsLoad(): Retrieve a message from the server. Expects a MESSAGE_ID,
122 ** returns 0 on success, [err] on failure.
125 ** preserve_newlines: Preserve newline delimiters in body text?
127 ** CLIENT MUST free(toret.body) MANUALLY!!!!
129 int CxMsLoad(int id, unsigned long int mid, int preserve_newlines, MESGINFO *toret) {
130 char buf[255], *newline="\n";
131 int rc, message_contents = 0, line_width;
133 DPF((DFA,"Loading message \"%ld\"",mid));
134 toret->message_id = 0;
135 toret->author[0] = 0;
138 toret->subject[0] = 0;
140 sprintf(buf,"MSG2 %ld",mid);
142 rc = CxClRecv(id, buf);
143 if(CHECKRC(rc, RC_LISTING) ) {
144 DPF((DFA,"RC_LISTING"));
146 rc = CxClRecv(id, buf);
148 if(buf[strlen(buf)-1]=='\r')
149 buf[strlen(buf)-1]=0;
151 DPF((DFA,"[%d] buf: %s", rc, buf));
153 if(strstr(buf,"From:") &&
155 strcpy(toret->author, buf+5);
157 } else if((strstr(buf,"To:") == (char *)&buf) &&
159 strcpy(toret->rcpt, buf+3);
161 } else if(strstr(buf,"X-UIDL:")
162 && !message_contents) {
163 DPF((DFA,"Message ID: %s",buf+7));
164 toret->message_id = atoi(buf+7);
166 } else if(strstr(buf,"X-Citadel-Room:")
167 && !message_contents) {
168 DPF((DFA,"Room: %s",buf+15));
169 strcpy(toret->room, buf+15);
171 strlen(toret->room)-1
174 } else if(strstr(buf,"Subject:")
175 && !message_contents) {
176 strcpy(toret->subject, buf+8);
178 } else if(strstr(buf,"Path:")
179 && !message_contents) {
180 strcpy(toret->path, buf+5);
182 } else if(strstr(buf,"Node:")
183 && !message_contents) {
184 strcpy(toret->node, buf+5);
186 } else if((strstr(buf,"Date:") == (char *)&buf)
187 && !message_contents) {
188 strcpy(toret->date, buf+5);
190 } else if((buf[0] == 0) || (buf[0] == '\r') ||
192 message_contents = 1;
195 ** ugliness. Load entire message. Ick.
199 rc = CxClRecv(id, buf);
203 line_width = strlen(buf);
206 ** Start by stripping out the CR.
208 *(strchr(buf,'\r')) = 0;
209 if(preserve_newlines)
210 line_width+=strlen(newline);
211 line_width++; /** Count NULL. **/
214 toret->body = (char *)CxMalloc(
218 strcpy(toret->body, buf);
221 toret->body = (char *) realloc(
227 strcat(toret->body, buf);
231 ** If we are to preserve the newlines
232 ** present in the message, then append
233 ** a newline to the end of each line.
235 if(preserve_newlines)
236 strcat(toret->body, newline);
244 DPF((DFA,"RC_LISTING completed."));
247 DPF((DFA,"[Return Data]"));
248 DPF((DFA,"toret->message_id: %d\n",toret->message_id));
249 DPF((DFA,"toret->author: %s\n",toret->author));
250 DPF((DFA,"toret->room: %s\n",toret->room));
254 ** If this message has been loaded, we succeeded.
256 if(toret->message_id) {
257 DPF((DFA,"Returning [SUCCESS]"));
261 ** Otherwise, we failed.
264 DPF((DFA,"Returning [ENOMSG]"));
270 ** CxMsSaveOk(): Verify that users can post to this room. Returns 1 if posting is
271 ** allowed, 0 if posting is not allowed.
273 int CxMsSaveOk(int id, const char *username) {
277 DPF((DFA,"Checking room for post permissions..."));
278 sprintf(buf,"ENT0 0|%s|0|0",username);
280 rc = CxClRecv(id, buf);
281 if(CHECKRC(rc, RC_OK) ) {
282 DPF((DFA,"Ok for posting"));
286 DPF((DFA,"Not Ok for posting [%d]",rc));
294 ** CxMsSave(): Save (post/send) a message to the server. Expects a fully quantified
295 ** MESGINFO struct. Returns 0 on success, [err] on failure.
297 ** 1: No room specified
298 ** 2: Posting not allowed in this room.
299 ** 3: Message rejected for unknown reasons.
302 int CxMsSave(int id, MESGINFO msg) {
306 DPF((DFA,"Preparing to save message to server..."));
309 DPF((DFA,"Returning [ENOROOM]"));
313 DPF((DFA,"Checking for access..."));
314 sprintf(buf,"ENT0 0|%s|0|0",msg.rcpt);
316 rc = CxClRecv(id, buf);
317 DPF((DFA,"Server said [%s]",buf));
319 if( CHECKRC(rc, RC_OK)) {
320 DPF((DFA,"Permission to save"));
322 sprintf(buf,"ENT0 1|%s|0|4|",msg.rcpt);
325 rc = CxClRecv(id, buf);
326 if( CHECKRC(rc, RC_SENDLIST)) {
327 DPF((DFA,"Sending message to server..."));
328 sprintf(buf, "From: %s", msg.author);
330 sprintf(buf, "To: %s", msg.rcpt);
332 sprintf(buf, "X-Mailer: libCxClient %s", CXREVISION);
334 sprintf(buf, "Subject: %s", msg.subject);
337 CxClSend(id, msg.body);
342 DPF((DFA,"Server accepted message"));
347 DPF((DFA,"No permission to save!"));
355 ** CxMsMark(): Mark message(s) as read.
357 void CxMsMark( int id, long unsigned int msgid ) {
361 DPF((DFA, "Marking message %s read.", msgid));
363 if( msgid == MSGS_ALL ) {
364 sprintf( buf, "SLRP highest" );
367 sprintf( buf, "SLRP %ld", msgid );
371 rc = CxClRecv( id, buf );
377 DPF((DFA, "Failed."));