]> code.citadel.org Git - citadel.git/blobdiff - citadel/commands.c
Fixes for Cygwin (see ChangeLog)
[citadel.git] / citadel / commands.c
index 36b63a8f8bf63e489cc75a92c7e03aab44119b6a..e68c4436ca43c47f831b7e7f824b50410dcc685c 100644 (file)
@@ -5,6 +5,8 @@
  *
  * This version is the traditional command parser for room prompts.
  *
+ * $Id$
+ *
  */
 
 #include "sysdep.h"
 #include <sgtty.h>
 #endif
 
-#ifdef NEED_SELECT_H
+#ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
 #endif
 
 
 #include <signal.h>
 #include <errno.h>
+#include <stdarg.h>
 #include "citadel.h"
 #include "commands.h"
 #include "messages.h"
 #include "citadel_decls.h"
 #include "routines.h"
 #include "routines2.h"
+#ifndef HAVE_SNPRINTF
+#include "snprintf.h"
+#endif
 
 struct citcmd {
        struct citcmd *next;
@@ -50,8 +56,12 @@ struct citcmd {
 int rc_exp_beep;
 char rc_exp_cmd[256];
 int rc_allow_attachments;
+int rc_display_message_numbers;
+int rc_force_mail_prompts;
+int rc_ansi_color;
 
 char *gl_string;
+int next_lazy_cmd = 5;
 
 struct citcmd *cmdlist = NULL;
 
@@ -111,13 +121,17 @@ void set_keepalives(int s)
  */
 void do_keepalive(void) {
        char buf[256];
-       static long idlet = 0L;
-       long now;
+       static time_t idlet = 0;
+       time_t now;
 
        time(&now);
        if ((now - idlet) < ((long)S_KEEPALIVE)) return;
        time(&idlet);
 
+       /* Do a space-backspace to keep socksified telnet sessions open */
+       printf(" %c", 8);
+       fflush(stdout);
+
        if (keepalives_enabled != KA_NO) {
                serv_puts("NOOP");
                if (keepalives_enabled == KA_YES) {
@@ -125,7 +139,7 @@ void do_keepalive(void) {
                        if (buf[3]=='*') {
                                express_msgs = 1;
                                if (ok_to_interrupt == 1) {
-                                       printf("\r                    \r");
+                                       printf("\r%64s\r", "");
                                        print_express();
                                        printf("%s%c ",room_name,
                                                room_prompt(room_flags));
@@ -141,7 +155,7 @@ int inkey(void) {           /* get a character from the keyboard, with   */
        int a;          /* the watchdog timer in effect if necessary */
         fd_set rfds;
         struct timeval tv;
-       long start_time, now;
+       time_t start_time, now;
        char inbuf[2];
 
        time(&start_time);
@@ -187,6 +201,30 @@ int inkey(void) {          /* get a character from the keyboard, with   */
        return(a);
        }
 
+
+int yesno(void) { /* Returns 1 for yes, 0 for no */
+int a;
+       while (1) {
+               a=inkey(); a=tolower(a);
+               if (a=='y') { printf("Yes\n"); return(1); }
+               if (a=='n') { printf("No\n");  return(0); }
+               }
+       }
+
+int yesno_d(int d) /* Returns 1 for yes, 0 for no, arg is default value */
+       {
+int a;
+       while (1) {
+               a=inkey(); a=tolower(a);
+               if (a==13) a=(d ? 'y' : 'n');
+               if (a=='y') { printf("Yes\n"); return(1); }
+               if (a=='n') { printf("No\n");  return(0); }
+               }
+       }
+
+
+
+
 void getline(char *string, int lim)    /* Gets a line from the terminal */
                                /* Pointer to string buffer */
                        /* Maximum length - if negative, no-show */
@@ -238,6 +276,21 @@ void strprompt(char *prompt, char *str, int len)
        if (buf[0]!=0) strcpy(str,buf);
        }
 
+/*
+ * boolprompt()  -  prompt for a yes/no, print the existing value and
+ *                  allow the user to press return to keep it...
+ */
+int boolprompt(char *prompt, int prev_val) {
+       color(3);
+       printf("%s [", prompt);
+       color(1);
+       printf("%s", (prev_val ? "Yes" : "No"));
+       color(3);
+       printf("]: ");
+       color(7);
+       return(yesno_d(prev_val));
+       }
+
 /* 
  * intprompt()  -  like strprompt(), except for an integer
  *                 (note that it RETURNS the new value!)
@@ -248,7 +301,7 @@ int intprompt(char *prompt, int ival, int imin, int imax)
        int i;
        i = ival;
        do {
-               sprintf(buf,"%d",i);
+               snprintf(buf,sizeof buf,"%d",i);
                strprompt(prompt,buf,15);
                i=atoi(buf);
                if (i<imin) printf("*** Must be no less than %d.\n",imin);
@@ -285,6 +338,7 @@ void load_command_set(void) {
        FILE *ccfile;
        char buf[256];
        struct citcmd *cptr;
+       struct citcmd *lastcmd = NULL;
        int a,d;
        int b = 0;
 
@@ -299,21 +353,27 @@ void load_command_set(void) {
        rc_exp_beep = 1;
        rc_allow_attachments = 0;
        strcpy(rc_exp_cmd, "");
+       rc_display_message_numbers = 0;
+       rc_force_mail_prompts = 0;
+       rc_ansi_color = 0;
 
        /* now try to open the citadel.rc file */
 
        ccfile = NULL;
        if (getenv("HOME") != NULL) {
-               sprintf(buf,"%s/.citadelrc",getenv("HOME"));
+               snprintf(buf,sizeof buf,"%s/.citadelrc",getenv("HOME"));
                ccfile = fopen(buf,"r");
                }
        if (ccfile==NULL) {
                ccfile = fopen("/usr/local/lib/citadel.rc","r");
                }
        if (ccfile==NULL) {
-               sprintf(buf,"%s/citadel.rc",BBSDIR);
+               snprintf(buf,sizeof buf,"%s/citadel.rc",BBSDIR);
                ccfile = fopen(buf,"r");
                }
+       if (ccfile==NULL) {
+               ccfile = fopen("./citadel.rc","r");
+               }
        if (ccfile==NULL) {
                perror("commands: cannot open citadel.rc");
                logoff(errno);
@@ -349,6 +409,23 @@ void load_command_set(void) {
                rc_allow_attachments = atoi(&buf[18]);
                }
 
+           if (!struncmp(buf,"display_message_numbers=", 24)) {
+               rc_display_message_numbers = atoi(&buf[24]);
+               }
+
+           if (!struncmp(buf,"force_mail_prompts=", 19)) {
+               rc_force_mail_prompts = atoi(&buf[19]);
+               }
+
+           if (!struncmp(buf,"ansi_color=", 11)) {
+               if (!strncasecmp(&buf[11], "on", 2)) 
+                       rc_ansi_color = 1;
+               if (!strncasecmp(&buf[11], "auto", 4)) 
+                       rc_ansi_color = 2;      /* autodetect */
+               if (!strncasecmp(&buf[11], "user", 4)) 
+                       rc_ansi_color = 3;      /* user config */
+               }
+
            if (!struncmp(buf,"username=",9))
                strcpy(rc_username,&buf[9]);
 
@@ -387,9 +464,10 @@ void load_command_set(void) {
                        ++a;
                        }
 
-               cptr->next = cmdlist;
-               cmdlist = cptr;
-
+               cptr->next = NULL;
+               if (cmdlist == NULL) cmdlist = cptr;
+               else lastcmd->next = cptr;
+               lastcmd = cptr;
                }
            }
        fclose(ccfile);
@@ -509,8 +587,15 @@ int getcmd(char *argbuf)
        int ch;
        int a;
        int got;
+       int this_lazy_cmd;
        struct citcmd *cptr;
 
+       /* Switch color support on or off if we're in user mode */
+       if (rc_ansi_color == 3) {
+               if (userflags & US_COLOR) enable_color = 1;
+               else enable_color = 0;
+               }
+
        /* if we're running in idiot mode, display a cute little menu */
        IFNEXPERT formout("mainmenu");
 
@@ -527,12 +612,35 @@ int getcmd(char *argbuf)
                ch = inkey();
                ok_to_interrupt = 0;
 
+               /* Handle the backspace key, but only if there's something
+                * to backspace over...
+                */
                if ( (ch == 8) && (cmdpos > 0) ) {
                        back(cmdspaces[cmdpos-1] + 1);
                        cmdbuf[cmdpos] = 0;
                        --cmdpos;
                        }
 
+               /* Spacebar invokes "lazy traversal" commands */
+               if ( (ch == 32) && (cmdpos == 0) ) {
+                       this_lazy_cmd = next_lazy_cmd;
+                       if (this_lazy_cmd == 13) next_lazy_cmd = 5;
+                       if (this_lazy_cmd == 5) next_lazy_cmd = 13;
+                       for (cptr = cmdlist; cptr != NULL; cptr = cptr->next) {
+                               if (cptr->c_cmdnum == this_lazy_cmd) {
+                                       for (a=0; a<5; ++a)
+                                           if (cptr->c_keys[a][0] != 0)
+                                               printf("%s ", cmd_expand(
+                                                       cptr->c_keys[a], 0));
+                                       printf("\n");
+                                       return(this_lazy_cmd);
+                                       }
+                               }
+                       printf("\n");
+                       return(this_lazy_cmd);
+                       }
+
+               /* Otherwise, process the command */
                cmdbuf[cmdpos] = tolower(ch);
 
                for (cptr = cmdlist; cptr != NULL; cptr = cptr->next) {
@@ -550,13 +658,28 @@ int getcmd(char *argbuf)
 
                for (cptr = cmdlist; cptr != NULL; cptr = cptr->next) {
                        if (cmdmatch(cmdbuf,cptr,5)) {
+                               /* We've found our command. */
                                if (requires_string(cptr,cmdpos)) {
                                        getline(argbuf,32);
                                        }
                                else {
                                        printf("\n");
                                        }
+
+                               /* If this command is one that changes rooms,
+                                * then the next lazy-command (space bar)
+                                * should be "read new" instead of "goto"
+                                */
+                               if ((cptr->c_cmdnum==5)
+                                       ||(cptr->c_cmdnum==6)
+                                       ||(cptr->c_cmdnum==47)
+                                       ||(cptr->c_cmdnum==52)
+                                       ||(cptr->c_cmdnum==16)
+                                       ||(cptr->c_cmdnum==20))
+                                               next_lazy_cmd = 13;
+
                                return(cptr->c_cmdnum);
+
                                }
                        }
 
@@ -605,13 +728,18 @@ void sttybbs(int cmd)             /* SysV version of sttybbs() */
          {
        struct termios live;
        static struct termios saved_settings;
+       static int last_cmd = 0;
+
+       if (cmd == SB_LAST)
+               cmd = last_cmd;
+       else
+               last_cmd = cmd;
 
        if ( (cmd == 0) || (cmd == 1) ) {
                tcgetattr(0,&live);
                live.c_iflag=ISTRIP|IXON|IXANY;
                live.c_oflag=OPOST|ONLCR;
-               live.c_lflag=NOFLSH;
-               if (cmd==1) live.c_lflag=ISIG|NOFLSH;
+               live.c_lflag=ISIG|NOFLSH;
 
                if (cmd==SB_YES_INTR) {
                        live.c_cc[VINTR]=NEXT_KEY;
@@ -794,22 +922,18 @@ FMTEND:   printf("\n");
  */
 void color(int colornum)
 {
-
-#ifdef ANSI_COLOR
        if (enable_color) {
-               fflush(stdout);
-               printf("%c[3%dm%c[1m", 27, colornum, 27);
+               printf("\033[3%dm", colornum);
                fflush(stdout);
                }
-#endif
        }
 
-void cls(void) {
-#ifdef ANSI_COLOR
-       fflush(stdout);
-       printf("%c[2J%c[H", 27, 27);
-       fflush(stdout);
-#endif
+void cls(int colornum) {
+       if (enable_color) {
+               printf("\033[4%dm\033[2J\033[H", colornum);
+               printf("\033[0m"); /* change to 1 for bold colours */
+               fflush(stdout);
+               }
        }
 
 
@@ -817,45 +941,55 @@ void cls(void) {
  * Detect whether ANSI color is available (answerback)
  */
 void send_ansi_detect(void) {
-#ifdef ANSI_COLOR
-       printf("%c[c", 27);
-       fflush(stdout);
-       time(&AnsiDetect);
-#endif
+       if (rc_ansi_color == 2) {
+               printf("\033[c");
+               fflush(stdout);
+               time(&AnsiDetect);
+               }
        }
 
 void look_for_ansi(void) {
-#ifdef ANSI_COLOR
         fd_set rfds;
         struct timeval tv;
        char abuf[512];
        time_t now;
        int a;
 
-       strcpy(abuf, "");
+       if (rc_ansi_color == 0) {
+               enable_color = 0;
+               }
+       else if (rc_ansi_color == 1) {
+               enable_color = 1;
+               }
+       else if (rc_ansi_color == 2) {
 
-       time(&now);
-       if ( (now - AnsiDetect) < 2 ) sleep(1);
+               /* otherwise, do the auto-detect */
 
-       do {
-               FD_ZERO(&rfds);
-               FD_SET(0,&rfds);
-               tv.tv_sec = 0;
-               tv.tv_usec = 1;
-
-               select(1, &rfds, NULL, NULL, &tv);
-               if (FD_ISSET(0, &rfds)) {
-                       abuf[strlen(abuf)+1] = 0;
-                       read(0, &abuf[strlen(abuf)], 1);
-                       }
+               strcpy(abuf, "");
 
-               } while (FD_ISSET(0, &rfds));
+               time(&now);
+               if ( (now - AnsiDetect) < 2 ) sleep(1);
 
-       for (a=0; a<strlen(abuf); ++a) {
-               if ( (abuf[a] == 27) && (abuf[a+1] == '[')
-                  && (abuf[a+2] == '?') ) {
-                       enable_color = 1;
+               do {
+                       FD_ZERO(&rfds);
+                       FD_SET(0,&rfds);
+                       tv.tv_sec = 0;
+                       tv.tv_usec = 1;
+
+                       select(1, &rfds, NULL, NULL, &tv);
+                       if (FD_ISSET(0, &rfds)) {
+                               abuf[strlen(abuf)+1] = 0;
+                               read(0, &abuf[strlen(abuf)], 1);
+                               }
+       
+                       } while (FD_ISSET(0, &rfds));
+       
+               for (a=0; a<strlen(abuf); ++a) {
+                       if ( (abuf[a] == 27) && (abuf[a+1] == '[')
+                       && (abuf[a+2] == '?') ) {
+                               enable_color = 1;
+                               }
                        }
                }
-#endif
+
        }