User Biography display: remove call, do through templates directly.
[citadel.git] / citadel / textclient / citadel.c
index 532f4467ffdcdabba736875c387d5f23f568caf1..5821df40413c8b86f7fd7e85ebf8c66a5235aa96 100644 (file)
@@ -1,21 +1,15 @@
 /*
  * Main source module for the client program.
  *
- * Copyright (c) 1987-2009 by the citadel.org team
+ * Copyright (c) 1987-2012 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 open source software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3.
  *
  *  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"
@@ -82,12 +76,9 @@ extern char *moreprompt;
 char temp[PATH_MAX];           /* Name of general-purpose temp file */
 char temp2[PATH_MAX];          /* Name of general-purpose temp file */
 char tempdir[PATH_MAX];                /* Name of general-purpose temp directory */
-char editor_paths[MAX_EDITORS][SIZ];   /* paths to external editors */
 char printcmd[SIZ];            /* print command */
 int editor_pid = (-1);
 char fullname[USERNAME_SIZE];
-int screenwidth;
-int screenheight;
 unsigned room_flags;
 unsigned room_flags2;
 int entmsg_ok = 0;
@@ -107,7 +98,6 @@ char newnow;
 long highest_msg_read;         /* used for <A>bandon room cmd */
 long maxmsgnum;                        /* used for <G>oto */
 char sigcaught = 0;
-char have_xterm = 0;           /* are we running on an xterm? */
 char rc_username[USERNAME_SIZE];
 char rc_password[32];
 char hostbuf[SIZ];
@@ -127,21 +117,6 @@ 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
  */
@@ -335,8 +310,6 @@ void remove_march(char *roomname, int floornum)
 char *pop_march(int desired_floor, struct march *_march)
 {
        static char TheRoom[ROOMNAMELEN];
-       int TheFloor = 0;
-       int TheOrder = 32767;
        int TheWeight = 0;
        int weight;
        struct march *mptr = NULL;
@@ -358,8 +331,6 @@ char *pop_march(int desired_floor, struct march *_march)
                if (weight > TheWeight) {
                        TheWeight = weight;
                        strcpy(TheRoom, mptr->march_name);
-                       TheFloor = mptr->march_floor;
-                       TheOrder = mptr->march_order;
                }
        }
        return (TheRoom);
@@ -529,6 +500,9 @@ void dotgoto(CtdlIPC *ipc, char *towhere, int display_name, int fromungoto)
                color(DIM_WHITE);
                if (!IsEmptyStr(rc_gotmail_cmd)) {
                        rv = system(rc_gotmail_cmd);
+                       if (rv) 
+                               scr_printf("*** failed to check for mail calling %s Reason %d.\n",
+                                          rc_gotmail_cmd, rv);
                }
        }
        free(room);
@@ -552,14 +526,13 @@ void gotonext(CtdlIPC *ipc)
        char buf[SIZ];
        struct march *mptr, *mptr2;
        char next_room[ROOMNAMELEN];
-       int r;                          /* IPC response code */
 
        /* 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 (marchptr == NULL) {
-               r = CtdlIPCKnownRooms(ipc, SubscribedRoomsWithNewMessages,
-                                       AllFloors, &marchptr, buf);
+               CtdlIPCKnownRooms(ipc, SubscribedRoomsWithNewMessages,
+                                 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
@@ -604,7 +577,6 @@ void forget_all_rooms_on(CtdlIPC *ipc, int ffloor)
        int r;                          /* IPC response code */
 
        scr_printf("Forgetting all rooms on %s...\n", &floorlist[ffloor][0]);
-       scr_flush();
        remove_march("_FLOOR_", ffloor);
        r = CtdlIPCKnownRooms(ipc, AllAccessibleRooms, ffloor, &flist, buf);
        if (r / 100 != 1) {
@@ -879,10 +851,6 @@ void  gotoroomstep(CtdlIPC *ipc, int direction, int mode)
 
        if (mode == 0) { /* not skipping */
            updatels(ipc);
-       } else {
-               if (rc_alt_semantics) {
-               updatelsa(ipc);
-               }
        }
 
        /* Free the room list */
@@ -999,7 +967,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 (!IsEmptyStr(editor_paths[0])) {
+       if (!IsEmptyStr(editor_path)) {
        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);
@@ -1016,10 +984,9 @@ void system_info(CtdlIPC *ipc)
        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);
+       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);
@@ -1029,7 +996,7 @@ void system_info(CtdlIPC *ipc)
        resp = NULL;
 
        /* get high message# */
