#include <errno.h>
#include <stdarg.h>
#include "citadel.h"
+#include "citadel_ipc.h"
#include "commands.h"
#include "messages.h"
#include "citadel_decls.h"
int rc_ansi_color;
int num_urls = 0;
int rc_prompt_control = 0;
+time_t rc_idle_threshold = (time_t)900;
char urls[MAXURLS][SIZ];
char rc_url_cmd[SIZ];
+char rc_gotmail_cmd[SIZ];
char *gl_string;
int next_lazy_cmd = 5;
int lines_printed = 0; /* line count for paginator */
extern int screenwidth, screenheight;
extern int termn8;
+extern CtdlIPC *ipc_for_signal_handlers; /* KLUDGE cover your eyes */
struct citcmd *cmdlist = NULL;
/*
* 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.
*/
-int checkpagin(int lp, int pagin, int height)
+int checkpagin(int lp, unsigned int pagin, unsigned int height)
{
int thekey;
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);
/* Otherwise, start spewing... */
va_start(arg_ptr, format);
- vsprintf(buf, format, arg_ptr);
+ vsnprintf(buf, sizeof(buf), format, arg_ptr);
va_end(arg_ptr);
for (i=0; i<strlen(buf); ++i) {
int flags = 0;
char sender[64];
char node[64];
+ char *listing = NULL;
+ int r; /* IPC result code */
if (express_msgs == 0)
return;
}
while (express_msgs != 0) {
- serv_puts("GEXP");
- serv_gets(buf);
- if (buf[0] != '1')
+ r = CtdlIPCGetInstantMessage(ipc_for_signal_handlers, &listing, buf);
+ if (r / 100 != 1)
return;
- express_msgs = extract_int(&buf[4], 0);
- timestamp = extract_long(&buf[4], 1);
- flags = extract_int(&buf[4], 2);
- extract(sender, &buf[4], 3);
- extract(node, &buf[4], 4);
+ express_msgs = extract_int(buf, 0);
+ timestamp = extract_long(buf, 1);
+ flags = extract_int(buf, 2);
+ extract(sender, buf, 3);
+ extract(node, buf, 4);
strcpy(last_paged, sender);
stamp = localtime(×tamp);
fprintf(outpipe, " from %s", sender);
if (strncmp(serv_info.serv_nodename, node, 32))
fprintf(outpipe, " @%s", node);
- fprintf(outpipe, ":\n");
- while (serv_gets(buf), strcmp(buf, "000")) {
- fprintf(outpipe, "%s\n", buf);
- }
+ fprintf(outpipe, ":\n%s\n", listing);
pclose(outpipe);
if (express_msgs == 0)
return;
scr_printf(":\n");
lines_printed++;
- fmout(screenwidth, NULL, NULL, 1, screenheight, -1, 0);
+ fmout(screenwidth, NULL, listing, NULL, 1, screenheight, -1, 0);
+ free(listing);
+
+ /* when running in curses mode, the scroll bar in most
+ xterm-style programs becomes useless, so it makes sense to
+ pause after a screenful of pages if the user has been idle
+ for a while. However, this is annoying to some of the users
+ who aren't in curses mode and tend to leave their clients
+ idle. keepalives become disabled, resulting in getting booted
+ when coming back to the idle session. but they probably have
+ a working scrollback in their terminal, so disable it in this
+ case:
+ */
+ if (!is_curses_enabled())
+ lines_printed = 0;
}
scr_printf("\n---\n");
color(BRIGHT_WHITE);
static time_t idlet = 0;
static void really_do_keepalive(void) {
- char buf[1024];
+ int r; /* IPC response code */
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);
- if (buf[3] == '*') {
- express_msgs = 1;
+ r = CtdlIPCNoop(ipc_for_signal_handlers);
+ if (express_msgs > 0) {
if (ok_to_interrupt == 1) {
scr_printf("\r%64s\r", "");
print_express();
}
}
}
+
+ /* 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) ) {
+ CtdlIPC_putline(ipc_for_signal_handlers, "QNOP");
+ }
}
/* threaded nonblocking keepalive stuff starts here. I'm going for a simple
int inkey(void)
{ /* get a character from the keyboard, with */
int a; /* the watchdog timer in effect if necessary */
-#ifndef HAVE_CURSES_H /* avoid compiler warning */
fd_set rfds;
struct timeval tv;
-#endif
time_t start_time;
scr_flush();
time(&start_time);
do {
-#ifdef HAVE_CURSES_H /* IO, maybe you wanna move this to screen.c */
- a = scr_blockread();
-#else
/* This loop waits for keyboard input. If the keepalive
* timer expires, it sends a keepalive to the server if
* necessary and then waits again.
*/
do {
+ scr_set_windowsize();
do_keepalive();
+ scr_set_windowsize();
FD_ZERO(&rfds);
FD_SET(0, &rfds);
/* At this point, there's input, so fetch it.
* (There's a hole in the bucket...)
*/
- a = scr_getc();
-#endif
-
-
+ a = scr_getc(SCR_NOBLOCK);
if (a == 127)
a = 8;
if (a > 126)
a = 0;
if (a == 13)
a = 10;
- if (((a != 4) && (a != 10) && (a != 8) && (a != NEXT_KEY) && (a != STOP_KEY))
+ if (((a != 23) && (a != 4) && (a != 10) && (a != 8) && (a != NEXT_KEY) && (a != STOP_KEY))
&& ((a < 32) || (a > 126)))
a = 0;
+
+#if defined(HAVE_CURSES_H) || defined(HAVE_NCURSES_H)
+ if (a == ERR)
+ a = 0;
+#endif
+
} while (a == 0);
return (a);
}
async_ka_start();
GLA:a = inkey();
a = (a & 127);
- if ((a == 8) && (strlen(string) == 0))
+ if ((a == 8 || a == 23) && (strlen(string) == 0))
goto GLA;
if ((a != 10) && (a != 8) && (strlen(string) == lim))
goto GLA;
if ((a == 8) && (string[0] != 0)) {
string[strlen(string) - 1] = 0;
- scr_putc(8);
- scr_putc(32);
- scr_putc(8);
+ scr_putc(8); scr_putc(32); scr_putc(8);
+ goto GLA;
+ }
+ if ((a == 23) && (string[0] != 0)) {
+ do {
+ string[strlen(string) - 1] = 0;
+ scr_putc(8); scr_putc(32); scr_putc(8);
+ } while (strlen(string) && string[strlen(string) - 1] != ' ');
goto GLA;
}
if ((a == 10)) {
*/
void strprompt(char *prompt, char *str, int len)
{
+ int i;
char buf[128];
+
print_express();
color(DIM_WHITE);
scr_printf("%s ", prompt);
color(DIM_MAGENTA);
scr_printf("[");
color(BRIGHT_MAGENTA);
- scr_printf("%s", str);
+
+ if (len >= 0) {
+ scr_printf("%s", str);
+ }
+ else {
+ for (i=0; i<strlen(str); ++i) {
+ scr_printf("*");
+ }
+ }
+
color(DIM_MAGENTA);
scr_printf("]");
color(DIM_WHITE);
color(DIM_WHITE);
scr_printf("%s ", prompt);
color(DIM_MAGENTA);
- scr_printf(" [");
+ scr_printf("[");
color(BRIGHT_MAGENTA);
scr_printf("%s", (prev_val ? "Yes" : "No"));
color(DIM_MAGENTA);
rc_force_mail_prompts = 0;
rc_ansi_color = 0;
strcpy(rc_url_cmd, "");
+ strcpy(rc_gotmail_cmd, "");
+#ifdef HAVE_OPENSSL
rc_encrypt = RC_DEFAULT;
+#endif
#ifdef HAVE_CURSES_H
rc_screen = RC_DEFAULT;
#endif
}
if (ccfile == NULL) {
perror("commands: cannot open citadel.rc");
- logoff(errno);
+ logoff(NULL, 3);
}
while (fgets(buf, sizeof buf, ccfile) != NULL) {
while ((strlen(buf) > 0) ? (isspace(buf[strlen(buf) - 1])) : 0)
buf[strlen(buf) - 1] = 0;
if (!strncasecmp(buf, "encrypt=", 8)) {
- if (!strcasecmp(&buf[8], "yes"))
+ if (!strcasecmp(&buf[8], "yes")) {
+#ifdef HAVE_OPENSSL
rc_encrypt = RC_YES;
- else if (!strcasecmp(&buf[8], "no"))
+#else
+ fprintf(stderr, "citadel.rc requires encryption support but citadel is not compiled with OpenSSL");
+ logoff(NULL, 3);
+#endif
+ }
+#ifdef HAVE_OPENSSL
+ else if (!strcasecmp(&buf[8], "no")) {
rc_encrypt = RC_NO;
- else if (!strcasecmp(&buf[8], "default"))
+ }
+ else if (!strcasecmp(&buf[8], "default")) {
rc_encrypt = RC_DEFAULT;
+ }
+#endif
}
#ifdef HAVE_CURSES_H
if (!strncasecmp(buf, "allow_attachments=", 18)) {
rc_allow_attachments = atoi(&buf[18]);
}
+ if (!strncasecmp(buf, "idle_threshold=", 15)) {
+ rc_idle_threshold = atoi(&buf[15]);
+ }
if (!strncasecmp(buf, "remember_passwords=", 19)) {
rc_remember_passwords = atoi(&buf[19]);
}
if (!strncasecmp(buf, "urlcmd=", 7))
strcpy(rc_url_cmd, &buf[7]);
+ if (!strncasecmp(buf, "gotmailcmd=", 11))
+ strcpy(rc_gotmail_cmd, &buf[11]);
+
if (!strncasecmp(buf, "alternate_semantics=", 20)) {
if (!strncasecmp(&buf[11], "yes", 3))
rc_alt_semantics = 1;
* This function returns an integer command number. If the command prompts
* for a string then it is placed in the supplied buffer.
*/
-int getcmd(char *argbuf)
+int getcmd(CtdlIPC *ipc, char *argbuf)
{
char cmdbuf[5];
int cmdspaces[5];
enable_color = 0;
}
/* if we're running in idiot mode, display a cute little menu */
- IFNEXPERT formout("mainmenu");
+ IFNEXPERT formout(ipc, "mainmenu");
- print_express(); /* print express messages if there are any */
+ print_express();
strcpy(argbuf, "");
cmdpos = 0;
for (a = 0; a < 5; ++a)
live.c_oflag = OPOST | ONLCR;
live.c_lflag = ISIG | NOFLSH;
- live.c_cc[VINTR] = (-1);
- live.c_cc[VQUIT] = (-1);
+ live.c_cc[VINTR] = 0;
+ live.c_cc[VQUIT] = 0;
#ifdef hpux
live.c_cc[VMIN] = 0;
/*
* display_help() - help file viewer
*/
-void display_help(char *name)
+void display_help(CtdlIPC *ipc, char *name)
{
- formout(name);
+ formout(ipc, name);
}
*/
int fmout(
int width, /* screen width to use */
- FILE *fpin, /* file to read from, or NULL to read from server */
+ FILE *fpin, /* file to read from, or NULL to format given text */
+ char *text, /* Text to be formatted (when fpin is NULL) */
FILE *fpout, /* File to write to, or NULL to write to screen */
char pagin, /* nonzero if we should use the paginator */
int height, /* screen height to use */
int starting_lp,/* starting value for lines_printed, -1 for global */
- char subst) /* nonzero if we should use hypertext mode */
+ int subst) /* nonzero if we should use hypertext mode */
{
- int a, b, c, d, old;
+ int a, b, c, old;
int real = (-1);
char aaa[140];
char buffer[512];
+ char *e;
int eof_flag = 0;
num_urls = 0; /* Start with a clean slate of embedded URL's */
old = 255;
strcpy(buffer, "");
c = 1; /* c is the current pos */
+ e = text; /* e is pointer to current pos */
FMTA: while ((eof_flag == 0) && (strlen(buffer) < 126)) {
if (fpin != NULL) { /* read from file */
buffer[strlen(buffer) + 1] = 0;
buffer[strlen(buffer)] = a;
}
- } else { /* read from server */
- d = strlen(buffer);
- serv_gets(&buffer[d]);
- while ((!isspace(buffer[d])) && (isspace(buffer[strlen(buffer) - 1])))
- buffer[strlen(buffer) - 1] = 0;
- if (!strcmp(&buffer[d], "000")) {
- buffer[d] = 0;
+ } else { /* read from text */
+ if (!*e) {
eof_flag = 1;
while (isspace(buffer[strlen(buffer) - 1]))
buffer[strlen(buffer) - 1] = 0;
+ buffer[strlen(buffer) + 1] = 0;
+ buffer[strlen(buffer)] = 10;
+ }
+ if (eof_flag == 0) {
+ a = *e++;
+ buffer[strlen(buffer) + 1] = 0;
+ buffer[strlen(buffer)] = a;
}
- d = strlen(buffer);
- buffer[d] = 10;
- buffer[d + 1] = 0;
}
}
goto FMTA;
/* keypress caught; drain the server */
-OOPS: do {
- serv_gets(aaa);
- } while (strcmp(aaa, "000"));
+OOPS: /* do {
+ CtdlIPC_getline(ipc, aaa);
+ } while (strcmp(aaa, "000")); */
FMTEND:
if (fpout) {
#endif
/* When switching to dim white, actually output an 'original
* pair' sequence -- this looks better on black-on-white
- * terminals.
+ * terminals. - Changed to ORIGINAL_PAIR as this actually
+ * wound up looking horrible on black-on-white terminals, not
+ * to mention transparent terminals.
*/
- if (colornum == DIM_WHITE)
+ if (colornum == ORIGINAL_PAIR)
printf("\033[39;49m");
else
printf("\033[3%d;40m", (colornum & 7));