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(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);
36 if( CHECKRC(rc, RC_LISTING)) {
37 from = date = subject = 0;
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.
79 char buf[255], *malleable;
82 DPF((DFA,"Retrieving list of messages from the server."));
87 if( CHECKRC(rc, RC_LISTING) ) {
93 malleable = (char *)CxMalloc(strlen(buf) + 1);
94 strcpy(malleable,buf);
95 DPF((DFA,"%s",malleable));
97 msgs = (CXLIST) CxLlInsert(msgs,malleable);
109 ** CxMsLoad(): Retrieve a message from the server. Expects a MESSAGE_ID,
110 ** returns 0 on success, [err] on failure.
113 ** preserve_newlines: Preserve newline delimiters in body text?
115 ** CLIENT MUST free(toret.body) MANUALLY!!!!
117 int CxMsLoad(const char *mid, int preserve_newlines, MESGINFO *toret) {
118 char buf[255], *newline="\n";
119 int rc, message_contents = 0, line_width;
121 DPF((DFA,"Loading message \"%s\"",mid));
122 toret->message_id = 0;
123 toret->author[0] = 0;
126 toret->subject[0] = 0;
128 sprintf(buf,"MSG2 %s",mid);
131 if(CHECKRC(rc, RC_LISTING) ) {
132 DPF((DFA,"RC_LISTING"));
136 if(buf[strlen(buf)-1]=='\r')
137 buf[strlen(buf)-1]=0;
139 DPF((DFA,"[%d] buf: %s", rc, buf));
141 if(strstr(buf,"From:") &&
143 strcpy(toret->author, buf+5);
145 } else if((strstr(buf,"To:") == (char *)&buf) &&
147 strcpy(toret->rcpt, buf+3);
149 } else if(strstr(buf,"X-UIDL:")
150 && !message_contents) {
151 DPF((DFA,"Message ID: %s",buf+7));
152 toret->message_id = atoi(buf+7);
154 } else if(strstr(buf,"X-Citadel-Room:")
155 && !message_contents) {
156 DPF((DFA,"Room: %s",buf+15));
157 strcpy(toret->room, buf+15);
159 strlen(toret->room)-1
162 } else if(strstr(buf,"Subject:")
163 && !message_contents) {
164 strcpy(toret->subject, buf+8);
166 } else if(strstr(buf,"Path:")
167 && !message_contents) {
168 strcpy(toret->path, buf+5);
170 } else if(strstr(buf,"Node:")
171 && !message_contents) {
172 strcpy(toret->node, buf+5);
174 } else if((strstr(buf,"Date:") == (char *)&buf)
175 && !message_contents) {
176 strcpy(toret->date, buf+5);
178 } else if((buf[0] == 0) || (buf[0] == '\r') ||
180 message_contents = 1;
183 ** ugliness. Load entire message. Ick.
191 line_width = strlen(buf);
194 ** Start by stripping out the CR.
196 *(strchr(buf,'\r')) = 0;
197 if(preserve_newlines)
198 line_width+=strlen(newline);
199 line_width++; /** Count NULL. **/
202 toret->body = (char *)CxMalloc(
206 strcpy(toret->body, buf);
209 toret->body = (char *) realloc(
215 strcat(toret->body, buf);
219 ** If we are to preserve the newlines
220 ** present in the message, then append
221 ** a newline to the end of each line.
223 if(preserve_newlines)
224 strcat(toret->body, newline);
232 DPF((DFA,"RC_LISTING completed."));
235 DPF((DFA,"[Return Data]"));
236 DPF((DFA,"toret->message_id: %d\n",toret->message_id));
237 DPF((DFA,"toret->author: %s\n",toret->author));
238 DPF((DFA,"toret->room: %s\n",toret->room));
242 ** If this message has been loaded, we succeeded.
244 if(toret->message_id) {
245 DPF((DFA,"Returning [SUCCESS]"));
249 ** Otherwise, we failed.
252 DPF((DFA,"Returning [ENOMSG]"));
258 ** CxMsSaveOk(): Verify that users can post to this room. Returns 1 if posting is
259 ** allowed, 0 if posting is not allowed.
261 int CxMsSaveOk(const char *username) {
265 DPF((DFA,"Checking room for post permissions..."));
266 sprintf(buf,"ENT0 0|%s|0|0",username);
269 if(CHECKRC(rc, RC_OK) ) {
270 DPF((DFA,"Ok for posting"));
274 DPF((DFA,"Not Ok for posting [%d]",rc));
282 ** CxMsSave(): Save (post/send) a message to the server. Expects a fully quantified
283 ** MESGINFO struct. Returns 0 on success, [err] on failure.
285 ** 1: No room specified
286 ** 2: Posting not allowed in this room.
287 ** 3: Message rejected for unknown reasons.
290 int CxMsSave(MESGINFO msg) {
294 DPF((DFA,"Preparing to save message to server..."));
297 DPF((DFA,"Returning [ENOROOM]"));
301 DPF((DFA,"Checking for access..."));
302 sprintf(buf,"ENT0 0|%s|0|0",msg.rcpt);
305 DPF((DFA,"Server said [%s]",buf));
307 if( CHECKRC(rc, RC_OK)) {
308 DPF((DFA,"Permission to save"));
310 sprintf(buf,"ENT0 1|%s|0|4|",msg.rcpt);
314 if( CHECKRC(rc, RC_SENDLIST)) {
315 DPF((DFA,"Sending message to server..."));
316 sprintf(buf, "From: %s", msg.author);
318 sprintf(buf, "To: %s", msg.rcpt);
320 sprintf(buf, "X-Mailer: libCxClient %s", CXREVISION);
322 sprintf(buf, "Subject: %s", msg.subject);
330 DPF((DFA,"Server accepted message"));
335 DPF((DFA,"No permission to save!"));