-       ret = CtdlIPCGenericCommand(ipc, "MRTG|messages", NULL, 0, &resp, &bytes, buf);
+       CtdlIPCGenericCommand(ipc, "MRTG|messages", NULL, 0, &resp, &bytes, buf);
        mrtg_himessage = extract_long(resp, 0);
        free(resp);
        resp = NULL;
@@ -1069,32 +1036,6 @@ void forget_this_floor(CtdlIPC *ipc)
 }
 
 
-/* 
- * Figure out the physical screen dimensions, if we can
- * WARNING:  this is now called from a signal handler!
- */
-void check_screen_dims(void)
-{
-#ifdef TIOCGWINSZ
-       struct {
-               unsigned short height;  /* rows */
-               unsigned short width;   /* columns */
-               unsigned short xpixels;
-               unsigned short ypixels;         /* pixels */
-       } xwinsz;
-
-       if (have_xterm) {       /* dynamically size screen if on an xterm */
-               if (ioctl(0, TIOCGWINSZ, &xwinsz) == 0) {
-                       if (xwinsz.height)
-                               screenheight = (int) xwinsz.height;
-                       if (xwinsz.width)
-                               screenwidth = (int) xwinsz.width;
-               }
-       }
-#endif
-}
-
-
 /*
  * set floor mode depending on client, server, and user settings
  */
