X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fcitadel.c;h=7e5ef874a2351bf2233c80e1a4b657bdce81c01f;hb=4eb74b26380dfde31c86c685f0589e0c653aebf0;hp=b18eb2e92278070a5ebbf3976f333834c65a0a1f;hpb=66a3c3763a6d805e292ddde06c905dffccc0a877;p=citadel.git diff --git a/citadel/citadel.c b/citadel/citadel.c index b18eb2e92..7e5ef874a 100644 --- a/citadel/citadel.c +++ b/citadel/citadel.c @@ -2,6 +2,22 @@ * $Id$ * * Main source module for the client program. + * + * Copyright (c) 1987-2009 by the citadel.org team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "sysdep.h" @@ -32,26 +48,27 @@ #include #include #include - +#include #include "citadel.h" #include "citadel_ipc.h" #include "axdefs.h" #include "routines.h" #include "routines2.h" +#include "tuiconfig.h" #include "rooms.h" #include "messages.h" #include "commands.h" #include "client_chat.h" #include "client_passwords.h" #include "citadel_decls.h" -#include "tools.h" -#include "acconfig.h" +#include "sysdep.h" #ifndef HAVE_SNPRINTF #include "snprintf.h" #endif #include "screen.h" #include "citadel_dirs.h" +#include "ecrash.h" #include "md5.h" #define IFEXPERT if (userflags&US_EXPERT) @@ -61,7 +78,7 @@ int rordercmp(struct ctdlroomlisting *r1, struct ctdlroomlisting *r2); -struct march *march = NULL; +march *marchptr = NULL; /* globals associated with the client program */ char temp[PATH_MAX]; /* Name of general-purpose temp file */ @@ -102,13 +119,29 @@ char curr_floor = 0; /* number of current floor */ char floorlist[128][SIZ]; /* names of floors */ int termn8 = 0; /* Set to nonzero to cause a logoff */ int secure; /* Set to nonzero when wire is encrypted */ -int can_do_msg4 = 0; /* Set to nonzero if the server can handle MSG4 commands */ extern char instant_msgs; /* instant messages waiting! */ extern int rc_ansi_color; /* ansi color value from citadel.rc */ extern int next_lazy_cmd; CtdlIPC *ipc_for_signal_handlers; /* KLUDGE cover your eyes */ +int enable_syslog = 0; + + +/* + * CtdlLogPrintf() ... Write logging information; + * simple here to have the same + * symbols in the client. + */ + +void CtdlLogPrintf(enum LogLevel loglevel, const char *format, ...) { + va_list arg_ptr; + + va_start(arg_ptr, format); + vfprintf(stderr, format, arg_ptr); + va_end(arg_ptr); + fflush(stderr); +} /* * here is our 'clean up gracefully and exit' routine @@ -221,9 +254,9 @@ void userlist(CtdlIPC *ipc, char *patn) return; } - pprintf(" User Name Num L LastCall Calls Posts\n"); - pprintf("------------------------- ----- - ---------- ----- -----\n"); - if (listing != NULL) while (strlen(listing) > 0) { + pprintf(" User Name Num L Last Visit Logins Messages\n"); + pprintf("------------------------- ----- - ---------- ------ --------\n"); + if (listing != NULL) while (!IsEmptyStr(listing)) { extract_token(buf, listing, 0, '\n', sizeof buf); remove_token(listing, 0, '\n'); @@ -239,7 +272,7 @@ void userlist(CtdlIPC *ipc, char *patn) (tmbuf.tm_mon + 1), tmbuf.tm_mday, (tmbuf.tm_year + 1900)); - pprintf("%5ld %5ld\n", extract_long(buf, 4), extract_long(buf, 5)); + pprintf("%6ld %8ld\n", extract_long(buf, 4), extract_long(buf, 5)); } } @@ -273,18 +306,18 @@ void remove_march(char *roomname, int floornum) { struct march *mptr, *mptr2; - if (march == NULL) + if (marchptr == NULL) return; - if ((!strcasecmp(march->march_name, roomname)) - || ((!strcasecmp(roomname, "_FLOOR_")) && (march->march_floor == floornum))) { - mptr = march->next; - free(march); - march = mptr; + if ((!strcasecmp(marchptr->march_name, roomname)) + || ((!strcasecmp(roomname, "_FLOOR_")) && (marchptr->march_floor == floornum))) { + mptr = marchptr->next; + free(marchptr); + marchptr = mptr; return; } - mptr2 = march; - for (mptr = march; mptr != NULL; mptr = mptr->next) { + mptr2 = marchptr; + for (mptr = marchptr; mptr != NULL; mptr = mptr->next) { if ((!strcasecmp(mptr->march_name, roomname)) || ((!strcasecmp(roomname, "_FLOOR_")) @@ -351,6 +384,7 @@ void dotgoto(CtdlIPC *ipc, char *towhere, int display_name, int fromungoto) int ugpos = uglistsize; int r; /* IPC result code */ struct ctdlipcroom *room = NULL; + int rv = 0; /* store ungoto information */ if (fromungoto == 0) { @@ -420,7 +454,7 @@ void dotgoto(CtdlIPC *ipc, char *towhere, int display_name, int fromungoto) } } - if (strlen(bbb) == 0) { + if (IsEmptyStr(bbb)) { scr_printf("No room '%s'.\n", towhere); return; } @@ -432,7 +466,7 @@ void dotgoto(CtdlIPC *ipc, char *towhere, int display_name, int fromungoto) } safestrncpy(room_name, room->RRname, ROOMNAMELEN); room_flags = room->RRflags; - room_flags = room->RRflags2; + room_flags2 = room->RRflags2; from_floor = curr_floor; curr_floor = room->RRfloor; @@ -484,8 +518,8 @@ void dotgoto(CtdlIPC *ipc, char *towhere, int display_name, int fromungoto) newmailcount); } color(DIM_WHITE); - if (strlen(rc_gotmail_cmd) > 0) { - system(rc_gotmail_cmd); + if (!IsEmptyStr(rc_gotmail_cmd)) { + rv = system(rc_gotmail_cmd); } } status_line(ipc->ServInfo.humannode, ipc->ServInfo.site_location, @@ -508,20 +542,22 @@ void gotonext(CtdlIPC *ipc) /* Check to see if the march-mode list is already allocated. * If it is, pop the first room off the list and go there. */ - if (march == NULL) { + if (marchptr == NULL) { r = CtdlIPCKnownRooms(ipc, SubscribedRoomsWithNewMessages, - AllFloors, &march, buf); + AllFloors, &marchptr, buf); /* add _BASEROOM_ to the end of the march list, so the user will end up * in the system base room (usually the Lobby>) at the end of the loop */ mptr = (struct march *) malloc(sizeof(struct march)); mptr->next = NULL; + mptr->march_order = 0; + mptr->march_floor = 0; strcpy(mptr->march_name, "_BASEROOM_"); - if (march == NULL) { - march = mptr; + if (marchptr == NULL) { + marchptr = mptr; } else { - mptr2 = march; + mptr2 = marchptr; while (mptr2->next != NULL) mptr2 = mptr2->next; mptr2->next = mptr; @@ -532,8 +568,8 @@ void gotonext(CtdlIPC *ipc) */ remove_march(room_name, 0); } - if (march != NULL) { - strcpy(next_room, pop_march(curr_floor, march)); + if (marchptr != NULL) { + strcpy(next_room, pop_march(curr_floor, marchptr)); } else { strcpy(next_room, "_BASEROOM_"); } @@ -635,7 +671,7 @@ void gotofloor(CtdlIPC *ipc, char *towhere, int mode) scr_printf("No floor '%s'.\n", towhere); return; } - for (mptr = march; mptr != NULL; mptr = mptr->next) { + for (mptr = marchptr; mptr != NULL; mptr = mptr->next) { if ((mptr->march_floor) == tofloor) { gf_toroom(ipc, mptr->march_name, mode); return; @@ -659,7 +695,7 @@ void gotofloor(CtdlIPC *ipc, char *towhere, int mode) mptr = tmp; } } - if (strlen(targ) > 0) { + if (!IsEmptyStr(targ)) { gf_toroom(ipc, targ, mode); return; } @@ -681,7 +717,7 @@ void gotofloor(CtdlIPC *ipc, char *towhere, int mode) mptr = tmp; } } - if (strlen(targ) > 0) { + if (!IsEmptyStr(targ)) { gf_toroom(ipc, targ, mode); } else { scr_printf("There are no rooms on '%s'.\n", &floorlist[tofloor][0]); @@ -747,7 +783,7 @@ void gotoroomstep(CtdlIPC *ipc, int direction, int mode) struct ctdlroomlisting *rs; int list_it; char rmname[ROOMNAMELEN]; - int rmslot; + int rmslot = 0; int rmtotal; /* Ask the server for a room list */ @@ -950,7 +986,7 @@ void read_config(CtdlIPC *ipc) scr_printf("Enable color support: "); color(BRIGHT_CYAN); scr_printf("%s\n", (user->flags & US_COLOR)? "Yes" : "No"); color(DIM_WHITE); } scr_printf("Be unlisted in userlog: "); color(BRIGHT_CYAN); scr_printf("%s\n", (user->flags & US_UNLISTED)? "Yes" : "No"); color(DIM_WHITE); - if (strlen(editor_paths[0]) > 0) { + if (!IsEmptyStr(editor_paths[0])) { scr_printf("Always enter messages with the full-screen editor: "); color(BRIGHT_CYAN); scr_printf("%s\n", (user->flags & US_EXTEDIT)? "Yes" : "No"); color(DIM_WHITE); } free(user); @@ -990,11 +1026,12 @@ void system_info(CtdlIPC *ipc) scr_printf("You are connected to %s (%s) @%s\n", ipc->ServInfo.nodename, ipc->ServInfo.humannode, ipc->ServInfo.fqdn); scr_printf("running %s with text client v%.2f,\n", ipc->ServInfo.software, (float)REV_LEVEL/100); + scr_printf("server build %s,\n", ipc->ServInfo.svn_revision, (float)REV_LEVEL/100); scr_printf("and located in %s.\n", ipc->ServInfo.site_location); scr_printf("Connected users %d / Active users %d / Highest message #%ld\n", mrtg_users, mrtg_active_users, mrtg_himessage); scr_printf("Server uptime: %s\n", mrtg_server_uptime); scr_printf("Your system administrator is %s.\n", ipc->ServInfo.sysadm); - scr_printf("Copyright (C)1987-2007 by the Citadel development team\n"); + scr_printf("Copyright (C)1987-2009 by the Citadel development team\n"); } /* @@ -1076,7 +1113,7 @@ int set_password(CtdlIPC *ipc) char pass2[20]; char buf[SIZ]; - if (strlen(rc_password) > 0) { + if (!IsEmptyStr(rc_password)) { strcpy(pass1, rc_password); strcpy(pass2, rc_password); } else { @@ -1115,6 +1152,14 @@ void get_serv_info(CtdlIPC *ipc, char *supplied_hostname) /* Look up the , in the bible if you're confused */ (locate_host(ipc, buf), buf), buf); + /* Indicate to the server that we prefer to decode Base64 and + * quoted-printable on the client side. + */ + if ((CtdlIPCSpecifyPreferredFormats(ipc, buf, "dont_decode") / 100 ) != 2) { + scr_printf("ERROR: Extremely old server; MSG4 framework not supported.\n"); + logoff(ipc, 0); + } + /* * Tell the server what our preferred content formats are. * @@ -1123,8 +1168,9 @@ void get_serv_info(CtdlIPC *ipc, char *supplied_hostname) * isn't really all that great, it's probably better to just go with * the plain text when we have it available. */ - if ((CtdlIPCSpecifyPreferredFormats(ipc, buf, "text/plain|text/html") / 100 )== 2) { - can_do_msg4 = 1; + if ((CtdlIPCSpecifyPreferredFormats(ipc, buf, "text/plain|text/html") / 100 ) != 2) { + scr_printf("ERROR: Extremely old server; MSG4 framework not supported.\n"); + logoff(ipc, 0); } } @@ -1212,14 +1258,18 @@ void who_is_online(CtdlIPC *ipc, int longlist) if (!longlist) { color(BRIGHT_WHITE); - pprintf(" User Name Room Idle From host\n"); + pprintf(" User Name Room "); + if (screenwidth >= 80) pprintf(" Idle From host"); + pprintf("\n"); color(DIM_WHITE); - pprintf(" ------------------------- -------------------- ---- ------------------------\n"); + pprintf(" ------------------------- --------------------"); + if (screenwidth >= 80) pprintf(" ---- ------------------------"); + pprintf("\n"); } r = CtdlIPCOnlineUsers(ipc, &listing, &timenow, buf); listing = SortOnlineUsers(listing); if (r / 100 == 1) { - while (strlen(listing) > 0) { + while (!IsEmptyStr(listing)) { int isidle = 0; /* Get another line */ @@ -1238,14 +1288,9 @@ void who_is_online(CtdlIPC *ipc, int longlist) idlesecs = (idletime - (idlehours * 3600) - (idlemins * 60)); if (idletime > rc_idle_threshold) { - /* - while (strlen(roomname) < 20) { - strcat(roomname, " "); - } - strcpy(&roomname[14], "[idle]"); - */ - if (skipidle) + if (skipidle) { isidle = 1; + } } if (longlist) { @@ -1264,57 +1309,64 @@ void who_is_online(CtdlIPC *ipc, int longlist) (long) idlemins, (long) idlesecs); - if ( (strlen(actual_user)+strlen(actual_room)+strlen(actual_host)) > 0) { + if ( (!IsEmptyStr(actual_user)&& + !IsEmptyStr(actual_room)&& + !IsEmptyStr(actual_host))) { pprintf("(really "); - if (strlen(actual_user)>0) pprintf("<%s> ", actual_user); - if (strlen(actual_room)>0) pprintf("in <%s> ", actual_room); - if (strlen(actual_host)>0) pprintf("from <%s> ", actual_host); + if (!IsEmptyStr(actual_user)) pprintf("<%s> ", actual_user); + if (!IsEmptyStr(actual_room)) pprintf("in <%s> ", actual_room); + if (!IsEmptyStr(actual_host)) pprintf("from <%s> ", actual_host); pprintf(")\n"); } pprintf("\n"); } else { - if (isidle == 0) { - if (extract_int(buf, 0) == last_session) { - pprintf(" "); - } else { + if (isidle == 0) { + if (extract_int(buf, 0) == last_session) { + pprintf(" "); + } + else { + color(BRIGHT_MAGENTA); + pprintf("%-3s", flags); + } + last_session = extract_int(buf, 0); + color(BRIGHT_CYAN); + pprintf("%-25s ", username); color(BRIGHT_MAGENTA); - pprintf("%-3s", flags); - } - last_session = extract_int(buf, 0); - color(BRIGHT_CYAN); - pprintf("%-25s ", username); - color(BRIGHT_MAGENTA); - roomname[20] = 0; - pprintf("%-20s ", roomname); - if (idletime > rc_idle_threshold) { - /* over 1000d, must be gone fishing */ - if (idlehours > 23999) { - pprintf("fish"); - /* over 10 days */ - } else if (idlehours > 239) { - pprintf("%3ldd", - idlehours / 24); - /* over 10 hours */ - } else if (idlehours > 9) { - pprintf("%1ldd%02ld", - idlehours / 24, - idlehours % 24); - /* less than 10 hours */ - } else { - pprintf("%1ld:%02ld", - idlehours, idlemins); + roomname[20] = 0; + pprintf("%-20s", roomname); + + if (screenwidth >= 80) { + pprintf(" "); + if (idletime > rc_idle_threshold) { + /* over 1000d, must be gone fishing */ + if (idlehours > 23999) { + pprintf("fish"); + /* over 10 days */ + } else if (idlehours > 239) { + pprintf("%3ldd", idlehours / 24); + /* over 10 hours */ + } else if (idlehours > 9) { + pprintf("%1ldd%02ld", + idlehours / 24, + idlehours % 24); + /* less than 10 hours */ + } + else { + pprintf("%1ld:%02ld", idlehours, idlemins); + } + } + else { + pprintf(" "); + } + pprintf(" "); + color(BRIGHT_CYAN); + fromhost[24] = '\0'; + pprintf("%-24s", fromhost); } - } - else { - pprintf(" "); - } - pprintf(" "); - color(BRIGHT_CYAN); - fromhost[24] = '\0'; - pprintf("%-24s\n", fromhost); - color(DIM_WHITE); - } + pprintf("\n"); + color(DIM_WHITE); + } } } } @@ -1363,16 +1415,36 @@ int main(int argc, char **argv) struct ctdluser *myself = NULL; CtdlIPC* ipc; /* Our server connection */ int r; /* IPC result code */ + int rv = 0; /* fetch but ignore syscall return value to suppress warnings */ int relh=0; int home=0; char relhome[PATH_MAX]=""; char ctdldir[PATH_MAX]=CTDLDIR; - - - - calc_dirs_n_files(relh, home, relhome, ctdldir); - + int lp; +#ifdef HAVE_BACKTRACE + eCrashParameters params; +// eCrashSymbolTable symbol_table; +#endif + calc_dirs_n_files(relh, home, relhome, ctdldir, 0); + +#ifdef HAVE_BACKTRACE + bzero(¶ms, sizeof(params)); + params.filename = file_pid_paniclog; +// panic_fd=open(file_pid_paniclog, O_APPEND|O_CREAT|O_DIRECT); + params.filep = fopen(file_pid_paniclog, "a+"); + params.debugLevel = ECRASH_DEBUG_VERBOSE; + params.dumpAllThreads = TRUE; + params.useBacktraceSymbols = 1; +/// BuildSymbolTable(&symbol_table); +// params.symbolTable = &symbol_table; + params.signals[0]=SIGSEGV; + params.signals[1]=SIGILL; + params.signals[2]=SIGBUS; + params.signals[3]=SIGABRT; + + eCrash_Init(¶ms); +#endif setIPCDeathHook(screen_delete); setIPCErrorPrintf(err_printf); setCryptoStatusHook(statusHook); @@ -1553,7 +1625,7 @@ int main(int argc, char **argv) GSTA: /* See if we have a username and password on disk */ if (rc_remember_passwords) { get_stored_password(hostbuf, portbuf, fullname, password); - if (strlen(fullname) > 0) { + if (!IsEmptyStr(fullname)) { r = CtdlIPCTryLogin(ipc, fullname, aaa); if (r / 100 == 3) { if (*nonce) { @@ -1576,7 +1648,7 @@ int main(int argc, char **argv) termn8 = 0; newnow = 0; do { - if (strlen(rc_username) > 0) { + if (!IsEmptyStr(rc_username)) { strcpy(fullname, rc_username); } else { newprompt("Enter your name: ", fullname, 29); @@ -1588,7 +1660,7 @@ int main(int argc, char **argv) } while ( (!strcasecmp(fullname, "bbs")) || (!strcasecmp(fullname, "new")) - || (strlen(fullname) == 0)); + || (IsEmptyStr(fullname))); if (!strcasecmp(fullname, "off")) { mcmd = 29; @@ -1600,7 +1672,7 @@ int main(int argc, char **argv) goto NEWUSR; /* password authentication */ - if (strlen(rc_password) > 0) { + if (!IsEmptyStr(rc_password)) { strcpy(password, rc_password); } else { newprompt("\rPlease enter your password: ", password, -19); @@ -1620,11 +1692,11 @@ int main(int argc, char **argv) goto PWOK; } scr_printf("<< wrong password >>\n"); - if (strlen(rc_password) > 0) + if (!IsEmptyStr(rc_password)) logoff(ipc, 2); goto GSTA; -NEWUSR: if (strlen(rc_password) == 0) { +NEWUSR: if (IsEmptyStr(rc_password)) { scr_printf("'%s' not found.\n", fullname); scr_printf("Type 'off' if you would like to exit.\n"); if (ipc->ServInfo.newuser_disabled == 1) { @@ -1679,8 +1751,8 @@ NEWUSR: if (strlen(rc_password) == 0) { if (b > 1) scr_printf("*** You have %d new private messages in Mail>\n", b); color(DIM_WHITE); - if (strlen(rc_gotmail_cmd) > 0) { - system(rc_gotmail_cmd); + if (!IsEmptyStr(rc_gotmail_cmd)) { + rv = system(rc_gotmail_cmd); } } if ((axlevel >= 6) && (chek.needvalid > 0)) { @@ -1780,13 +1852,13 @@ NEWUSR: if (strlen(rc_password) == 0) { dotgoto(ipc, "_MAIL_", 1, 0); break; case 20: - if (strlen(argbuf) > 0) { + if (!IsEmptyStr(argbuf)) { updatels(ipc); dotgoto(ipc, argbuf, 0, 0); } break; case 52: - if (strlen(argbuf) > 0) { + if (!IsEmptyStr(argbuf)) { if (rc_alt_semantics) { updatelsa(ipc); } @@ -2150,10 +2222,6 @@ NEWUSR: if (strlen(rc_password) == 0) { deletefile(ipc); break; - case 53: - netsendfile(ipc); - break; - case 54: movefile(ipc); break; @@ -2230,6 +2298,14 @@ NEWUSR: if (strlen(rc_password) == 0) { dotknown(ipc, 6, NULL); break; + case 127: /* Configure POP3 aggregation */ + do_pop3client_configuration(ipc); + break; + + case 128: /* Configure XML/RSS feed retrieval */ + do_rssclient_configuration(ipc); + break; + default: /* allow some math on the command */ /* commands 100... to 100+MAX_EDITORS-1 will call the appropriate editor... in other @@ -2248,8 +2324,8 @@ TERMN8: scr_printf("%s logged out.", fullname); termn8 = 0; color(ORIGINAL_PAIR); scr_printf("\n"); - while (march != NULL) { - remove_march(march->march_name, 0); + while (marchptr != NULL) { + remove_march(marchptr->march_name, 0); } if (mcmd == 30) { sln_printf("\n\nType 'off' to disconnect, or next user...\n"); @@ -2261,6 +2337,12 @@ TERMN8: scr_printf("%s logged out.", fullname); formout(ipc, "goodbye"); logoff(ipc, 0); } + /* Free the ungoto list */ + for (lp = 0; lp < uglistsize; lp++) { + free(uglist[lp]); + } + uglistsize = 0; goto GSTA; } /* end main() */ +