From c971049374441fd18ded28f0a3be75b9f215be75 Mon Sep 17 00:00:00 2001 From: Michael Hampton Date: Thu, 16 Jan 2003 10:04:04 +0000 Subject: [PATCH] * ENT0 command: changed post-as username from arg 4 to arg 5; 4 was already used as the message subject * Convert message entry and reading to new IPC code * Minor bugfixes throughout IPC code --- citadel/ChangeLog | 7 ++ citadel/citadel.c | 17 ++-- citadel/citadel_ipc.c | 55 +++++++---- citadel/citadel_ipc.h | 21 +++- citadel/commands.c | 25 +---- citadel/messages.c | 191 ++++++++++++++++++++---------------- citadel/messages.h | 3 +- citadel/msgbase.c | 2 +- citadel/techdoc/session.txt | 6 +- 9 files changed, 187 insertions(+), 140 deletions(-) diff --git a/citadel/ChangeLog b/citadel/ChangeLog index 328593fdb..4a78156b7 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,10 @@ $Log$ + Revision 601.113 2003/01/16 10:04:03 error + * ENT0 command: changed post-as username from arg 4 to arg 5; 4 was already + used as the message subject + * Convert message entry and reading to new IPC code + * Minor bugfixes throughout IPC code + Revision 601.112 2003/01/16 04:17:02 ajc * citadel_ipc.c: when issuing a SPEX command, send the string value for room/floor/site instead of the number. citserver wants a string. @@ -4396,3 +4402,4 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant Fri Jul 10 1998 Art Cancro * Initial CVS import + diff --git a/citadel/citadel.c b/citadel/citadel.c index a260b42f4..db25b2d17 100644 --- a/citadel/citadel.c +++ b/citadel/citadel.c @@ -1268,9 +1268,9 @@ NEWUSR: if (strlen(rc_password) == 0) { uglistsize = 0; if (newnow == 1) - readmsgs(ipc, 3, 1, 5); + readmsgs(ipc, LastMessages, ReadForward, 5); else - readmsgs(ipc, 1, 1, 0); + readmsgs(ipc, NewMessages, ReadForward, 0); /* MAIN COMMAND LOOP */ do { @@ -1335,22 +1335,23 @@ NEWUSR: if (strlen(rc_password) == 0) { dotungoto(ipc, argbuf); break; case 10: - readmsgs(ipc, 0, 1, 0); + readmsgs(ipc, AllMessages, ReadForward, 0); break; case 9: - readmsgs(ipc, 3, 1, 5); + readmsgs(ipc, LastMessages, ReadForward, 5); break; case 13: - readmsgs(ipc, 1, 1, 0); + readmsgs(ipc, NewMessages, ReadForward, 0); break; case 11: - readmsgs(ipc, 0, (-1), 0); + readmsgs(ipc, AllMessages, ReadReverse, 0); break; case 12: - readmsgs(ipc, 2, (-1), 0); + readmsgs(ipc, OldMessages, ReadReverse, 0); break; case 71: - readmsgs(ipc, 3, 1, atoi(argbuf)); + readmsgs(ipc, LastMessages, ReadForward, + atoi(argbuf)); break; case 7: forget(ipc); diff --git a/citadel/citadel_ipc.c b/citadel/citadel_ipc.c index a7e185f8f..53c9f7f64 100644 --- a/citadel/citadel_ipc.c +++ b/citadel/citadel_ipc.c @@ -407,15 +407,15 @@ int CtdlIPCGotoRoom(CtdlIPC *ipc, const char *room, const char *passwd, /* MSGS */ /* which is 0 = all, 1 = old, 2 = new, 3 = last, 4 = first, 5 = gt, 6 = lt */ /* whicharg is number of messages, applies to last, first, gt, lt */ -int CtdlIPCGetMessages(CtdlIPC *ipc, int which, int whicharg, - const char *mtemplate, long **mret, char *cret) +int CtdlIPCGetMessages(CtdlIPC *ipc, enum MessageList which, int whicharg, + const char *mtemplate, unsigned long **mret, char *cret) { register int ret; register unsigned long count = 0; static char *proto[] = { "ALL", "OLD", "NEW", "LAST", "FIRST", "GT", "LT" }; char aaa[33]; - char *bbb; + char *bbb = NULL; size_t bbbsize; if (!cret) return -2; @@ -431,19 +431,25 @@ int CtdlIPCGetMessages(CtdlIPC *ipc, int which, int whicharg, (mtemplate) ? 1 : 0); if (mtemplate) count = strlen(mtemplate); ret = CtdlIPCGenericCommand(ipc, aaa, mtemplate, count, &bbb, &bbbsize, cret); + if (ret / 100 != 1) + return ret; count = 0; - while (strlen(bbb)) { - int a; - + *mret = (unsigned long *)malloc(sizeof(unsigned long)); + if (!*mret) + return -1; + while (bbb && strlen(bbb)) { extract_token(aaa, bbb, 0, '\n'); - a = strlen(aaa); - memmove(aaa, bbb + a + 1, strlen(bbb) - a - 1); - *mret = (long *)realloc(mret, - (size_t)((count + 1) * sizeof (long))); - if (*mret) - *mret[count++] = atol(aaa); - *mret[count] = 0L; + remove_token(bbb, 0, '\n'); + *mret = (unsigned long *)realloc(*mret, (size_t)((count + 2) * + sizeof (unsigned long))); + if (*mret) { + (*mret)[count++] = atol(aaa); + (*mret)[count] = 0L; + } else { + break; + } } + if (bbb) free(bbb); return ret; } @@ -809,8 +815,8 @@ int CtdlIPCPostMessage(CtdlIPC *ipc, int flag, const struct ctdlipcmessage *mr, aaa = (char *)malloc(strlen(mr->recipient) + strlen(mr->author) + 40); if (!aaa) return -1; - sprintf(aaa, "ENT0 %d|%s|%d|%d|%s", flag, mr->recipient, mr->anonymous, - mr->type, mr->author); + sprintf(aaa, "ENT0 %d|%s|%d|%d|%s|%s", flag, mr->recipient, + mr->anonymous, mr->type, mr->subject, mr->author); ret = CtdlIPCGenericCommand(ipc, aaa, mr->text, strlen(mr->text), NULL, NULL, cret); free(aaa); @@ -1972,6 +1978,19 @@ int CtdlIPCInternalProgram(CtdlIPC *ipc, int secret, char *cret) } +/* FSCK */ +int CtdlIPCMessageBaseCheck(CtdlIPC *ipc, char **mret, char *cret) +{ + size_t size = 0; + + if (!cret) return -2; + if (!mret) return -2; + if (*mret) return -2; + + return CtdlIPCGenericCommand(ipc, "FSCK", NULL, 0, mret, &size, cret); +} + + /* * Not implemented: * @@ -2017,15 +2036,13 @@ char *CtdlIPCReadListing(CtdlIPC *ipc, char *dest) { size_t length = 0; size_t linelength; - char *ret; + char *ret = NULL; char aaa[SIZ]; ret = dest; if (ret != NULL) { length = strlen(ret); - } - else { - ret = strdup(""); + } else { length = 0; } diff --git a/citadel/citadel_ipc.h b/citadel/citadel_ipc.h index a7e1b7b0a..314e6baa2 100644 --- a/citadel/citadel_ipc.h +++ b/citadel/citadel_ipc.h @@ -132,7 +132,20 @@ enum RoomList { AllPublicRooms, }; #define AllFloors -1 - +enum MessageList { + AllMessages, + OldMessages, + NewMessages, + LastMessages, + FirstMessages, + MessagesGreaterThan, + MessagesLessThan, +}; +enum MessageDirection { + ReadReverse = -1, + ReadForward = 1, +}; + /* Shared Diffie-Hellman parameters */ #define DH_P "1A74527AEE4EE2568E85D4FB2E65E18C9394B9C80C42507D7A6A0DBE9A9A54B05A9A96800C34C7AA5297095B69C88901EEFD127F969DCA26A54C0E0B5C5473EBAEB00957D2633ECAE3835775425DE66C0DE6D024DBB17445E06E6B0C78415E589B8814F08531D02FD43778451E7685541079CFFB79EF0D26EFEEBBB69D1E80383" #define DH_G "2" @@ -155,9 +168,8 @@ int CtdlIPCGetConfig(CtdlIPC *ipc, struct usersupp **uret, char *cret); int CtdlIPCSetConfig(CtdlIPC *ipc, struct usersupp *uret, char *cret); int CtdlIPCGotoRoom(CtdlIPC *ipc, const char *room, const char *passwd, struct ctdlipcroom **rret, char *cret); -int CtdlIPCGetMessages(CtdlIPC *ipc, int which, int whicharg, - const char *mtemplate, - long **mret, char *cret); +int CtdlIPCGetMessages(CtdlIPC *ipc, enum MessageList which, int whicharg, + const char *mtemplate, unsigned long **mret, char *cret); int CtdlIPCGetSingleMessage(CtdlIPC *ipc, long msgnum, int headers, int as_mime, struct ctdlipcmessage **mret, char *cret); int CtdlIPCWhoKnowsRoom(CtdlIPC *ipc, char **listing, char *cret); @@ -266,6 +278,7 @@ int CtdlIPCStartEncryption(CtdlIPC *ipc, char *cret); int CtdlIPCDirectoryLookup(CtdlIPC *ipc, const char *address, char *cret); int CtdlIPCSpecifyPreferredFormats(CtdlIPC *ipc, char *cret, char *formats); int CtdlIPCInternalProgram(CtdlIPC *ipc, int secret, char *cret); +int CtdlIPCMessageBaseCheck(CtdlIPC *ipc, char **mret, char *cret); /* ************************************************************************** */ /* Stuff below this line is not for public consumption */ diff --git a/citadel/commands.c b/citadel/commands.c index c6d71a828..e7b307ade 100644 --- a/citadel/commands.c +++ b/citadel/commands.c @@ -1299,33 +1299,12 @@ int fmout( /* Read the entire message body into memory */ if (fpin) { - size_t got = 0; - - fseek(fpin, 0, SEEK_END); - i = ftell(fpin); - rewind(fpin); - buffer = (char *)calloc(1, i + 1); + buffer = load_message_from_file(fpin); if (!buffer) { - err_printf("Can't alloc memory for message: %s!\n", + err_printf("Can't print message: %s!\n", strerror(errno)); logoff(NULL, 3); } - - while (got < i) { - size_t g; - - g = fread(buffer + got, 1, i - got, fpin); - got += g; - if (g < i - got) { - /* Interrupted system call, keep going */ - if (errno == EINTR) - continue; - /* At this point we have either EOF or error */ - i = got; - break; - } - buffer[i] = 0; - } } else { buffer = text; } diff --git a/citadel/messages.c b/citadel/messages.c index b6341e50e..c02ceb4ec 100644 --- a/citadel/messages.c +++ b/citadel/messages.c @@ -913,6 +913,8 @@ MEABT2: unlink(filename); return (2); } + +#if 0 /* * Transmit message text to the server. * @@ -968,6 +970,8 @@ void transmit_message(CtdlIPC *ipc, FILE *fp) scr_printf(" \r"); scr_flush(); } +#endif + /* * Make sure there's room in msg_arr[] for at least one more. @@ -988,16 +992,17 @@ void check_msg_arr_size(void) { */ int entmsg(CtdlIPC *ipc, int is_reply, /* nonzero if this was a eply command */ - int c) /* */ + int c) /* mode */ { - char buf[300]; - char cmd[SIZ]; + char buf[SIZ]; int a, b; int need_recp = 0; int mode; long highmsg = 0L; FILE *fp; char subject[SIZ]; + struct ctdlipcmessage message; + int r; /* IPC response code */ if (c > 0) mode = 1; @@ -1010,12 +1015,16 @@ int entmsg(CtdlIPC *ipc, * First, check to see if we have permission to enter a message in * this room. The server will return an error code if we can't. */ - snprintf(cmd, sizeof cmd, "ENT0 0||0|%d", mode); - CtdlIPC_putline(ipc, cmd); - CtdlIPC_getline(ipc, cmd); - - if ((strncmp(cmd, "570", 3)) && (strncmp(cmd, "200", 3))) { - scr_printf("%s\n", &cmd[4]); + strcpy(message.recipient, ""); + strcpy(message.author, ""); + strcpy(message.subject, ""); + message.text = message.author; /* point to "", changes later */ + message.anonymous = 0; + message.type = mode; + r = CtdlIPCPostMessage(ipc, 0, &message, buf); + + if (r / 100 != 2 && r / 10 != 57) { + scr_printf("%s\n", buf); return (1); } @@ -1023,7 +1032,7 @@ int entmsg(CtdlIPC *ipc, * in this room, but a recipient needs to be specified. */ need_recp = 0; - if (!strncmp(cmd, "570", 3)) + if (r / 10 == 57) need_recp = 1; /* If the user is a dumbass, tell them how to type. */ @@ -1046,36 +1055,34 @@ int entmsg(CtdlIPC *ipc, } else strcpy(buf, "sysop"); } + strcpy(message.recipient, buf); if (is_reply) { if (strlen(reply_subject) > 0) { if (!strncasecmp(reply_subject, "Re: ", 3)) { - strcpy(subject, reply_subject); + strcpy(message.subject, reply_subject); } else { - snprintf(subject, - sizeof subject, + snprintf(message.subject, + sizeof message.subject, "Re: %s", reply_subject); } } } - b = 0; if (room_flags & QR_ANONOPT) { scr_printf("Anonymous (Y/N)? "); if (yesno() == 1) - b = 1; + message.anonymous = 1; } /* If it's mail, we've got to check the validity of the recipient... */ - if (strlen(buf) > 0) { - snprintf(cmd, sizeof cmd, "ENT0 0|%s|%d|%d|%s", buf, b, mode, subject); - CtdlIPC_putline(ipc, cmd); - CtdlIPC_getline(ipc, cmd); - if (cmd[0] != '2') { - scr_printf("%s\n", &cmd[4]); + if (strlen(message.recipient) > 0) { + r = CtdlIPCPostMessage(ipc, 0, &message, buf); + if (r / 100 != 2) { + scr_printf("%s\n", buf); return (1); } } @@ -1084,19 +1091,17 @@ int entmsg(CtdlIPC *ipc, * tell upon saving whether someone else has posted too. */ num_msgs = 0; - CtdlIPC_putline(ipc, "MSGS LAST|1"); - CtdlIPC_getline(ipc, cmd); - if (cmd[0] != '1') { - scr_printf("%s\n", &cmd[5]); + free(msg_arr); msg_arr = NULL; + r = CtdlIPCGetMessages(ipc, LastMessages, 1, NULL, &msg_arr, buf); + if (r / 100 != 1) { + scr_printf("%s\n", buf); } else { - while (CtdlIPC_getline(ipc, cmd), strcmp(cmd, "000")) { - check_msg_arr_size(); - msg_arr[num_msgs++] = atol(cmd); - } + for (num_msgs = 0; msg_arr[num_msgs]; num_msgs++) + ; } /* Now compose the message... */ - if (client_make_message(ipc, temp, buf, b, 0, c, subject) != 0) { + if (client_make_message(ipc, temp, message.recipient, message.anonymous, 0, c, message.subject) != 0) { return (2); } @@ -1106,38 +1111,31 @@ int entmsg(CtdlIPC *ipc, /* Yes, unlink it now, so it doesn't stick around if we crash */ unlink(temp); - if (fp == NULL) { + if (!fp || !(message.text = load_message_from_file(fp))) { err_printf("*** Internal error while trying to save message!\n" - " %s: %s\n", + "%s: %s\n", temp, strerror(errno)); return(errno); } + if (fp) fclose(fp); + /* Transmit message to the server */ - snprintf(cmd, sizeof cmd, "ENT0 1|%s|%d|%d|%s|", buf, b, mode, subject); - CtdlIPC_putline(ipc, cmd); - CtdlIPC_getline(ipc, cmd); - if (cmd[0] != '4') { - scr_printf("%s\n", &cmd[4]); + r = CtdlIPCPostMessage(ipc, 1, &message, buf); + if (r / 100 != 4) { + scr_printf("%s\n", buf); return (1); } - transmit_message(ipc, fp); - CtdlIPC_putline(ipc, "000"); - - fclose(fp); - if (num_msgs >= 1) highmsg = msg_arr[num_msgs - 1]; - num_msgs = 0; - CtdlIPC_putline(ipc, "MSGS NEW"); - CtdlIPC_getline(ipc, cmd); - if (cmd[0] != '1') { - scr_printf("%s\n", &cmd[5]); + + free(msg_arr); msg_arr = NULL; + r = CtdlIPCGetMessages(ipc, NewMessages, 0, NULL, &msg_arr, buf); + if (r / 100 != 1) { + scr_printf("%s\n", buf); } else { - while (CtdlIPC_getline(ipc, cmd), strcmp(cmd, "000")) { - check_msg_arr_size(); - msg_arr[num_msgs++] = atol(cmd); - } + for (num_msgs = 0; msg_arr[num_msgs]; num_msgs++) + ; } /* get new highest message number in room to set lrp for goto... */ @@ -1242,8 +1240,8 @@ void list_urls(CtdlIPC *ipc) * Read the messages in the current room */ void readmsgs(CtdlIPC *ipc, - int c, /* 0=Read all 1=Read new 2=Read old 3=Read last q */ - int rdir, /* 1=Forward (-1)=Reverse */ + enum MessageList c, /* see listing in citadel_ipc.h */ + enum MessageDirection rdir, /* 1=Forward (-1)=Reverse */ int q /* Number of msgs to read (if c==3) */ ) { int a, b, e, f, g, start; @@ -1269,31 +1267,16 @@ void readmsgs(CtdlIPC *ipc, strcpy(prtfile, tmpnam(NULL)); - num_msgs = 0; - strcpy(cmd, "MSGS "); - switch (c) { - case 0: - strcat(cmd, "ALL"); - break; - case 1: - strcat(cmd, "NEW"); - break; - case 2: - strcat(cmd, "OLD"); - break; - case 3: - snprintf(&cmd[5], sizeof cmd - 5, "LAST|%d", q); - break; + if (msg_arr) { + free(msg_arr); + msg_arr = NULL; } - CtdlIPC_putline(ipc, cmd); - CtdlIPC_getline(ipc, cmd); - if (cmd[0] != '1') { - scr_printf("%s\n", &cmd[5]); + r = CtdlIPCGetMessages(ipc, c, q, NULL, &msg_arr, cmd); + if (r / 100 != 1) { + scr_printf("%s\n", cmd); } else { - while (CtdlIPC_getline(ipc, cmd), strcmp(cmd, "000")) { - check_msg_arr_size(); - msg_arr[num_msgs++] = atol(cmd); - } + for (num_msgs = 0; msg_arr[num_msgs]; num_msgs++) + ; } if (num_msgs == 0) { @@ -1647,6 +1630,8 @@ void edit_system_message(CtdlIPC *ipc, char *which_message) void check_message_base(CtdlIPC *ipc) { char buf[SIZ]; + char *transcript = NULL; + int r; /* IPC response code */ scr_printf ("Please read the documentation before running this command.\n" @@ -1654,14 +1639,56 @@ void check_message_base(CtdlIPC *ipc) if (yesno() == 0) return; - CtdlIPC_putline(ipc, "FSCK"); - CtdlIPC_getline(ipc, buf); - if (buf[0] != '1') { - scr_printf("%s\n", &buf[4]); + r = CtdlIPCMessageBaseCheck(ipc, &transcript, buf); + if (r / 100 != 1) { + scr_printf("%s\n", buf); return; } - while (CtdlIPC_getline(ipc, buf), strcmp(buf, "000")) { - scr_printf("%s\n", buf); + while (transcript && strlen(transcript)) { + lines_printed = 1; + extract_token(buf, transcript, 0, '\n'); + remove_token(transcript, 0, '\n'); + pprintf("%s\n", buf); } + if (transcript) free(transcript); + return; +} + + +/* + * Loads the contents of a file into memory. Caller must free the allocated + * memory. + */ +char *load_message_from_file(FILE *src) +{ + size_t i; + size_t got = 0; + char *dest = NULL; + + fseek(src, 0, SEEK_END); + i = ftell(src); + rewind(src); + + dest = (char *)calloc(1, i + 1); + if (!dest) + return NULL; + + while (got < i) { + size_t g; + + g = fread(dest + got, 1, i - got, src); + got += g; + if (g < i - got) { + /* Interrupted system call, keep going */ + if (errno == EINTR) + continue; + /* At this point we have either EOF or error */ + i = got; + break; + } + dest[i] = 0; + } + + return dest; } diff --git a/citadel/messages.h b/citadel/messages.h index c328a878b..1ed820e20 100644 --- a/citadel/messages.h +++ b/citadel/messages.h @@ -1,7 +1,7 @@ /* $Id$ */ int ka_system(char *shc); int entmsg(CtdlIPC *ipc, int is_reply, int c); -void readmsgs(CtdlIPC *ipc, int c, int rdir, int q); +void readmsgs(CtdlIPC *ipc, enum MessageList c, enum MessageDirection rdir, int q); void edit_system_message(CtdlIPC *ipc, char *which_message); pid_t ka_wait(int *kstatus); void list_urls(CtdlIPC *ipc); @@ -14,4 +14,5 @@ int client_make_message(CtdlIPC *ipc, int mode, char *subject); void citedit(CtdlIPC *ipc, FILE *); +char *load_message_from_file(FILE *src); int file_checksum(char *filename); diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 622f1f1a2..aaf901b3c 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -2588,7 +2588,7 @@ void cmd_ent0(char *entargs) ERROR + HIGHER_ACCESS_REQUIRED); return; } - extract(newusername, entargs, 4); + extract(newusername, entargs, 5); memset(CC->fake_postname, 0, sizeof(CC->fake_postname) ); safestrncpy(CC->fake_postname, newusername, sizeof(CC->fake_postname) ); diff --git a/citadel/techdoc/session.txt b/citadel/techdoc/session.txt index a9d5710f8..c10c9abfd 100644 --- a/citadel/techdoc/session.txt +++ b/citadel/techdoc/session.txt @@ -751,7 +751,7 @@ perform this operation at the beginning of an "enter message" command *before* starting up its editor, so the user does not end up typing a message in vain that will not be permitted to be saved. If it is set to 2, the server will accept an "apparent" post name if the user is privileged enough. -This post name is arg 4. +This post name is arg 5. 1 - Recipient. This argument is utilized only for private mail messages. It is ignored for public messages. It contains, of course, the name of the recipient of the message. @@ -760,7 +760,9 @@ anonymous messages. In such rooms, this flag may be set to 1 to flag a message as anonymous, otherwise 0 for a normal message. 3 - Format type. Any valid Citadel/UX format type may be used (this will typically be 0; see the MSG0 command above). - 4 - Post name. When postflag is 2, this is the name you are posting as. + 4 - Subject. If present, this argument will be used as the subject of +the message. + 5 - Post name. When postflag is 2, this is the name you are posting as. This is an Aide only command. Possible result codes: -- 2.39.2