From fb01cc858cda6e86a72fc791aaec492a5b335411 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Fri, 24 May 2002 19:58:13 +0000 Subject: [PATCH] * Fixed the "idle timeout during paginator prompt" bug by reintroducting the concept of a "half keepalive" and sending them during paginator prompts. --- citadel/ChangeLog | 5 +- citadel/citadel.h | 7 ++- citadel/citserver.c | 8 ++- citadel/commands.c | 16 +++++- citadel/ipcdef.h | 3 +- citadel/routines.c | 102 ++++++++++++++++++------------------ citadel/serv_info.c | 3 ++ citadel/techdoc/session.txt | 14 +++++ 8 files changed, 101 insertions(+), 57 deletions(-) diff --git a/citadel/ChangeLog b/citadel/ChangeLog index 4a2514f8a..c5cd6e090 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,8 @@ $Log$ + Revision 591.31 2002/05/24 19:58:13 ajc + * Fixed the "idle timeout during paginator prompt" bug by reintroducting the + concept of a "half keepalive" and sending them during paginator prompts. + Revision 591.30 2002/05/23 03:33:21 ajc * Added a GTSN (GeT list of SeeN messages) command @@ -3675,4 +3679,3 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant Fri Jul 10 1998 Art Cancro * Initial CVS import - diff --git a/citadel/citadel.h b/citadel/citadel.h index e0119bfff..841be3860 100644 --- a/citadel/citadel.h +++ b/citadel/citadel.h @@ -265,8 +265,11 @@ struct floor { #define RC_DEFAULT 2 /* setting depends on user config */ /* keepalives */ -#define KA_NO 0 /* no keepalives */ -#define KA_YES 1 /* full keepalives */ +enum { + KA_NO, /* no keepalives */ + KA_YES, /* full keepalives */ + KA_HALF /* half keepalives */ +}; /* for <;G>oto and <;S>kip commands */ #define GF_GOTO 0 /* <;G>oto floor mode */ diff --git a/citadel/citserver.c b/citadel/citserver.c index 78a0e7e79..5aea06c2b 100644 --- a/citadel/citserver.c +++ b/citadel/citserver.c @@ -330,6 +330,7 @@ void cmd_info(void) { cprintf("1\n"); /* 1 = yes, this system supports floors */ cprintf("1\n"); /* 1 = we support the extended paging options */ cprintf("%s\n", CC->cs_nonce); + cprintf("1\n"); /* 1 = yes, this system supports the QNOP command */ cprintf("000\n"); } @@ -891,9 +892,10 @@ void do_command_loop(void) { /* * Let other clients see the last command we executed, and - * update the idle time, but not NOOP, PEXP, or GEXP. + * update the idle time, but not NOOP, QNOP, PEXP, or GEXP. */ if ( (strncasecmp(cmdbuf, "NOOP", 4)) + && (strncasecmp(cmdbuf, "QNOP", 4)) && (strncasecmp(cmdbuf, "PEXP", 4)) && (strncasecmp(cmdbuf, "GEXP", 4)) ) { strcpy(CC->lastcmdname, " "); @@ -912,6 +914,10 @@ void do_command_loop(void) { if (!strncasecmp(cmdbuf,"NOOP",4)) { cprintf("%d%cok\n",CIT_OK,CtdlCheckExpress()); } + + else if (!strncasecmp(cmdbuf,"QNOP",4)) { + /* do nothing, this command returns no response */ + } else if (!strncasecmp(cmdbuf,"QUIT",4)) { cprintf("%d Goodbye.\n",CIT_OK); diff --git a/citadel/commands.c b/citadel/commands.c index e101b9422..09c2bec8c 100644 --- a/citadel/commands.c +++ b/citadel/commands.c @@ -135,7 +135,7 @@ char was_a_key_pressed(void) { /* * Check to see if we need to pause at the end of a screen. - * If we do, we have to disable server keepalives during the pause because + * If we do, we have to switch to half keepalives during the pause because * we are probably in the middle of a server operation and the NOOP command * would confuse everything. */ @@ -154,7 +154,7 @@ int checkpagin(int lp, int pagin, int height) if (!pagin) return(0); if (lp>=(height-1)) { - set_keepalives(KA_NO); + set_keepalives(KA_HALF); hit_any_key(); set_keepalives(KA_YES); return(0); @@ -348,6 +348,10 @@ static void really_do_keepalive(void) { char buf[1024]; time(&idlet); + + /* If full keepalives are enabled, send a NOOP to the server and + * wait for a response. + */ if (keepalives_enabled == KA_YES) { serv_puts("NOOP"); serv_gets(buf); @@ -362,6 +366,14 @@ static void really_do_keepalive(void) { } } } + + /* If half keepalives are enabled, send a QNOP to the server (if the + * server supports it) and then do nothing. + */ + if ( (keepalives_enabled == KA_HALF) + && (serv_info.serv_supports_qnop > 0) ) { + serv_puts("QNOP"); + } } /* threaded nonblocking keepalive stuff starts here. I'm going for a simple diff --git a/citadel/ipcdef.h b/citadel/ipcdef.h index 5acea43a3..ba54081d0 100644 --- a/citadel/ipcdef.h +++ b/citadel/ipcdef.h @@ -39,7 +39,8 @@ struct CtdlServInfo { char serv_moreprompt[256]; int serv_ok_floors; int serv_paging_level; - }; + int serv_supports_qnop; +}; #define QR_PERMANENT 1 /* Room does not purge */ #define QR_INUSE 2 /* Set if in use, clear if avail */ diff --git a/citadel/routines.c b/citadel/routines.c index 9d75ee47b..2dfcf11f6 100644 --- a/citadel/routines.c +++ b/citadel/routines.c @@ -64,13 +64,15 @@ extern char rc_floor_mode; extern int rc_ansi_color; extern int rc_prompt_control; -void back(int spaces) /* Destructive backspace */ - { +/* Destructive backspace */ +void back(int spaces) { int a; - for (a=1; a<=spaces; ++a) { - scr_putc(8); scr_putc(32); scr_putc(8); - } + for (a=0; a126) string[a]=32; - } + } /* Remove leading and trailing blanks */ while(string[0]<33) strcpy(string,&string[1]); @@ -346,8 +347,8 @@ void strproc(char *string) if ((string[a]==32)&&(string[a+1]==32)) { strcpy(&string[a],&string[a+1]); a=0; - } } + } /* remove characters which would interfere with the network */ for (a=0; aut_line, 24); #if defined(HAVE_UT_TYPE) || defined(HAVE_GETUTXLINE) - } + } else goto fail; #endif #endif /* HAVE_UTMP_H */ - } +} /* * miscellaneous server commands (testing, etc.) @@ -493,21 +494,21 @@ void misc_server_cmd(char *cmd) { serv_gets(buf); scr_printf("%s\n",buf); if (buf[0]=='1') { - set_keepalives(KA_NO); + set_keepalives(KA_HALF); while (serv_gets(buf), strcmp(buf,"000")) { scr_printf("%s\n",buf); - } + } set_keepalives(KA_YES); return; - } + } if (buf[0]=='4') { do { newprompt("> ",buf,255); serv_puts(buf); - } while(strcmp(buf,"000")); + } while(strcmp(buf,"000")); return; - } } +} /* @@ -527,11 +528,11 @@ int file_checksum(char *filename) */ while (ch=getc(fp), ch>=0) { cksum = (cksum + ch); - } + } fclose(fp); return(cksum); - } +} /* * nuke a directory and its contents @@ -545,13 +546,14 @@ int nukedir(char *dirname) dp = opendir(dirname); if (dp == NULL) { return(errno); - } + } while (d = readdir(dp), d != NULL) { - snprintf(filename, sizeof filename, "%s/%s", dirname, d->d_name); + snprintf(filename, sizeof filename, "%s/%s", + dirname, d->d_name); unlink(filename); - } + } closedir(dp); return(rmdir(dirname)); - } +} diff --git a/citadel/serv_info.c b/citadel/serv_info.c index 02915751c..675a69b81 100644 --- a/citadel/serv_info.c +++ b/citadel/serv_info.c @@ -61,6 +61,9 @@ void CtdlInternalGetServInfo(struct CtdlServInfo *infobuf) { case 10: infobuf->serv_ok_floors = atoi(buf); break; case 11: infobuf->serv_paging_level = atoi(buf); + break; + case 13: infobuf->serv_supports_qnop = atoi(buf); + break; } ++a; } diff --git a/citadel/techdoc/session.txt b/citadel/techdoc/session.txt index b9f4151db..947618326 100644 --- a/citadel/techdoc/session.txt +++ b/citadel/techdoc/session.txt @@ -552,6 +552,7 @@ parts of the listing: Line 13 - The "nonce" for this session, for support of APOP-style authentication. If this field is present, clients may authenticate in this manner. + Line 14 - Set to nonzero if this server supports the QNOP command. *** NOTE! *** The "server type" code is intended to promote global compatibility in a scenario in which developers have added proprietary @@ -1900,6 +1901,19 @@ views.txt for more information on views. The sole parameter for this command is the type of view requested. VIEW returns OK on success or ERROR on failure. + QNOP (Quiet No OPeration) + + This command does nothing, similar to the NOOP command. However, unlike the +NOOP command, it returns *absolutely no response* at all. The client has no +way of knowing that the command executed. It is intended for sending +"keepalives" in situations where a full NOOP would cause the client protocol +to get out of sync. + + Naturally, sending this command to a server that doesn't support it is an +easy way to mess things up. Therefore, client software should first check +the output of an INFO command to ensure that the server supports quiet noops. + + ASYN (ASYNchronous message support) Negotiate the use of asynchronous, or unsolicited, protocol messages. The -- 2.39.2