@@ -1191,7 +1132,20 @@ void get_serv_info(CtdlIPC *ipc, char *supplied_hostname)
 
 
 /*
- * Record compare function for SortOnlineUsers()
+ * Session username compare function for SortOnlineUsers()
+ */
+int rwho_username_cmp(const void *rec1, const void *rec2) {
+       char *u1, *u2;
+
+       u1 = strchr(rec1, '|');
+       u2 = strchr(rec2, '|');
+
+       return strcasecmp( (u1?++u1:"") , (u2?++u2:"") );
+}
+
+
+/*
+ * Idle time compare function for SortOnlineUsers()
  */
 int idlecmp(const void *rec1, const void *rec2) {
        time_t i1, i2;
@@ -1209,8 +1163,11 @@ int idlecmp(const void *rec1, const void *rec2) {
  * Sort the list of online users by idle time.
  * This function frees the supplied buffer, and returns a new one
  * to the caller.  The caller is responsible for freeing the returned buffer.
+ *
+ * If 'condense' is nonzero, multiple sessions for the same user will be
+ * combined into one for brevity.
  */
-char *SortOnlineUsers(char *listing) {
+char *SortOnlineUsers(char *listing, int condense) {
        int rows;
        char *sortbuf;
        char *retbuf;
@@ -1233,17 +1190,37 @@ char *SortOnlineUsers(char *listing) {
                memcpy(&sortbuf[i*SIZ], buf, (size_t)SIZ);
        }
 
-       /* Do the sort */
+       /* Sort by idle time */
        qsort(sortbuf, rows, SIZ, idlecmp);
 
+       /* Combine multiple sessions for the same user */
+       if (condense) {
+               qsort(sortbuf, rows, SIZ, rwho_username_cmp);
+               if (rows > 1) for (i=1; i<rows; ++i) if (i>0) {
+                       char u1[USERNAME_SIZE];
+                       char u2[USERNAME_SIZE];
+                       extract_token(u1, &sortbuf[(i-1)*SIZ], 1, '|', sizeof u1);
+                       extract_token(u2, &sortbuf[i*SIZ], 1, '|', sizeof u2);
+                       if (!strcasecmp(u1, u2)) {
+                               memcpy(&sortbuf[i*SIZ], &sortbuf[(i+1)*SIZ], (rows-i-1)*SIZ);
+                               --rows;
+                               --i;
+                       }
+               }
+
+               qsort(sortbuf, rows, SIZ, idlecmp);     /* idle sort again */
+       }
+
        /* Copy back to a \n delimited list */
        strcpy(retbuf, "");
        for (i=0; i<rows; ++i) {
-               strcat(retbuf, &sortbuf[i*SIZ]);
-               if (i<(rows-1)) strcat(retbuf, "\n");
+               if (!IsEmptyStr(&sortbuf[i*SIZ])) {
+                       strcat(retbuf, &sortbuf[i*SIZ]);
+                       if (i<(rows-1)) strcat(retbuf, "\n");
+               }
        }
-    free(listing);
-    free(sortbuf);
+       free(listing);
+       free(sortbuf);
        return(retbuf);
 }
 
@@ -1281,7 +1258,7 @@ void who_is_online(CtdlIPC *ipc, int longlist)
                scr_printf("\n");
        }
        r = CtdlIPCOnlineUsers(ipc, &listing, &timenow, buf);
-       listing = SortOnlineUsers(listing);
+       listing = SortOnlineUsers(listing, (!longlist));
        if (r / 100 == 1) {
                while (!IsEmptyStr(listing)) {
                        int isidle = 0;
@@ -1408,7 +1385,6 @@ int shift(int argc, char **argv, int start, int count) {
 
 static void statusHook(char *s) {
        scr_printf(s);
-       scr_flush();
 }
 
 /*
@@ -1423,7 +1399,6 @@ int main(int argc, char **argv)
        char *telnet_client_host = NULL;
        char *sptr, *sptr2;     /* USed to extract the nonce */
        char hexstring[MD5_HEXSTRING_SIZE];
-       int stored_password = 0;
        char password[SIZ];
        struct ctdlipcmisc chek;
        struct ctdluser *myself = NULL;
@@ -1547,6 +1522,11 @@ int main(int argc, char **argv)
        
 
        screen_new();
+       /* Get screen dimensions.  First we go to a default of 80x24.
+        * Then attempt to read the actual screen size from the terminal.
+        */
+       check_screen_dims();
+
 
 #ifdef __CYGWIN__
        newprompt("Connect to (return for local server): ", hostbuf, 64);
@@ -1609,11 +1589,7 @@ int main(int argc, char **argv)
        get_serv_info(ipc, telnet_client_host);
        scr_printf("%-24s\n%s\n%s\n", ipc->ServInfo.software, ipc->ServInfo.humannode,
                   ipc->ServInfo.site_location);
-       scr_flush();
 
-       screenwidth = 80;       /* default screen dimensions */
-       screenheight = 24;
-       
        scr_printf(" pause    next    stop\n");
        scr_printf(" ctrl-s  ctrl-o  ctrl-c\n\n");
        formout(ipc, "hello");  /* print the opening greeting */
@@ -1634,7 +1610,6 @@ int main(int argc, char **argv)
 
                        if (r / 100 == 2) {
                                load_user_info(aaa);
-                               stored_password = 1;
                                goto PWOK;
                        } else {
                                set_stored_password(hostbuf, portbuf, "", "");
@@ -1678,7 +1653,7 @@ int main(int argc, char **argv)
        if (!IsEmptyStr(rc_password)) {
                strcpy(password, rc_password);
        } else {
-               newprompt("\rPlease enter your password: ", password, -19);
+               newprompt("\rPlease enter your password: ", password, -(SIZ-1));
        }
 
        if (*nonce) {
@@ -1763,6 +1738,10 @@ NEWUSR:  if (IsEmptyStr(rc_password)) {
                        color(DIM_WHITE);
                        if (!IsEmptyStr(rc_gotmail_cmd)) {
                                rv = system(rc_gotmail_cmd);
+                               if (rv)
+                                       scr_printf("*** failed to check for mail calling %s Reason %d.\n",
+                                                  rc_gotmail_cmd, rv);
+
                        }
                }
                if ((axlevel >= AxAideU) && (chek.needvalid > 0)) {
@@ -1782,21 +1761,7 @@ NEWUSR:  if (IsEmptyStr(rc_password)) {
        CtdlMakeTempFileName(temp2, sizeof temp2);
        CtdlMakeTempFileName(tempdir, sizeof tempdir);
 
-       /* Get screen dimensions.  First we go to a default of 80x24.  Then
-        * we try to get the user's actual screen dimensions off the server.
-        * However, if we're running on an xterm, all this stuff is
-        * irrelevant because we're going to dynamically size the screen
-        * during the session.
-        */
-       screenwidth = 80;
-       screenheight = 24;
        r = CtdlIPCGetConfig(ipc, &myself, aaa);
-       if (getenv("TERM") != NULL)
-               if (!strcmp(getenv("TERM"), "xterm")) {
-                       have_xterm = 1;
-               }
-       check_screen_dims();
-
        set_floor_mode(ipc);
 
        /* Enter the lobby */
@@ -1816,7 +1781,7 @@ NEWUSR:   if (IsEmptyStr(rc_password)) {
                mcmd = getcmd(ipc, argbuf);     /* Get keyboard command */
 
 #ifdef TIOCGWINSZ
-               check_screen_dims();            /* if xterm, get screen size */
+               check_screen_dims();            /* get screen size */
 #endif
 
                if (termn8 == 0)
@@ -1841,14 +1806,9 @@ NEWUSR:  if (IsEmptyStr(rc_password)) {
                                gotonext(ipc);
                                break;
                        case 47:                        /* <A>bandon */
-                               if (!rc_alt_semantics) {
-                                       updatelsa(ipc);
-                               }
                                gotonext(ipc);
                                break;
                        case 90:                        /* <.A>bandon */
-                               if (!rc_alt_semantics)
-                                       updatelsa(ipc);
                                dotgoto(ipc, argbuf, 0, 0);
                                break;
                        case 58:                        /* <M>ail */
@@ -1863,9 +1823,6 @@ NEWUSR:   if (IsEmptyStr(rc_password)) {
                                break;
                        case 52:
                                if (!IsEmptyStr(argbuf)) {
-                                       if (rc_alt_semantics) {
-                                               updatelsa(ipc);
-                                       }
                                        dotgoto(ipc, argbuf, 0, 0);
                                }
                                break;
@@ -1963,9 +1920,7 @@ NEWUSR:   if (IsEmptyStr(rc_password)) {
                                break;
                        case 29:
                        case 30:
-                               if (!rc_alt_semantics) {
-                                       updatels(ipc);
-                               }
+                               updatels(ipc);
                                termn8 = 1;
                                break;
                        case 48:
@@ -2023,8 +1978,7 @@ NEWUSR:   if (IsEmptyStr(rc_password)) {
                        case 15:
                                scr_printf("Are you sure (y/n)? ");
                                if (yesno() == 1) {
-                                       if (!rc_alt_semantics)
-                                               updatels(ipc);
+                                       updatels(ipc);
                                        a = 0;
                                        termn8 = 1;
                                }
@@ -2034,8 +1988,7 @@ NEWUSR:   if (IsEmptyStr(rc_password)) {
                                scr_printf("All users will be disconnected!  "
                                           "Really terminate the server? ");
                                if (yesno() == 1) {
-                                       if (!rc_alt_semantics)
-                                               updatels(ipc);
+                                       updatels(ipc);
                                        r = CtdlIPCTerminateServerNow(ipc, aaa);
                                        scr_printf("%s\n", aaa);
                                        if (r / 100 == 2) {
@@ -2088,9 +2041,6 @@ NEWUSR:   if (IsEmptyStr(rc_password)) {
                                break;
 
                        case 6:
-                               if (rc_alt_semantics) {
-                                       updatelsa(ipc);
-                               }
                                gotonext(ipc);
                                break;
 
@@ -2118,10 +2068,6 @@ NEWUSR:  if (IsEmptyStr(rc_password)) {
                                do_internet_configuration(ipc);
                                break;
 
-                       case 83:
-                               check_message_base(ipc);
-                               break;
-
                        case 84:
                                quiet_mode(ipc);
                                break;
@@ -2295,17 +2241,8 @@ NEWUSR:  if (IsEmptyStr(rc_password)) {
                                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
-                                  words, command numbers 100+ will match
-                                  the citadel.rc keys editor0, editor1, etc.*/
-                               if (mcmd >= 100 && mcmd < (100+MAX_EDITORS))
-                               {
-                                       /* entmsg mode >=2 select editor */
-                                       entmsg(ipc, 0, mcmd - 100 + 2, 0);
-                                       break;
-                               }
+                       default:
+                               break;
                        }       /* end switch */
        } while (termn8 == 0);