X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fcitadel.c;h=7e5ef874a2351bf2233c80e1a4b657bdce81c01f;hb=4eb74b26380dfde31c86c685f0589e0c653aebf0;hp=6779f8978c8b825a245f87a9eb02d22839be2f53;hpb=1248e88ae490d17b4896ada5a74a0a9ea23b365c;p=citadel.git diff --git a/citadel/citadel.c b/citadel/citadel.c index 6779f8978..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) @@ -59,7 +76,9 @@ #define IFAIDE if (axlevel>=6) #define IFNAIDE if (axlevel<6) -struct march *march = NULL; +int rordercmp(struct ctdlroomlisting *r1, struct ctdlroomlisting *r2); + +march *marchptr = NULL; /* globals associated with the client program */ char temp[PATH_MAX]; /* Name of general-purpose temp file */ @@ -72,6 +91,7 @@ char fullname[USERNAME_SIZE]; int screenwidth; int screenheight; unsigned room_flags; +unsigned room_flags2; char room_name[ROOMNAMELEN]; char *uglist[UGLISTLEN]; /* size of the ungoto list */ long uglistlsn[UGLISTLEN]; /* current read position for all the ungoto's. Not going to make any friends with this one. */ @@ -99,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 @@ -218,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'); @@ -236,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)); } } @@ -270,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_")) @@ -301,7 +337,7 @@ void remove_march(char *roomname, int floornum) * Locate the room on the march list which we most want to go to. Each room * is measured given a "weight" of preference based on various factors. */ -char *pop_march(int desired_floor) +char *pop_march(int desired_floor, struct march *_march) { static char TheRoom[ROOMNAMELEN]; int TheFloor = 0; @@ -311,10 +347,10 @@ char *pop_march(int desired_floor) struct march *mptr = NULL; strcpy(TheRoom, "_BASEROOM_"); - if (march == NULL) + if (_march == NULL) return (TheRoom); - for (mptr = march; mptr != NULL; mptr = mptr->next) { + for (mptr = _march; mptr != NULL; mptr = mptr->next) { weight = 0; if ((strcasecmp(mptr->march_name, "_BASEROOM_"))) weight = weight + 10000; @@ -348,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) { @@ -417,11 +454,10 @@ 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; } - room = NULL; r = CtdlIPCGotoRoom(ipc, bbb, "", &room, aaa); } if (r / 100 != 1 && r / 100 != 2) { @@ -430,6 +466,7 @@ void dotgoto(CtdlIPC *ipc, char *towhere, int display_name, int fromungoto) } safestrncpy(room_name, room->RRname, ROOMNAMELEN); room_flags = room->RRflags; + room_flags2 = room->RRflags2; from_floor = curr_floor; curr_floor = room->RRfloor; @@ -481,12 +518,13 @@ 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, room_name, secure, newmailcount); + free(room); } /* Goto next room having unread messages. @@ -504,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; @@ -528,8 +568,8 @@ void gotonext(CtdlIPC *ipc) */ remove_march(room_name, 0); } - if (march != NULL) { - strcpy(next_room, pop_march(curr_floor)); + if (marchptr != NULL) { + strcpy(next_room, pop_march(curr_floor, marchptr)); } else { strcpy(next_room, "_BASEROOM_"); } @@ -569,6 +609,7 @@ void forget_all_rooms_on(CtdlIPC *ipc, int ffloor) flist = flist->next; free(fptr); } + if (room) free(room); } @@ -630,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; @@ -645,16 +686,16 @@ void gotofloor(CtdlIPC *ipc, char *towhere, int mode) if (r / 100 == 1) { struct march *tmp = mptr; - /* TODO: room order is being ignored? */ + /*. . . according to room order */ if (mptr) - strncpy(targ, mptr->march_name, ROOMNAMELEN); + strcpy(targ, pop_march(tofloor, mptr)); while (mptr) { tmp = mptr->next; free(mptr); mptr = tmp; } } - if (strlen(targ) > 0) { + if (!IsEmptyStr(targ)) { gf_toroom(ipc, targ, mode); return; } @@ -666,23 +707,332 @@ void gotofloor(CtdlIPC *ipc, char *towhere, int mode) r = CtdlIPCKnownRooms(ipc, AllAccessibleRooms, tofloor, &mptr, buf); if (r / 100 == 1) { struct march *tmp = mptr; - - /* TODO: room order is being ignored? */ + + /*. . . according to room order */ if (mptr) - strncpy(targ, mptr->march_name, ROOMNAMELEN); + strcpy(targ, pop_march(tofloor, mptr)); while (mptr) { tmp = mptr->next; free(mptr); 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]); } } +/* + * Indexing mechanism for a room list, called by gotoroomstep() + */ +void room_tree_list_query(struct ctdlroomlisting *rp, char *findrmname, int findrmslot, char *rmname, int *rmslot, int *rmtotal) +{ + char roomname[ROOMNAMELEN]; + static int cur_rmslot = 0; + + if (rp == NULL) { + cur_rmslot = 0; + return; + } + + if (rp->lnext != NULL) { + room_tree_list_query(rp->lnext, findrmname, findrmslot, rmname, rmslot, rmtotal); + } + + if (sigcaught == 0) { + strcpy(roomname, rp->rlname); + + if (rmname != NULL) { + if (cur_rmslot == findrmslot) { + strcpy(rmname, roomname); + } + } + if (rmslot != NULL) { + if (!strcmp(roomname, findrmname)) { + *rmslot = cur_rmslot; + } + } + cur_rmslot++; + } + + if (rp->rnext != NULL) { + room_tree_list_query(rp->rnext, findrmname, findrmslot, rmname, rmslot, rmtotal); + } + + if ((rmname == NULL) && (rmslot == NULL)) + free(rp); + + if (rmtotal != NULL) { + *rmtotal = cur_rmslot; + } +} + +/* + * step through rooms on current floor + */ +void gotoroomstep(CtdlIPC *ipc, int direction, int mode) +{ + struct march *listing = NULL; + struct march *mptr; + int r; /* IPC response code */ + char buf[SIZ]; + struct ctdlroomlisting *rl = NULL; + struct ctdlroomlisting *rp; + struct ctdlroomlisting *rs; + int list_it; + char rmname[ROOMNAMELEN]; + int rmslot = 0; + int rmtotal; + + /* Ask the server for a room list */ + r = CtdlIPCKnownRooms(ipc, SubscribedRooms, (-1), &listing, buf); + if (r / 100 != 1) { + listing = NULL; + } + + load_floorlist(ipc); + + for (mptr = listing; mptr != NULL; mptr = mptr->next) { + list_it = 1; + + if ( floor_mode + && (mptr->march_floor != curr_floor)) + list_it = 0; + + if (list_it) { + rp = malloc(sizeof(struct ctdlroomlisting)); + strncpy(rp->rlname, mptr->march_name, ROOMNAMELEN); + rp->rlflags = mptr->march_flags; + rp->rlfloor = mptr->march_floor; + rp->rlorder = mptr->march_order; + rp->lnext = NULL; + rp->rnext = NULL; + + rs = rl; + if (rl == NULL) { + rl = rp; + } else { + while (rp != NULL) { + if (rordercmp(rp, rs) < 0) { + if (rs->lnext == NULL) { + rs->lnext = rp; + rp = NULL; + } else { + rs = rs->lnext; + } + } else { + if (rs->rnext == NULL) { + rs->rnext = rp; + rp = NULL; + } else { + rs = rs->rnext; + } + } + } + } + } + } + + /* Find position of current room */ + room_tree_list_query(NULL, NULL, 0, NULL, NULL, NULL); + room_tree_list_query(rl, room_name, 0, NULL, &rmslot, &rmtotal); + + if (direction == 0) { /* Previous room */ + /* If we're at the first room, wrap to the last room */ + if (rmslot == 0) { + rmslot = rmtotal - 1; + } else { + rmslot--; + } + } else { /* Next room */ + /* If we're at the last room, wrap to the first room */ + if (rmslot == rmtotal - 1) { + rmslot = 0; + } else { + rmslot++; + } + } + + /* Get name of next/previous room */ + room_tree_list_query(NULL, NULL, 0, NULL, NULL, NULL); + room_tree_list_query(rl, NULL, rmslot, rmname, NULL, NULL); + + /* Free the tree */ + room_tree_list_query(rl, NULL, 0, NULL, NULL, NULL); + + if (mode == 0) { /* not skipping */ + updatels(ipc); + } else { + if (rc_alt_semantics) { + updatelsa(ipc); + } + } + + /* Free the room list */ + while (listing) { + mptr = listing->next; + free(listing); + listing = mptr; + }; + + dotgoto(ipc, rmname, 1, 0); +} + + +/* + * step through floors on system + */ +void gotofloorstep(CtdlIPC *ipc, int direction, int mode) +{ + int tofloor; + + if (floorlist[0][0] == 0) + load_floorlist(ipc); + + empty_keep_going: + + if (direction == 0) { /* Previous floor */ + if (curr_floor) tofloor = curr_floor - 1; + else tofloor = 127; + + while (!floorlist[tofloor][0]) tofloor--; + } else { /* Next floor */ + if (curr_floor < 127) tofloor = curr_floor + 1; + else tofloor = 0; + + while (!floorlist[tofloor][0] && tofloor < 127) tofloor++; + if (!floorlist[tofloor][0]) tofloor = 0; + } + /* ;g works when not in floor mode so . . . */ + if (!floor_mode) { + scr_printf("(%s)\n", floorlist[tofloor] ); + } + + gotofloor(ipc, floorlist[tofloor], mode); + if (curr_floor != tofloor) { /* gotofloor failed */ + curr_floor = tofloor; + goto empty_keep_going; + } +} + +/* + * Display user 'preferences'. + */ +extern int rc_prompt_control; +void read_config(CtdlIPC *ipc) +{ + char buf[SIZ]; + char *resp = NULL; + int r; /* IPC response code */ + char _fullname[USERNAME_SIZE]; + long _usernum; + int _axlevel, _timescalled, _posted; + time_t _lastcall; + struct ctdluser *user = NULL; + + /* get misc user info */ + r = CtdlIPCGetBio(ipc, fullname, &resp, buf); + if (r / 100 != 1) { + pprintf("%s\n", buf); + return; + } + extract_token(_fullname, buf, 1, '|', sizeof fullname); + _usernum = extract_long(buf, 2); + _axlevel = extract_int(buf, 3); + _lastcall = extract_long(buf, 4); + _timescalled = extract_int(buf, 5); + _posted = extract_int(buf, 6); + free(resp); + resp = NULL; + + /* get preferences */ + r = CtdlIPCGetConfig(ipc, &user, buf); + if (r / 100 != 2) { + scr_printf("%s\n", buf); + free(user); + return; + } + + /* show misc user info */ + scr_printf("%s\nAccess level: %d (%s)\n" + "User #%ld / %d Calls / %d Posts", + _fullname, _axlevel, axdefs[(int) _axlevel], + _usernum, _timescalled, _posted); + if (_lastcall > 0L) { + scr_printf(" / Curr login: %s", + asctime(localtime(&_lastcall))); + } + scr_printf("\n"); + + /* show preferences */ + scr_printf("Your screen width: "); color(BRIGHT_CYAN); scr_printf("%d", /*user->USscreenwidth*/ screenwidth); color(DIM_WHITE); + scr_printf(", height: "); color(BRIGHT_CYAN); scr_printf("%d\n", /*user->USscreenheight*/ screenheight); color(DIM_WHITE); + scr_printf("Are you an experienced Citadel user: "); color(BRIGHT_CYAN); scr_printf("%s\n", (user->flags & US_EXPERT) ? "Yes" : "No"); color(DIM_WHITE); + scr_printf("Print last old message on New message request: "); color(BRIGHT_CYAN); scr_printf("%s\n", (user->flags & US_LASTOLD)? "Yes" : "No"); color(DIM_WHITE); + scr_printf("Prompt after each message: "); color(BRIGHT_CYAN); scr_printf("%s\n", (!(user->flags & US_NOPROMPT))? "Yes" : "No"); color(DIM_WHITE); + if ((user->flags & US_NOPROMPT) == 0) { + scr_printf("Use 'disappearing' prompts: "); color(BRIGHT_CYAN); scr_printf("%s\n", (user->flags & US_DISAPPEAR)? "Yes" : "No"); color(DIM_WHITE); + } + scr_printf("Pause after each screenful of text: "); color(BRIGHT_CYAN); scr_printf("%s\n", (user->flags & US_PAGINATOR)? "Yes" : "No"); color(DIM_WHITE); + if (rc_prompt_control == 3 && (user->flags & US_PAGINATOR)) { + scr_printf("ext and top work at paginator prompt: "); color(BRIGHT_CYAN); scr_printf("%s\n", (user->flags & US_PROMPTCTL)? "Yes" : "No"); color(DIM_WHITE); + } + if (rc_floor_mode == RC_DEFAULT) { + scr_printf("View rooms by floor: "); color(BRIGHT_CYAN); scr_printf("%s\n", (user->flags & US_FLOORS)? "Yes" : "No"); color(DIM_WHITE); + } + if (rc_ansi_color == 3) { + 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 (!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); +} + +/* + * Display system statistics. + */ +void system_info(CtdlIPC *ipc) +{ + char buf[SIZ]; + char *resp = NULL; + size_t bytes; + int mrtg_users, mrtg_active_users; + char mrtg_server_uptime[40]; + long mrtg_himessage; + int ret; /* IPC response code */ + + /* get #users, #active & server uptime */ + ret = CtdlIPCGenericCommand(ipc, "MRTG|users", NULL, 0, &resp, &bytes, buf); + mrtg_users = extract_int(resp, 0); + remove_token(resp, 0, '\n'); + mrtg_active_users = extract_int(resp, 0); + remove_token(resp, 0, '\n'); + extract_token(mrtg_server_uptime, resp, 0, '\n', sizeof mrtg_server_uptime); + free(resp); + resp = NULL; + + /* get high message# */ + ret = CtdlIPCGenericCommand(ipc, "MRTG|messages", NULL, 0, &resp, &bytes, buf); + mrtg_himessage = extract_long(resp, 0); + free(resp); + resp = NULL; + + /* refresh server info just in case */ + CtdlIPCServerInfo(ipc, buf); + + 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-2009 by the Citadel development team\n"); +} /* * forget all rooms on current floor @@ -763,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 { @@ -802,9 +1152,25 @@ 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); - /* Tell the server what our preferred content formats are */ - if ((CtdlIPCSpecifyPreferredFormats(ipc, buf, "text/html|text/plain") / 100 )== 2) { - can_do_msg4 = 1; + /* 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. + * + * Originally we preferred HTML over plain text because we can format + * it to the reader's screen width, but since our HTML-to-text parser + * 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) { + scr_printf("ERROR: Extremely old server; MSG4 framework not supported.\n"); + logoff(ipc, 0); } } @@ -862,6 +1228,8 @@ char *SortOnlineUsers(char *listing) { strcat(retbuf, &sortbuf[i*SIZ]); if (i<(rows-1)) strcat(retbuf, "\n"); } + free(listing); + free(sortbuf); return(retbuf); } @@ -890,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 */ @@ -916,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) { @@ -942,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); + } } } } @@ -1030,7 +1404,7 @@ int main(int argc, char **argv) { int a, b, mcmd; char aaa[100], bbb[100];/* general purpose variables */ - char argbuf[32]; /* command line buf */ + char argbuf[64]; /* command line buf */ char nonce[NONCE_SIZE]; char *telnet_client_host = NULL; char *sptr, *sptr2; /* USed to extract the nonce */ @@ -1041,7 +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; + 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); @@ -1143,6 +1546,7 @@ int main(int argc, char **argv) argc = shift(argc, argv, a, 1); } } + screen_new(); @@ -1221,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) { @@ -1244,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); @@ -1256,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; @@ -1268,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); @@ -1288,16 +1692,21 @@ 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) { - scr_printf("'%s' not found.\n" - "Do you want to create a new account with this name? ", +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) { + goto GSTA; + } + scr_printf("Do you want to create a new user account called '%s'? ", fullname); - if (yesno() == 0) + if (yesno() == 0) { goto GSTA; + } } r = CtdlIPCCreateUser(ipc, fullname, 1, aaa); @@ -1342,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)) { @@ -1390,6 +1799,7 @@ NEWUSR: if (strlen(rc_password) == 0) { dotgoto(ipc, "_BASEROOM_", 1, 0); /* Main loop for the system... user is logged in. */ + free(uglist[0]); uglistsize = 0; if (newnow == 1) @@ -1411,27 +1821,16 @@ NEWUSR: if (strlen(rc_password) == 0) { formout(ipc, "help"); break; case 4: - entmsg(ipc, 0, ((userflags & US_EXTEDIT) ? 2 : 0)); + entmsg(ipc, 0, ((userflags & US_EXTEDIT) ? 2 : 0), 0); break; case 36: - entmsg(ipc, 0, 1); + entmsg(ipc, 0, 1, 0); break; case 46: - entmsg(ipc, 0, 2); + entmsg(ipc, 0, 2, 0); break; case 78: - { - /* Only m.author is used */ - struct ctdlipcmessage m; - newprompt("What do you want your username to be? ", - m.author, USERNAME_SIZE - 1); - m.text = ""; - r = CtdlIPCPostMessage(ipc, 2, &m, aaa); - if (r / 100 != 2) - scr_printf("%s\n", aaa); - else - entmsg(ipc, 0, 0); - } + entmsg(ipc, 0, ((userflags & US_EXTEDIT) ? 2 : 0), 1); break; case 5: /* oto */ updatels(ipc); @@ -1453,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); } @@ -1823,10 +2222,6 @@ NEWUSR: if (strlen(rc_password) == 0) { deletefile(ipc); break; - case 53: - netsendfile(ipc); - break; - case 54: movefile(ipc); break; @@ -1835,6 +2230,82 @@ NEWUSR: if (strlen(rc_password) == 0) { page_user(ipc); break; + case 110: /* <+> Next room */ + gotoroomstep(ipc, 1, 0); + break; + + case 111: /* <-> Previous room */ + gotoroomstep(ipc, 0, 0); + break; + + case 112: /* <>> Next floor */ + gotofloorstep(ipc, 1, GF_GOTO); + break; + + case 113: /* <<> Previous floor */ + gotofloorstep(ipc, 0, GF_GOTO); + break; + + case 116: /* <.> skip to <+> Next room */ + gotoroomstep(ipc, 1, 1); + break; + + case 117: /* <.> skip to <-> Previous room */ + gotoroomstep(ipc, 0, 1); + break; + + case 118: /* <.> skip to <>> Next floor */ + gotofloorstep(ipc, 1, GF_SKIP); + break; + + case 119: /* <.> skip to <<> Previous floor */ + gotofloorstep(ipc, 0, GF_SKIP); + break; + + case 114: + read_config(ipc); + break; + + case 115: + system_info(ipc); + break; + + case 120: /* .KAnonymous */ + dotknown(ipc, 0, NULL); + break; + + case 121: /* .KDirectory */ + dotknown(ipc, 1, NULL); + break; + + case 122: /* .KMatch */ + dotknown(ipc, 2, argbuf); + break; + + case 123: /* .KpreferredOnly */ + dotknown(ipc, 3, NULL); + break; + + case 124: /* .KPrivate */ + dotknown(ipc, 4, NULL); + break; + + case 125: /* .KRead only */ + dotknown(ipc, 5, NULL); + break; + + case 126: /* .KShared */ + 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 @@ -1843,7 +2314,7 @@ NEWUSR: if (strlen(rc_password) == 0) { if (mcmd >= 100 && mcmd < (100+MAX_EDITORS)) { /* entmsg mode >=2 select editor */ - entmsg(ipc, 0, mcmd - 100 + 2); + entmsg(ipc, 0, mcmd - 100 + 2, 0); break; } } /* end switch */ @@ -1853,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"); @@ -1866,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() */ +