$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.
Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
* Initial CVS import
+
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 {
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);
/* 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;
(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;
}
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);
}
+/* 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:
*
{
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;
}
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"
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);
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 */
/* 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;
}
return (2);
}
+
+#if 0
/*
* Transmit message text to the server.
*
scr_printf(" \r");
scr_flush();
}
+#endif
+
/*
* Make sure there's room in msg_arr[] for at least one more.
*/
int entmsg(CtdlIPC *ipc,
int is_reply, /* nonzero if this was a <R>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;
* 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);
}
* 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. */
} 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);
}
}
* 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);
}
/* 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... */
* 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;
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) {
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"
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;
}
/* $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);
int mode,
char *subject);
void citedit(CtdlIPC *ipc, FILE *);
+char *load_message_from_file(FILE *src);
int file_checksum(char *filename);
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) );
*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.
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: