From ba269a98296772d79eb59db2cd762d98022a3ef0 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Sun, 10 Jan 1999 01:38:40 +0000 Subject: [PATCH] Lotsa stuff. See the changeLog for more details. --- citadel/ChangeLog | 8 + citadel/citadel.c | 35 +-- citadel/citadel.h | 1 + citadel/citserver.c | 1 + citadel/client_chat.c | 64 ++++ citadel/client_chat.h | 1 + citadel/control.c | 9 + citadel/file_ops.c | 2 +- citadel/ipcdef.h | 1 + citadel/msgbase.c | 23 +- citadel/msgbase.h | 3 +- citadel/routines.c | 2 + citadel/routines2.c | 7 +- citadel/serv_chat.c | 586 +++++++++++++++++++----------------- citadel/serv_expire.c | 4 +- citadel/serv_info.c | 2 + citadel/serv_upgrade.c | 4 +- citadel/techdoc/session.txt | 17 +- 18 files changed, 447 insertions(+), 323 deletions(-) diff --git a/citadel/ChangeLog b/citadel/ChangeLog index 1c018fab2..a4e4cf7be 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,3 +1,11 @@ +Fri Jan 8 12:35:09 EST 1999 Art Cancro + * control.c: include to fix PATH_MAX undefined + * serv_chat.c: made the following changes to cmd_sexp() -- + * Send zero-length message to check only, don't send + * Send "-" message on the command line to invoke + the SEND_LISTING transfer mode for a multi-line message + * Added facilities to log all pages to a room (site configurable) + Tue Jan 5 23:24:52 EST 1999 Art Cancro * Replaced all occurances of malloc(), realloc(), and free() in the server and server-modules with mallok(), reallok(), and phree(). diff --git a/citadel/citadel.c b/citadel/citadel.c index 8a0874e7c..3ff466ac5 100644 --- a/citadel/citadel.c +++ b/citadel/citadel.c @@ -82,14 +82,12 @@ char floor_mode; char curr_floor = 0; /* number of current floor */ char floorlist[128][256]; /* names of floors */ char express_msgs = 0; /* express messages waiting! */ -char last_paged[32]=""; jmp_buf jmp_reconnect; /* for server reconnects */ char re_username[32]; char re_password[32]; void sigpipehandler(int nothing) { - printf("Longjumpfing with %d\n", nothing); longjmp(jmp_reconnect, nothing); } @@ -746,6 +744,7 @@ void who_is_online(int longlist) char tbuf[128], clientsoft[128]; time_t timenow=0; time_t idletime, idlehours, idlemins, idlesecs; + int last_session = (-1); if (longlist) { @@ -789,8 +788,14 @@ void who_is_online(int longlist) } else { - color(1); printf("%-3s ", flags); - color(2); printf("%-3d ", extract_int(buf,0)); + if (extract_int(buf,0)==last_session) { + printf(" "); + } + else { + color(1); printf("%-3s ", flags); + color(2); printf("%-3d ", extract_int(buf,0)); + } + last_session=extract_int(buf,0); color(3); printf("%-25s ", username); color(4); printf("%-20s ", roomname); color(5); printf("%-24s\n", fromhost); @@ -813,7 +818,7 @@ void enternew(char *desc, char *buf, int maxlen) int main(int argc, char **argv) { int a,b,mcmd; -char aaa[100],bbb[100],ccc[100],eee[100]; /* general purpose variables */ +char aaa[100],bbb[100],eee[100]; /* general purpose variables */ char argbuf[32]; /* command line buf */ int termn8 = 0; @@ -992,7 +997,11 @@ do { /* MAIN LOOP OF PROGRAM */ /* Reconnect to the server if the connection was broken */ if (setjmp(jmp_reconnect)) { + printf("\rServer connection broken; reconnecting...\r"); + fflush(stdout); attach_to_server(argc,argv); + printf(" \r"); + fflush(stdout); serv_gets(aaa); if (aaa[0]!='2') { printf("%s\n", &aaa[4]); exit(0); } sprintf(aaa, "USER %s", re_username); @@ -1267,21 +1276,7 @@ case 54: break; case 56: - if (last_paged[0]) - snprintf(bbb, sizeof bbb, "Page who [%s]? ", last_paged); - else - snprintf(bbb, sizeof bbb, "Page who? "); - newprompt(bbb,aaa,30); - if (!aaa[0]) - strcpy(aaa, last_paged); - strproc(aaa); - newprompt("Message: ",bbb,69); - snprintf(ccc,sizeof ccc,"SEXP %s|%s",aaa,bbb); - serv_puts(ccc); - serv_gets(ccc); - if (!strncmp("200", ccc, 3)) - strcpy(last_paged, aaa); - printf("%s\n",&ccc[4]); + page_user(); break; } /* end switch */ diff --git a/citadel/citadel.h b/citadel/citadel.h index eb8468677..574dd7975 100644 --- a/citadel/citadel.h +++ b/citadel/citadel.h @@ -73,6 +73,7 @@ struct config { struct ExpirePolicy c_ep; /* System default msg expire policy */ int c_userpurge; /* System default user purge (days) */ int c_roompurge; /* System default room purge (days) */ + char c_logpages[ROOMNAMELEN]; /* Room to log pages to (or not) */ }; #define NODENAME config.c_nodename diff --git a/citadel/citserver.c b/citadel/citserver.c index 1ab8a0f58..07b23e840 100644 --- a/citadel/citserver.c +++ b/citadel/citserver.c @@ -176,6 +176,7 @@ void cmd_info(void) { cprintf("%d\n",SERVER_TYPE); cprintf("%s\n",config.c_moreprompt); cprintf("1\n"); /* 1 = yes, this system supports floors */ + cprintf("1\n"); /* 1 = we support the extended paging options */ cprintf("000\n"); } diff --git a/citadel/client_chat.c b/citadel/client_chat.c index f54b11f3c..79f72622b 100644 --- a/citadel/client_chat.c +++ b/citadel/client_chat.c @@ -32,6 +32,10 @@ #define MIN(a, b) ((a) < (b) ? (a) : (b)) +extern struct CtdlServInfo serv_info; +extern char temp[]; +void citedit(FILE *fp, long int base_pos); + void chatmode(void) { char wbuf[256]; char buf[256]; @@ -188,4 +192,64 @@ RCL: if (send_complete_line) { } } +/* + * send an express message + */ +void page_user() { + static char last_paged[32] = ""; + char buf[256], touser[256], msg[256]; + FILE *fp; + + strcpy(touser, last_paged); + strprompt("Page who", touser, 30); + + /* old server -- use inline paging */ + if (serv_info.serv_paging_level == 0) { + newprompt("Message: ",msg,69); + snprintf(buf,sizeof buf,"SEXP %s|%s",touser,msg); + serv_puts(buf); + serv_gets(buf); + if (!strncmp(buf, "200", 3)) { + strcpy(last_paged, touser); + } + printf("%s\n", &buf[4]); + return; + } + + /* new server -- use extended paging */ + else if (serv_info.serv_paging_level >= 1) { + snprintf(buf, sizeof buf, "SEXP %s||", touser); + serv_puts(buf); + serv_gets(buf); + if (buf[0] != '2') { + printf("%s\n", &buf[4]); + return; + } + fp = fopen(temp, "w"); + if (fp==NULL) printf("Error: %s\n", strerror(errno)); + printf("Type message to send. Enter a blank line when finished.\n"); + citedit(fp, 0); + fclose(fp); + snprintf(buf, sizeof buf, "SEXP %s|-", touser); + serv_puts(buf); + serv_gets(buf); + if (buf[0]=='4') { + strcpy(last_paged, touser); + fp = fopen(temp, "r"); + while (fgets(buf, sizeof buf, fp) != NULL) { + buf[strlen(buf)-1] = 0; + if (strcmp(buf, "000")) serv_puts(buf); + fclose(fp); + unlink(temp); + } + serv_puts("000"); + printf("Message sent.\n"); + } + else { + printf("%s\n", &buf[4]); + } + } +} + + diff --git a/citadel/client_chat.h b/citadel/client_chat.h index a1866596d..5add246ff 100644 --- a/citadel/client_chat.h +++ b/citadel/client_chat.h @@ -1,2 +1,3 @@ /* $Id$ */ void chatmode(void); +void page_user(void); diff --git a/citadel/control.c b/citadel/control.c index a4069b112..e69b42a41 100644 --- a/citadel/control.c +++ b/citadel/control.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include "citadel.h" @@ -26,6 +27,7 @@ #include "config.h" #include "msgbase.h" #include "tools.h" +#include "room_ops.h" struct CitControl CitControl; struct config config; @@ -143,6 +145,7 @@ void cmd_conf(char *argbuf) { cprintf("%s\n", config.c_net_password); cprintf("%d\n", config.c_userpurge); cprintf("%d\n", config.c_roompurge); + cprintf("%s\n", config.c_logpages); cprintf("000\n"); } @@ -198,6 +201,9 @@ void cmd_conf(char *argbuf) { break; case 17: config.c_roompurge = atoi(buf); break; + case 18: strncpy(config.c_logpages, + buf, ROOMNAMELEN); + break; } ++a; } @@ -206,6 +212,9 @@ void cmd_conf(char *argbuf) { "Global system configuration edited by %s", CC->curr_user); aide_message(buf); + + if (strlen(config.c_logpages) > 0) + create_room(config.c_logpages, 4, "", 0); } else { diff --git a/citadel/file_ops.c b/citadel/file_ops.c index e83ba34a9..40d8289e3 100644 --- a/citadel/file_ops.c +++ b/citadel/file_ops.c @@ -558,7 +558,7 @@ void cmd_ucls(char *cmd) fprintf(fp,"NEW UPLOAD: '%s'\n %s\n",CC->upl_file,CC->upl_comment); putc(0,fp); fclose(fp); - save_message(CC->temp, "", 0, M_LOCAL, 1); + save_message(CC->temp, "", "", M_LOCAL, 1); } else { diff --git a/citadel/ipcdef.h b/citadel/ipcdef.h index 406275c1b..48d418d02 100644 --- a/citadel/ipcdef.h +++ b/citadel/ipcdef.h @@ -39,6 +39,7 @@ struct CtdlServInfo { char serv_sysadm[64]; char serv_moreprompt[256]; int serv_ok_floors; + int serv_paging_level; }; #define QR_PERMANENT 1 /* Room does not purge */ diff --git a/citadel/msgbase.c b/citadel/msgbase.c index e76c6d3d9..fc594505e 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -727,7 +727,7 @@ void copy_file(char *from, char *to) */ void save_message(char *mtmp, /* file containing proper message */ char *rec, /* Recipient (if mail) */ - char mtsflag, /* 0 for normal, 1 to force Aide> room */ + char *force_room, /* if non-zero length, force a room */ int mailtype, /* local or remote type, see citadel.h */ int generate_id) /* set to 1 to generate an 'I' field */ { @@ -744,8 +744,8 @@ void save_message(char *mtmp, /* file containing proper message */ int a; static int seqnum = 0; - lprintf(9, "save_message(%s,%s,%d,%d,%d)\n", - mtmp, rec, mtsflag, mailtype, generate_id); + lprintf(9, "save_message(%s,%s,%s,%d,%d)\n", + mtmp, rec, force_room, mailtype, generate_id); /* Strip non-printable characters out of the recipient name */ strcpy(recipient, rec); @@ -786,7 +786,8 @@ void save_message(char *mtmp, /* file containing proper message */ /* mailtype = alias(recipient); */ if (mailtype == M_LOCAL) { if (getuser(&userbuf, recipient)!=0) { - mtsflag = 1; /* User not found, goto Aide */ + /* User not found, goto Aide */ + strcpy(force_room, AIDEROOM); } else { strcpy(hold_rm, actual_rm); @@ -796,9 +797,9 @@ void save_message(char *mtmp, /* file containing proper message */ } /* ...or if this message is destined for Aide> then go there. */ - if (mtsflag) { + if (strlen(force_room) > 0) { strcpy(hold_rm, actual_rm); - strcpy(actual_rm, AIDEROOM); + strcpy(actual_rm, force_room); } /* This call to usergoto() changes rooms if necessary. It also @@ -848,20 +849,18 @@ void save_message(char *mtmp, /* file containing proper message */ */ void aide_message(char *text) { - time_t now; FILE *fp; - time(&now); fp=fopen(CC->temp,"wb"); fprintf(fp,"%c%c%c",255,MES_NORMAL,0); fprintf(fp,"Psysop%c",0); - fprintf(fp,"T%ld%c",now,0); + fprintf(fp,"T%ld%c", time(NULL), 0); fprintf(fp,"ACitadel%c",0); fprintf(fp,"OAide%c",0); fprintf(fp,"N%s%c",NODENAME,0); fprintf(fp,"M%s\n%c",text,0); fclose(fp); - save_message(CC->temp,"",1,M_LOCAL,1); + save_message(CC->temp,"",AIDEROOM,M_LOCAL,1); syslog(LOG_NOTICE,text); } @@ -1082,7 +1081,7 @@ SKFALL: b=MES_NORMAL; make_message(CC->temp,&CC->usersupp,buf,CC->quickroom.QRname,b,e,format_type, CC->fake_username); else make_message(CC->temp,&CC->usersupp,buf,CC->quickroom.QRname,b,e,format_type, ""); - save_message(CC->temp,buf,mtsflag,e,1); + save_message(CC->temp,buf, (mtsflag ? AIDEROOM : ""), e,1); CC->fake_postname[0]='\0'; return; } @@ -1160,7 +1159,7 @@ void cmd_ent3(char *entargs) } fclose(fp); - save_message(CC->temp, recp, 0, e, 0); + save_message(CC->temp, recp, "", e, 0); } diff --git a/citadel/msgbase.h b/citadel/msgbase.h index 550d27f24..0907e865f 100644 --- a/citadel/msgbase.h +++ b/citadel/msgbase.h @@ -14,8 +14,7 @@ long int send_message (char *message_in_memory, size_t message_length, int generate_id); void loadtroom (void); void copy_file (char *from, char *to); -void save_message (char *mtmp, char *rec, char mtsflag, int mailtype, - int generate_id); +void save_message (char *, char *, char *, int, int); void aide_message (char *text); void make_message (char *filename, struct usersupp *author, char *recipient, char *room, int type, int net_type, int format_type, diff --git a/citadel/routines.c b/citadel/routines.c index c74732a91..ce3a16a38 100644 --- a/citadel/routines.c +++ b/citadel/routines.c @@ -436,9 +436,11 @@ void misc_server_cmd(char *cmd) { serv_gets(buf); printf("%s\n",buf); if (buf[0]=='1') { + set_keepalives(KA_NO); while (serv_gets(buf), strcmp(buf,"000")) { printf("%s\n",buf); } + set_keepalives(KA_YES); return; } if (buf[0]=='4') { diff --git a/citadel/routines2.c b/citadel/routines2.c index 22476816a..01364065c 100644 --- a/citadel/routines2.c +++ b/citadel/routines2.c @@ -576,7 +576,7 @@ void read_bio(void) { */ void do_system_configuration(void) { char buf[256]; - char sc[18][256]; + char sc[19][256]; int expire_mode = 0; int expire_value = 0; int a; @@ -590,7 +590,7 @@ void do_system_configuration(void) { if (buf[0] == '1') { a = 0; while (serv_gets(buf), strcmp(buf, "000")) { - if (a<18) strcpy(&sc[a][0], buf); + if (a<19) strcpy(&sc[a][0], buf); ++a; } } @@ -638,6 +638,7 @@ void do_system_configuration(void) { strprompt("Server-to-server networking password", &sc[15][0], 19); strprompt("Default user purge time (days)", &sc[16][0], 5); strprompt("Default room purge time (days)", &sc[17][0], 5); + strprompt("Name of room to log pages", &sc[18][0], ROOMNAMELEN); /* Angels and demons dancing in my head... */ do { @@ -672,7 +673,7 @@ void do_system_configuration(void) { serv_puts("CONF set"); serv_gets(buf); if (buf[0] == '4') { - for (a=0; a<18; ++a) serv_puts(&sc[a][0]); + for (a=0; a<19; ++a) serv_puts(&sc[a][0]); serv_puts("000"); } diff --git a/citadel/serv_chat.c b/citadel/serv_chat.c index fcacf1fd5..73cc4fa53 100644 --- a/citadel/serv_chat.c +++ b/citadel/serv_chat.c @@ -1,4 +1,11 @@ -/* $Id$ */ +/* + * serv_chat.c + * + * This module handles all "real time" communication between users. The + * modes of communication currently supported are Chat and Paging. + * + * $Id$ + */ #include #include #include @@ -25,6 +32,7 @@ #include "config.h" #include "dynloader.h" #include "tools.h" +#include "msgbase.h" struct ChatLine *ChatQueue = NULL; int ChatLastMsg = 0; @@ -34,29 +42,28 @@ extern struct CitContext *ContextList; #define MODULE_NAME "Chat module" #define MODULE_AUTHOR "Art Cancro" #define MODULE_EMAIL "ajc@uncnsrd.mt-kisco.ny.us" -#define MAJOR_VERSION 0 -#define MINOR_VERSION 2 +#define MAJOR_VERSION 1 +#define MINOR_VERSION 0 static struct DLModule_Info info = { - MODULE_NAME, - MODULE_AUTHOR, - MODULE_EMAIL, - MAJOR_VERSION, - MINOR_VERSION + MODULE_NAME, + MODULE_AUTHOR, + MODULE_EMAIL, + MAJOR_VERSION, + MINOR_VERSION }; struct DLModule_Info *Dynamic_Module_Init(void) { - CtdlRegisterProtoHook(cmd_chat, "CHAT", - "Initiates a real-time chat session"); - CtdlRegisterProtoHook(cmd_pexp, "PEXP", "Poll for express messages"); - CtdlRegisterProtoHook(cmd_sexp, "SEXP", "Send an express message"); - return &info; + CtdlRegisterProtoHook(cmd_chat, "CHAT", "Begin real-time chat"); + CtdlRegisterProtoHook(cmd_pexp, "PEXP", "Poll for express messages"); + CtdlRegisterProtoHook(cmd_sexp, "SEXP", "Send an express message"); + return &info; } void allwrite(char *cmdbuf, int flag, char *roomname, char *username) -{ +{ FILE *fp; char bcast[256]; char *un; @@ -64,50 +71,39 @@ void allwrite(char *cmdbuf, int flag, char *roomname, char *username) time_t now; if (CC->fake_username[0]) - un = CC->fake_username; - else - un = CC->usersupp.fullname; - if (flag == 1) - { - sprintf(bcast,":|<%s %s>",un,cmdbuf); - } - else - if (flag == 0) - { - sprintf(bcast,"%s|%s",un,cmdbuf); - } + un = CC->fake_username; else - if (flag == 2) - { - sprintf(bcast,":|<%s whispers %s>", un, cmdbuf); + un = CC->usersupp.fullname; + if (flag == 1) { + sprintf(bcast, ":|<%s %s>", un, cmdbuf); + } else if (flag == 0) { + sprintf(bcast, "%s|%s", un, cmdbuf); + } else if (flag == 2) { + sprintf(bcast, ":|<%s whispers %s>", un, cmdbuf); } - if ((strcasecmp(cmdbuf,"NOOP")) && (flag !=2)) { - fp = fopen(CHATLOG,"a"); - fprintf(fp,"%s\n",bcast); + if ((strcasecmp(cmdbuf, "NOOP")) && (flag != 2)) { + fp = fopen(CHATLOG, "a"); + fprintf(fp, "%s\n", bcast); fclose(fp); - } - + } clnew = (struct ChatLine *) mallok(sizeof(struct ChatLine)); memset(clnew, 0, sizeof(struct ChatLine)); if (clnew == NULL) { fprintf(stderr, "citserver: cannot alloc chat line: %s\n", strerror(errno)); return; - } - + } time(&now); clnew->next = NULL; clnew->chat_time = now; strncpy(clnew->chat_room, roomname, sizeof clnew->chat_room); clnew->chat_room[sizeof clnew->chat_room - 1] = 0; - if (username) - { - strncpy(clnew->chat_username, username, - sizeof clnew->chat_username); - clnew->chat_username[sizeof clnew->chat_username - 1] = 0; - } - else - clnew->chat_username[0] = '\0'; + if (username) { + strncpy(clnew->chat_username, username, + sizeof clnew->chat_username); + clnew->chat_username[sizeof clnew->chat_username - 1] = 0; + } else + clnew->chat_username[0] = '\0'; strcpy(clnew->chat_text, bcast); /* Here's the critical section. @@ -118,49 +114,48 @@ void allwrite(char *cmdbuf, int flag, char *roomname, char *username) clnew->chat_seq = ChatLastMsg; if (ChatQueue == NULL) { ChatQueue = clnew; - } - else { - for (clptr=ChatQueue; clptr->next != NULL; clptr=clptr->next) ;; + } else { + for (clptr = ChatQueue; clptr->next != NULL; clptr = clptr->next);; clptr->next = clnew; - } + } /* Then, before releasing the lock, free the expired messages */ - while(1) { - if (ChatQueue == NULL) goto DONE_FREEING; - if ( (now - ChatQueue->chat_time) < 120L ) goto DONE_FREEING; + while (1) { + if (ChatQueue == NULL) + goto DONE_FREEING; + if ((now - ChatQueue->chat_time) < 120L) + goto DONE_FREEING; clptr = ChatQueue; ChatQueue = ChatQueue->next; phree(clptr); - } -DONE_FREEING: end_critical_section(S_CHATQUEUE); } + DONE_FREEING:end_critical_section(S_CHATQUEUE); +} t_context *find_context(char **unstr) { - t_context *t_cc, *found_cc = NULL; - char *name, *tptr; - - if ((!*unstr) || (!unstr)) - return(NULL); - - begin_critical_section(S_SESSION_TABLE); - for (t_cc = ContextList; ((t_cc) && (!found_cc)); t_cc = t_cc->next) - { - if (t_cc->fake_username[0]) - name = t_cc->fake_username; - else - name = t_cc->curr_user; - tptr = *unstr; - if ((!strncasecmp(name, tptr, strlen(name))) && (tptr[strlen(name)] == ' ')) - { - found_cc = t_cc; - *unstr = &(tptr[strlen(name)+1]); - } - } - end_critical_section(S_SESSION_TABLE); - - return(found_cc); + t_context *t_cc, *found_cc = NULL; + char *name, *tptr; + + if ((!*unstr) || (!unstr)) + return (NULL); + + begin_critical_section(S_SESSION_TABLE); + for (t_cc = ContextList; ((t_cc) && (!found_cc)); t_cc = t_cc->next) { + if (t_cc->fake_username[0]) + name = t_cc->fake_username; + else + name = t_cc->curr_user; + tptr = *unstr; + if ((!strncasecmp(name, tptr, strlen(name))) && (tptr[strlen(name)] == ' ')) { + found_cc = t_cc; + *unstr = &(tptr[strlen(name) + 1]); + } + } + end_critical_section(S_SESSION_TABLE); + + return (found_cc); } /* @@ -174,28 +169,24 @@ void do_chat_listing(int allflag) cprintf(":|\n:| Users currently in chat:\n"); begin_critical_section(S_SESSION_TABLE); for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) { - if ( (!strcasecmp(ccptr->cs_room, "")) - && ((ccptr->cs_flags & CS_STEALTH) == 0)) { + if ((!strcasecmp(ccptr->cs_room, "")) + && ((ccptr->cs_flags & CS_STEALTH) == 0)) { cprintf(":| %-25s <%s>\n", (ccptr->fake_username[0]) ? ccptr->fake_username : ccptr->curr_user, ccptr->chat_room); - } } + } - if (allflag == 1) - { + if (allflag == 1) { cprintf(":|\n:| Users not in chat:\n"); - for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) - { - if ( (strcasecmp(ccptr->cs_room, "")) - && ((ccptr->cs_flags & CS_STEALTH) == 0)) - { + for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) { + if ((strcasecmp(ccptr->cs_room, "")) + && ((ccptr->cs_flags & CS_STEALTH) == 0)) { cprintf(":| %-25s <%s>:\n", (ccptr->fake_username[0]) ? ccptr->fake_username : ccptr->curr_user, (ccptr->fake_roomname[0]) ? ccptr->fake_roomname : ccptr->cs_room); } } } - end_critical_section(S_SESSION_TABLE); cprintf(":|\n"); - } +} void cmd_chat(char *argbuf) @@ -210,13 +201,12 @@ void cmd_chat(char *argbuf) int retval; if (!(CC->logged_in)) { - cprintf("%d Not logged in.\n",ERROR+NOT_LOGGED_IN); + cprintf("%d Not logged in.\n", ERROR + NOT_LOGGED_IN); return; - } - + } strcpy(CC->chat_room, "Main room"); - strcpy(hold_cs_room,CC->cs_room); + strcpy(hold_cs_room, CC->cs_room); CC->cs_flags = CC->cs_flags | CS_CHAT; set_wtmpsupp(""); cprintf("%d Entering chat mode (type '/help' for available commands)\n", @@ -225,153 +215,140 @@ void cmd_chat(char *argbuf) MyLastMsg = ChatLastMsg; if ((CC->cs_flags & CS_STEALTH) == 0) { - allwrite("",0, CC->chat_room, NULL); - } - + allwrite("", 0, CC->chat_room, NULL); + } strcpy(cmdbuf, ""); - while(1) { - int ok_cmd; - - ok_cmd = 0; + while (1) { + int ok_cmd; + + ok_cmd = 0; cmdbuf[strlen(cmdbuf) + 1] = 0; retval = client_read_to(&cmdbuf[strlen(cmdbuf)], 1, 2); /* if we have a complete line, do send processing */ - if (strlen(cmdbuf) > 0) if (cmdbuf[strlen(cmdbuf)-1] == 10) { - cmdbuf[strlen(cmdbuf) - 1] = 0; - time(&CC->lastcmd); - time(&CC->lastidle); - - if ( (!strcasecmp(cmdbuf,"exit")) - ||(!strcasecmp(cmdbuf,"/exit")) - ||(!strcasecmp(cmdbuf,"quit")) - ||(!strcasecmp(cmdbuf,"logout")) - ||(!strcasecmp(cmdbuf,"logoff")) - ||(!strcasecmp(cmdbuf,"/q")) - ||(!strcasecmp(cmdbuf,".q")) - ||(!strcasecmp(cmdbuf,"/quit")) - ) strcpy(cmdbuf,"000"); - - if (!strcmp(cmdbuf,"000")) { - if ((CC->cs_flags & CS_STEALTH) == 0) { - allwrite("",0, CC->chat_room, NULL); + if (strlen(cmdbuf) > 0) + if (cmdbuf[strlen(cmdbuf) - 1] == 10) { + cmdbuf[strlen(cmdbuf) - 1] = 0; + time(&CC->lastcmd); + time(&CC->lastidle); + + if ((!strcasecmp(cmdbuf, "exit")) + || (!strcasecmp(cmdbuf, "/exit")) + || (!strcasecmp(cmdbuf, "quit")) + || (!strcasecmp(cmdbuf, "logout")) + || (!strcasecmp(cmdbuf, "logoff")) + || (!strcasecmp(cmdbuf, "/q")) + || (!strcasecmp(cmdbuf, ".q")) + || (!strcasecmp(cmdbuf, "/quit")) + ) + strcpy(cmdbuf, "000"); + + if (!strcmp(cmdbuf, "000")) { + if ((CC->cs_flags & CS_STEALTH) == 0) { + allwrite("", 0, CC->chat_room, NULL); } - sleep(1); - cprintf("000\n"); - CC->cs_flags = CC->cs_flags - CS_CHAT; - set_wtmpsupp(hold_cs_room); - return; + sleep(1); + cprintf("000\n"); + CC->cs_flags = CC->cs_flags - CS_CHAT; + set_wtmpsupp(hold_cs_room); + return; } - - if ((!strcasecmp(cmdbuf,"/help")) - ||(!strcasecmp(cmdbuf,"help")) - ||(!strcasecmp(cmdbuf,"/?")) - ||(!strcasecmp(cmdbuf,"?"))) { - cprintf(":|\n"); - cprintf(":|Available commands: \n"); - cprintf(":|/help (prints this message) \n"); - cprintf(":|/who (list users currently in chat) \n"); - cprintf(":|/whobbs (list users in chat -and- elsewhere) \n"); - cprintf(":|/me ('action' line, ala irc) \n"); - cprintf(":|/msg (send private message, ala irc) \n"); - cprintf(":|/join (join new room) \n"); - cprintf(":|/quit (return to the BBS) \n"); - cprintf(":|\n"); - ok_cmd = 1; + if ((!strcasecmp(cmdbuf, "/help")) + || (!strcasecmp(cmdbuf, "help")) + || (!strcasecmp(cmdbuf, "/?")) + || (!strcasecmp(cmdbuf, "?"))) { + cprintf(":|\n"); + cprintf(":|Available commands: \n"); + cprintf(":|/help (prints this message) \n"); + cprintf(":|/who (list users currently in chat) \n"); + cprintf(":|/whobbs (list users in chat -and- elsewhere) \n"); + cprintf(":|/me ('action' line, ala irc) \n"); + cprintf(":|/msg (send private message, ala irc) \n"); + cprintf(":|/join (join new room) \n"); + cprintf(":|/quit (return to the BBS) \n"); + cprintf(":|\n"); + ok_cmd = 1; } - if (!strcasecmp(cmdbuf,"/who")) { - do_chat_listing(0); - ok_cmd = 1; + if (!strcasecmp(cmdbuf, "/who")) { + do_chat_listing(0); + ok_cmd = 1; } - if (!strcasecmp(cmdbuf,"/whobbs")) { - do_chat_listing(1); - ok_cmd = 1; + if (!strcasecmp(cmdbuf, "/whobbs")) { + do_chat_listing(1); + ok_cmd = 1; } - if (!strncasecmp(cmdbuf,"/me ",4)) { - allwrite(&cmdbuf[4],1, CC->chat_room, NULL); - ok_cmd = 1; + if (!strncasecmp(cmdbuf, "/me ", 4)) { + allwrite(&cmdbuf[4], 1, CC->chat_room, NULL); + ok_cmd = 1; } - - if (!strncasecmp(cmdbuf,"/msg ", 5)) - { - ok_cmd =1; - strptr1 = &cmdbuf[5]; - if ((t_context = find_context(&strptr1))) - { - allwrite(strptr1, 2, "", CC->curr_user); - if (strcasecmp(CC->curr_user, t_context->curr_user)) - allwrite(strptr1, 2, "", t_context->curr_user); - } - else - cprintf(":|User not found.\n", cmdbuf); - cprintf("\n"); - } - - if (!strncasecmp(cmdbuf,"/join ", 6)) - { - ok_cmd = 1; - allwrite("",0, CC->chat_room, NULL); - if (!cmdbuf[6]) - strcpy(CC->chat_room, "Main room"); - else - { - strncpy(CC->chat_room, &cmdbuf[6], - sizeof CC->chat_room); - CC->chat_room[sizeof CC->chat_room - 1] = 0; - } - allwrite("",0, CC->chat_room, NULL); - cprintf("\n"); - } - if ((cmdbuf[0]!='/')&&(strlen(cmdbuf)>0)) { - ok_cmd = 1; - allwrite(cmdbuf,0, CC->chat_room, NULL); + if (!strncasecmp(cmdbuf, "/msg ", 5)) { + ok_cmd = 1; + strptr1 = &cmdbuf[5]; + if ((t_context = find_context(&strptr1))) { + allwrite(strptr1, 2, "", CC->curr_user); + if (strcasecmp(CC->curr_user, t_context->curr_user)) + allwrite(strptr1, 2, "", t_context->curr_user); + } else + cprintf(":|User not found.\n", cmdbuf); + cprintf("\n"); + } + if (!strncasecmp(cmdbuf, "/join ", 6)) { + ok_cmd = 1; + allwrite("", 0, CC->chat_room, NULL); + if (!cmdbuf[6]) + strcpy(CC->chat_room, "Main room"); + else { + strncpy(CC->chat_room, &cmdbuf[6], + sizeof CC->chat_room); + CC->chat_room[sizeof CC->chat_room - 1] = 0; + } + allwrite("", 0, CC->chat_room, NULL); + cprintf("\n"); + } + if ((cmdbuf[0] != '/') && (strlen(cmdbuf) > 0)) { + ok_cmd = 1; + allwrite(cmdbuf, 0, CC->chat_room, NULL); } + if ((!ok_cmd) && (cmdbuf[0]) && (cmdbuf[0] != '\n')) + cprintf(":|Command %s is not understood.\n", cmdbuf); - if ((!ok_cmd) && (cmdbuf[0]) && (cmdbuf[0] != '\n')) - cprintf(":|Command %s is not understood.\n", cmdbuf); - - strcpy(cmdbuf, ""); + strcpy(cmdbuf, ""); } - /* now check the queue for new incoming stuff */ - + if (CC->fake_username[0]) - un = CC->fake_username; + un = CC->fake_username; else - un = CC->curr_user; + un = CC->curr_user; if (ChatLastMsg > MyLastMsg) { ThisLastMsg = ChatLastMsg; - for (clptr=ChatQueue; clptr!=NULL; clptr=clptr->next) - { - if ((clptr->chat_seq > MyLastMsg) && ((!clptr->chat_username[0]) || (!strncasecmp(un, clptr->chat_username, 32)))) - { - if ((!clptr->chat_room[0]) || (!strncasecmp(CC->chat_room, clptr->chat_room, ROOMNAMELEN))) - { - cprintf("%s\n", clptr->chat_text); - } - } + for (clptr = ChatQueue; clptr != NULL; clptr = clptr->next) { + if ((clptr->chat_seq > MyLastMsg) && ((!clptr->chat_username[0]) || (!strncasecmp(un, clptr->chat_username, 32)))) { + if ((!clptr->chat_room[0]) || (!strncasecmp(CC->chat_room, clptr->chat_room, ROOMNAMELEN))) { + cprintf("%s\n", clptr->chat_text); + } + } } MyLastMsg = ThisLastMsg; - } - } } +} /* * poll for express messages */ -void cmd_pexp(char *argbuf) /* arg unused */ { +void cmd_pexp(char *argbuf) +{ /* arg unused */ struct ExpressMessage *emptr; if (CC->FirstExpressMessage == NULL) { - cprintf("%d No express messages waiting.\n",ERROR); + cprintf("%d No express messages waiting.\n", ERROR); return; - } - - cprintf("%d Express msgs:\n",LISTING_FOLLOWS); + } + cprintf("%d Express msgs:\n", LISTING_FOLLOWS); while (CC->FirstExpressMessage != NULL) { cprintf("%s", CC->FirstExpressMessage->em_text); @@ -380,98 +357,153 @@ void cmd_pexp(char *argbuf) /* arg unused */ { CC->FirstExpressMessage = CC->FirstExpressMessage->next; phree(emptr); end_critical_section(S_SESSION_TABLE); - } + } cprintf("000\n"); +} + + +/* + * This is the back end to the express message sending function. + * Returns the number of users to which the message was sent. + * Sending a zero-length message tests for recipients without sending messages. + */ +int send_express_message(char *lun, char *x_user, char *x_msg) { + int message_sent = 0; + struct CitContext *ccptr; + struct ExpressMessage *emptr, *emnew; + char *un; + FILE *fp; + + /* find the target user's context and append the message */ + begin_critical_section(S_SESSION_TABLE); + for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) { + + if (ccptr->fake_username[0]) /* */ + un = ccptr->fake_username; + else + un = ccptr->usersupp.fullname; + + if ((!strcasecmp(un, x_user)) + || (!strcasecmp(x_user, "broadcast"))) { + if (strlen(x_msg) > 0) { + strcpy(ccptr->last_pager, CC->curr_user); + emnew = (struct ExpressMessage *) + mallok(sizeof(struct ExpressMessage)); + emnew->next = NULL; + sprintf(emnew->em_text, "%s from %s:\n %s\n", + ((!strcasecmp(x_user, "broadcast")) ? "Broadcast message" : "Message"), + lun, x_msg); + + if (ccptr->FirstExpressMessage == NULL) { + ccptr->FirstExpressMessage = emnew; + } else { + emptr = ccptr->FirstExpressMessage; + while (emptr->next != NULL) { + emptr = emptr->next; + } + emptr->next = emnew; + } + } + ++message_sent; + } } + end_critical_section(S_SESSION_TABLE); + /* Log the page to disk if configured to do so */ + if ( (strlen(config.c_logpages)>0) && (strlen(x_msg)>0) ) { + fp=fopen(CC->temp,"wb"); + fprintf(fp,"%c%c%c", 255, MES_NORMAL, 1); + fprintf(fp,"Psysop%c", 0); + fprintf(fp,"T%ld%c", time(NULL), 0); + fprintf(fp,"A%s%c", lun, 0); + fprintf(fp,"R%s%c", x_user, 0); + fprintf(fp,"O%s%c", config.c_logpages, 0); + fprintf(fp,"N%s%c", NODENAME, 0); + fprintf(fp,"M%s\n%c", x_msg,0); + fclose(fp); + save_message(CC->temp, "", config.c_logpages, M_LOCAL, 1); + unlink(CC->temp); + } + + return(message_sent); + } /* * send express messages */ void cmd_sexp(char *argbuf) { + int message_sent = 0; char x_user[256]; char x_msg[256]; - int message_sent = 0; - struct CitContext *ccptr; - struct ExpressMessage *emptr, *emnew; char *lun; /* */ + char *x_big_msgbuf = NULL; - if ((!(CC->logged_in))&&(!(CC->internal_pgm))) { - cprintf("%d Not logged in.\n",ERROR+NOT_LOGGED_IN); + if ((!(CC->logged_in)) && (!(CC->internal_pgm))) { + cprintf("%d Not logged in.\n", ERROR + NOT_LOGGED_IN); return; - } + } + if (num_parms(argbuf) < 2) { + cprintf("%d usage error\n", ERROR); + return; + } + if (CC->fake_username[0]) + lun = CC->fake_username; + else + lun = CC->usersupp.fullname; - if (num_parms(argbuf)!=2) { - cprintf("%d usage error\n",ERROR); - return; - } + extract(x_user, argbuf, 0); - if (CC->fake_username[0]) - lun = CC->fake_username; - else - lun = CC->usersupp.fullname; - - extract(x_user,argbuf,0); - - if (!strcmp(x_user, ".")) - { - strcpy(x_user, CC->last_pager); - } - extract(x_msg,argbuf,1); - - if (!x_user[0]) - { - cprintf("%d You were not previously paged.\n", ERROR); - return; - } - - if ( (!strcasecmp(x_user, "broadcast")) && (CC->usersupp.axlevel < 6) ) { + if (!strcmp(x_user, ".")) { + strcpy(x_user, CC->last_pager); + } + extract(x_msg, argbuf, 1); + + if (!x_user[0]) { + cprintf("%d You were not previously paged.\n", ERROR); + return; + } + if ((!strcasecmp(x_user, "broadcast")) && (CC->usersupp.axlevel < 6)) { cprintf("%d Higher access required to send a broadcast.\n", - ERROR+HIGHER_ACCESS_REQUIRED); + ERROR + HIGHER_ACCESS_REQUIRED); return; - } - - /* find the target user's context and append the message */ - begin_critical_section(S_SESSION_TABLE); - for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) { - char *un; - - if (ccptr->fake_username[0]) /* */ - un = ccptr->fake_username; - else - un = ccptr->usersupp.fullname; - - if ( (!strcasecmp(un, x_user)) - || (!strcasecmp(x_user, "broadcast")) ) { - strcpy(ccptr->last_pager, CC->curr_user); - emnew = (struct ExpressMessage *) - mallok(sizeof(struct ExpressMessage)); - emnew->next = NULL; - sprintf(emnew->em_text, "%s from %s:\n %s\n", - ( (!strcasecmp(x_user, "broadcast")) ? "Broadcast message" : "Message" ), - lun, x_msg); - - if (ccptr->FirstExpressMessage == NULL) { - ccptr->FirstExpressMessage = emnew; - } - else { - emptr = ccptr->FirstExpressMessage; - while (emptr->next != NULL) { - emptr = emptr->next; - } - emptr->next = emnew; - } + } - ++message_sent; - } + /* This loop handles text-transfer pages */ + if (!strcmp(x_msg, "-")) { + message_sent = send_express_message(lun, x_user, ""); + if (message_sent == 0) { + cprintf("%d No user '%s' logged in.\n", ERROR, x_user); + return; } - end_critical_section(S_SESSION_TABLE); - - if (message_sent > 0) { - cprintf("%d Message sent.\n",OK); + cprintf("%d Transmit message (will deliver to %d users)\n", + SEND_LISTING, message_sent); + x_big_msgbuf = mallok(256); + strcpy(x_big_msgbuf, ""); + while (client_gets(x_msg), strcmp(x_msg, "000")) { + x_big_msgbuf = reallok(x_big_msgbuf, + strlen(x_big_msgbuf) + strlen(x_msg) + 4); + if (strlen(x_big_msgbuf)>0) strcat(x_big_msgbuf, "\n"); + strcat(x_big_msgbuf, x_msg); } - else { - cprintf("%d No user '%s' logged in.\n",ERROR,x_user); + send_express_message(lun, x_user, x_big_msgbuf); + phree(x_big_msgbuf); + + /* This loop handles inline pages */ + } else { + message_sent = send_express_message(lun, x_user, x_msg); + + if (message_sent > 0) { + if (strlen(x_msg)>0) + cprintf("%d Message sent", OK); + else + cprintf("%d Ok to send message", OK); + if (message_sent > 1) cprintf(" to %d users", message_sent); + cprintf(".\n"); + } else { + cprintf("%d No user '%s' logged in.\n", ERROR, x_user); } + + } +} diff --git a/citadel/serv_expire.c b/citadel/serv_expire.c index c2d34b64c..aaa1e146d 100644 --- a/citadel/serv_expire.c +++ b/citadel/serv_expire.c @@ -95,8 +95,8 @@ extern struct CitContext *ContextList; #define MODULE_NAME "Expire old messages, users, rooms" #define MODULE_AUTHOR "Art Cancro" #define MODULE_EMAIL "ajc@uncnsrd.mt-kisco.ny.us" -#define MAJOR_VERSION 0 -#define MINOR_VERSION 1 +#define MAJOR_VERSION 1 +#define MINOR_VERSION 0 static struct DLModule_Info info = { MODULE_NAME, diff --git a/citadel/serv_info.c b/citadel/serv_info.c index 19074bb96..ee2e97022 100644 --- a/citadel/serv_info.c +++ b/citadel/serv_info.c @@ -23,6 +23,7 @@ void CtdlInternalGetServInfo(struct CtdlServInfo *infobuf) { serv_gets(buf); if (buf[0]!='1') return; + bzero(infobuf, sizeof(struct CtdlServInfo)); a = 0; while(serv_gets(buf), strcmp(buf,"000")) { switch(a) { @@ -46,6 +47,7 @@ void CtdlInternalGetServInfo(struct CtdlServInfo *infobuf) { break; case 10: infobuf->serv_ok_floors = atoi(buf); break; + case 11: infobuf->serv_paging_level = atoi(buf); } ++a; } diff --git a/citadel/serv_upgrade.c b/citadel/serv_upgrade.c index 6c49d5bb3..4d5a46b30 100644 --- a/citadel/serv_upgrade.c +++ b/citadel/serv_upgrade.c @@ -40,8 +40,8 @@ FILE *imfp, *exfp; #define MODULE_NAME "Import an unpacked system" #define MODULE_AUTHOR "Art Cancro" #define MODULE_EMAIL "ajc@uncnsrd.mt-kisco.ny.us" -#define MAJOR_VERSION 0 -#define MINOR_VERSION 3 +#define MAJOR_VERSION 1 +#define MINOR_VERSION 0 static struct DLModule_Info info = { MODULE_NAME, diff --git a/citadel/techdoc/session.txt b/citadel/techdoc/session.txt index 7bf1a7861..47b0a4183 100644 --- a/citadel/techdoc/session.txt +++ b/citadel/techdoc/session.txt @@ -456,11 +456,14 @@ parts of the listing: Line 4 - The fully-qualified domain name (FQDN) of the server Line 5 - The name of the server software, i.e. "Citadel/UX 4.00" Line 6 - (The revision level of the server code) * 100 - Line 7 - The geographical location of the BBS (for USA: city and state) + Line 7 - The geographical location of the BBS (city and state if in the US) Line 8 - The name of the system administrator Line 9 - A number identifying the server type (see below) Line 10 - The text of the system's paginator prompt Line 11 - Floor Flag. 1 if the system supports floors, 0 otherwise. + Line 12 - Paging level. 0 if the system only supports inline paging, + 1 if the system supports "extended" paging (check-only and + multiline modes). See the SEXP command for further information. *** NOTE! *** The "server type" code is intended to promote global compatibility in a scenario in which developers have added proprietary @@ -1275,10 +1278,15 @@ displayed the next time the target user executes a PEXP command. message to, and the text of the message. If the message is successfully transmitted, OK is returned. If the target user is not logged in or if anything else goes wrong, ERROR is returned. + + If the server supports extended paging, sending a zero-length message +merely checks for the presence of the requested user without actually sending +a message. Sending a message consisting solely of a "-" (hyphen) will cause +the server to return SEND_LISTING if the requested user is logged in, and the +client can then transmit a multi-line page. - In Citadel/UX 5.00 and above, the reserved name "broadcast" may be used -instead of a user name, to broadcast an express message to all users -currently connected to the server. + The reserved name "broadcast" may be used instead of a user name, to +broadcast an express message to all users currently connected to the server. Do be aware that if an express message is transmitted to a user who is logged in using a client that does not check for express messages, the message will @@ -1602,6 +1610,7 @@ fails for any reason, ERROR is returned. 16. Password for server-to-server networking 17. Default purge time (in days) for users 18. Default purge time (in days) for rooms + 19. Name of room to log express messages to (or a zero-length name for none) -- 2.39.2