From 0a4125a7c136a09a5422ababa2263c2b05f44a76 Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Thu, 3 Apr 2003 10:05:44 +0000 Subject: fprintf -> fputs, etc... --- vchat-commands.c | 60 ++++++++++++----- vchat-config.h | 2 + vchat-ui.c | 195 ++++++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 203 insertions(+), 54 deletions(-) diff --git a/vchat-commands.c b/vchat-commands.c index c81bf36..6380a44 100755 --- a/vchat-commands.c +++ b/vchat-commands.c @@ -2,7 +2,7 @@ * vchat-client - alpha version * vchat-commands.c - handling of client commands * - * Copyright (C) 2001 Andreas Kotes + * Copyright (C) 2003 Dirk Engling * * This program is free software. It can be redistributed and/or modified, * provided that this copyright notice is kept intact. This program is @@ -38,6 +38,7 @@ COMMAND_HELP, COMMAND_KEYS, COMMAND_QUIT, COMMAND_USER, +COMMAND_LOG, COMMAND_FLT, COMMAND_PM, COMMAND_ACTION, @@ -57,6 +58,7 @@ static void command_clflt ( unsigned char *tail); static void command_rmflt ( unsigned char *tail); void command_version ( unsigned char *tail); static void command_none ( unsigned char *line); +static void command_log ( unsigned char *tail); static void output_default ( unsigned char *tail); @@ -74,6 +76,7 @@ commandtable[] = { { COMMAND_QUIT, "QUIT", 4, command_quit, SHORT_HELPTEXT_QUIT, LONG_HELPTEXT_QUIT }, { COMMAND_USER, "USER", 4, command_user, SHORT_HELPTEXT_USER, LONG_HELPTEXT_USER }, { COMMAND_FLT, "FLT", 3, command_flt, NULL, LONG_HELPTEXT_FLT }, +{ COMMAND_LOG, "LOG", 3, command_log, NULL, NULL }, { COMMAND_PM, "MSG", 3, command_pm, SHORT_HELPTEXT_MSG, LONG_HELPTEXT_MSG }, { COMMAND_ACTION, "ME", 2, command_action, SHORT_HELPTEXT_ME, LONG_HELPTEXT_ME }, { COMMAND_PMSHORT, "M", 1, command_pm, NULL, SHORT_HELPTEXT_MSG }, @@ -89,18 +92,26 @@ translatecommand( unsigned char **cmd) int cut = 0; int maxcut = 0; + /* We do only want to allow Command abbrevation to + the next newline, so that /VRES won't expand to /V RES */ + while( (*cmd)[maxcut] && ((*cmd)[maxcut] != 0x20) && ((*cmd)[maxcut] != '\n')) maxcut++; if( maxcut ) maxcut--; + /* Repeatedly scan command table for command, with growing abbrevation cut off */ do { + /* Looks ugly, needs rewrite for better understanding */ for( result = 0; (result != COMMAND_NONE) && (strncasecmp(*cmd, commandtable[result].name, commandtable[result].len - ((commandtable[result].len - maxcut - cut > 0) ? cut : 0))); result++); } while ((cut < commandtable[0].len) && (commandtable[result].number == COMMAND_NONE) && (++cut)); - + + /* Just leave the tail... */ (*cmd) += commandtable[result].len; + + /* ... whose start may be affected by abbrevation */ if( commandtable[result].number != COMMAND_NONE ) (*cmd) -= cut; @@ -122,10 +133,8 @@ doaction( unsigned char *tail ) snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_TXPUBACTION), nick, tail); writechan (tmpstr); } else { - /* missing action */ - snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_BGTXPUBACTION)); - writechan (tmpstr); + msgout( " You do nothing. " ); } } @@ -159,10 +168,8 @@ privatemessagetx ( unsigned char *tail ) { ul_msgto(tail); } else { - - /* missing nick or message body inform user */ - snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_BGPRIVMSG)); - writepriv (tmpstr); + /* Bump user to fill in missing parts */ + msgout( *tail ? " Won't send empty message. ":" Recipient missing. " ); } } @@ -200,7 +207,6 @@ handleline (unsigned char *line) } break; default: - /* generic server command, send to server, show to user */ snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_COMMAND), line); networkoutput (line); @@ -237,17 +243,17 @@ static void command_user( unsigned char *tail) { while( *tail == ' ') tail++; - if( strlen(tail) >= 3) { + if( *tail ) { unsigned char * out = ul_matchuser( tail); if( *out ) { snprintf( tmpstr, TMPSTRSIZE, getformatstr(FS_USMATCH), tail, out); } else { - snprintf( tmpstr, TMPSTRSIZE, getformatstr(FS_ERR), "No user matched that substring"); + snprintf( tmpstr, TMPSTRSIZE, getformatstr(FS_ERR), " No user matched that regex. "); } } else { - snprintf( tmpstr, TMPSTRSIZE, getformatstr(FS_ERR), "Specify at least 3 characters to match users"); + snprintf( tmpstr, TMPSTRSIZE, getformatstr(FS_ERR), " Which user? "); } - writechan( tmpstr ); + msgout( tmpstr ); } /* handle a "/msg " request */ @@ -296,10 +302,8 @@ command_help (unsigned char *line) { /* handle an unknown command */ static void command_none( unsigned char *line) { - flushout( ); snprintf(tmpstr, TMPSTRSIZE, " Unknown client command: %s ", line); - writeout(tmpstr); - showout( ); + msgout(tmpstr); } /* handle a "/flt " request */ @@ -366,3 +370,25 @@ command_version( unsigned char *tail) writeout (vchat_cm_version); showout(); } + +/* Undocumented feature */ +void +command_log ( unsigned char *tail) +{ + /* log to file */ + FILE *logfile = NULL; + while( *tail == ' ' ) + tail++; + if( (logfile = fopen( tail, "w")) ) { + if( *tail == '_' ) { + writelog_i(logfile); + } else { + writelog(logfile); + } + fclose( logfile ); + msgout(" Log written. "); + } else { + snprintf(tmpstr, TMPSTRSIZE, " Can't open file: %s ", tail); + msgout(tmpstr); + } +} diff --git a/vchat-config.h b/vchat-config.h index d7e7305..85db619 100755 --- a/vchat-config.h +++ b/vchat-config.h @@ -38,6 +38,7 @@ static volatile configoption configoptions[] = { {CF_CERTFILE, CO_STR, "certfile", "~/.vchat/cert", NULL, NULL }, {CF_KEYFILE, CO_STR, "keyfile", "~/.vchat/key", NULL, NULL }, {CF_FORMFILE, CO_STR, "formatfile", "~/.vchat/formats", NULL, NULL }, + {CF_LOGFILE, CO_STR, "logfile", "~/.vchat/log", NULL, NULL, }, {CF_USESSL, CO_INT, "usessl", (char *) 1, (char *)-1, (unsigned char **)&usessl }, {CF_USECERT, CO_INT, "usecert", (char *) 1, (char *)-1, NULL }, {CF_USETIME, CO_INT, "usetime", (char *) 1, (char *)-1, (unsigned char **)&usetime }, @@ -48,6 +49,7 @@ static volatile configoption configoptions[] = { {CF_SCROLLBACK, CO_INT, "scrollback", (char *) 8192, (char *)-1, NULL }, {CF_SCROLLBPRIVT,CO_INT, "privscrollt",(char *) 0, (char *)-1, NULL }, {CF_SCROLLBACKT, CO_INT, "scrolltime", (char *) 86400, (char *)-1, NULL }, + {CF_KEEPLOG, CO_INT, "keeplog", (char *) 0, (char *)-1, NULL }, {CF_NIL, CO_NIL, NULL, NULL, NULL, NULL }, }; diff --git a/vchat-ui.c b/vchat-ui.c index 526727f..eba6ab0 100755 --- a/vchat-ui.c +++ b/vchat-ui.c @@ -46,6 +46,9 @@ static WINDOW *topic = NULL; static WINDOW *channel = NULL; static WINDOW *private = NULL; static WINDOW *output = NULL; + +static FILE *vchat_logfile = NULL; + /* our screen dimensions */ static int screensx = 0; static int screensy = 0; @@ -75,6 +78,7 @@ struct sb_entry { struct sb_data { struct sb_entry *entries; + struct sb_entry *last; int count; int scroll; }; @@ -242,7 +246,10 @@ sb_add (struct sb_data *sb, unsigned char *line, time_t when) { newone->what = strdup(line); newone->link = sb->entries; newone->stamp= 0xffff; - if( sb->entries ) sb->entries->link = (struct sb_entry*)((unsigned long)sb->entries->link ^ (unsigned long)newone); + if( sb->entries ) + sb->entries->link = (struct sb_entry*)((unsigned long)sb->entries->link ^ (unsigned long)newone); + else + sb->last = newone; sb->entries = newone; } return newone; @@ -258,8 +265,10 @@ void flushout ( ) void hideout( ) { - outputshown = 0; - resize(0); + if( outputshown ) { + outputshown = 0; + resize(0); + } } void showout (void) @@ -284,6 +293,12 @@ int writechan (unsigned char *str) { time_t now = time(NULL); tmp = sb_add(sb_pub,str,now); + if( getintoption( CF_KEEPLOG ) && vchat_logfile ) { + char date[16]; + strftime( date, sizeof(date), "%Y%m%d%H%M%S", localtime(&now)); + fprintf( vchat_logfile, "%s0%s\n", date, str); + } + if ( (sb_pub->scroll == sb_pub->count) && ((filtertype == 0) || ( testfilter(tmp)))) { i = writescr(channel, tmp); wnoutrefresh(channel); @@ -293,42 +308,56 @@ int writechan (unsigned char *str) { } int writecf (formtstr id,unsigned char *str) { - struct sb_entry *tmp; - int i = 0; - time_t now = time(NULL); - snprintf(tmpstr,TMPSTRSIZE,getformatstr(id),str); - tmp = sb_add(sb_pub,tmpstr,now); - if ( (sb_pub->scroll == sb_pub->count) && - ((filtertype == 0) || ( testfilter(tmp)))) { - i = writescr(channel, tmp); - wnoutrefresh(channel); - } - consoleline(NULL); - return i; + struct sb_entry *tmp; + int i = 0; + time_t now = time(NULL); + snprintf(tmpstr,TMPSTRSIZE,getformatstr(id),str); + tmp = sb_add(sb_pub,tmpstr,now); + + if( getintoption( CF_KEEPLOG ) && vchat_logfile ) { + char date[16]; + strftime( date, sizeof(date), "%Y%m%d%H%M%S", localtime(&now)); + fprintf( vchat_logfile, "%s0%s\n", date, str); + } + + if ( (sb_pub->scroll == sb_pub->count) && + ((filtertype == 0) || ( testfilter(tmp)))) { + i = writescr(channel, tmp); + wnoutrefresh(channel); + } + consoleline(NULL); + return i; } int writepriv (unsigned char *str) { - int i = 0; - time_t now = time (NULL); - struct sb_entry *tmp; - - if (private) { - tmp = sb_add(sb_priv,str,now); - if ( (sb_priv->scroll == sb_priv->scroll) && - ((filtertype == 0) || ( testfilter(tmp)))) { - i = writescr(private, tmp); - } - if( privwinhidden ) { - privheight_desired = privwinhidden; - privwinhidden = 0; - resize(0); - } - wnoutrefresh(private); - topicline(NULL); - } else - i = writechan( str ); - - return i; + int i = 0; + if (private) { + + time_t now = time (NULL); + struct sb_entry *tmp; + tmp = sb_add(sb_priv,str,now); + + if( getintoption( CF_KEEPLOG ) && vchat_logfile ) { + char date[16]; + strftime( date, sizeof(date), "%Y%m%d%H%M%S", localtime(&now)); + fprintf( vchat_logfile, "%s1%s\n", date, str); + } + + if ( (sb_priv->scroll == sb_priv->scroll) && + ((filtertype == 0) || ( testfilter(tmp)))) { + i = writescr(private, tmp); + } + if( privwinhidden ) { + privheight_desired = privwinhidden; + privwinhidden = 0; + resize(0); + } + wnoutrefresh(private); + topicline(NULL); + } else + i = writechan( str ); + + return i; } /* Get #if 's out of code */ @@ -467,6 +496,87 @@ writescr ( WINDOW *win, struct sb_entry *entry ) { return charcount; } +static void +writelog_processentry ( FILE *file, struct sb_entry* entry ) +{ + char *outtmp; + int outoff = 0; + if( usetime ) { + outtmp = tmpstr+64; + strftime(outtmp,64,getformatstr(FS_TIME),localtime(&entry->when)); + while(*outtmp) + if( *outtmp > 1 ) + tmpstr[outoff++] = *(outtmp++); + else + if( *(++outtmp)) + outtmp++; + } + + outtmp = entry->what; + while(*outtmp) + while(*outtmp && ( outoff < TMPSTRSIZE-1) ) { + if( *outtmp > 1 ) + tmpstr[outoff++] = *(outtmp++); + else + if( *(++outtmp)) + outtmp++; + tmpstr[outoff]=0; outoff = 0; + fputs( tmpstr, file ); + } + + fputc( '\n', file); +} + +void +writelog_i ( FILE *file) +{ + if( !private ) { + writelog( file); + } else { + struct sb_entry *now1= sb_pub->last, *prev1 = NULL, *tmp; + struct sb_entry *now2= sb_priv->last, *prev2 = NULL; + fputs( "Interleaved messages:\n\n", file); + while( now1 || now2 ) { + int process; + if( now1 && now2 ) { + process = ( now1->when < now2->when ) ? 1 : 2; + } else { + process = now1 ? 1 : 2; + } + + if( process == 1 ) { + writelog_processentry( file, now1 ); + tmp = now1; now1 = (struct sb_entry*)((unsigned long)now1->link ^ (unsigned long)prev1); prev1 = tmp; + } else { + writelog_processentry( file, now2 ); + tmp = now2; now2 = (struct sb_entry*)((unsigned long)now2->link ^ (unsigned long)prev2); prev2 = tmp; + } + } + } +} + +void +writelog ( FILE *file ) +{ + if( sb_pub->last ) { + struct sb_entry *now = sb_pub->last, *prev = NULL, *tmp; + fputs( "Public messages:\n\n", file); + while( now ) { + writelog_processentry( file, now ); + tmp = now; now = (struct sb_entry*)((unsigned long)now->link ^ (unsigned long)prev); prev = tmp; + } + putc( '\n', file ); + } + if( private && sb_priv->last ) { + struct sb_entry *now = sb_priv->last, *prev = NULL, *tmp; + fputs( "Private messages:\n\n", file); + while( now ) { + writelog_processentry( file, now ); + tmp = now; now = (struct sb_entry*)((unsigned long)now->link ^ (unsigned long)prev); prev = tmp; + } + } +} + static void resize_output ( ) { @@ -1068,6 +1178,15 @@ initui (void) writeout (vchat_us_version); writeout (vchat_cm_version); showout( ); + + if( getintoption( CF_KEEPLOG ) ) { + unsigned char *logfile = getstroption( CF_LOGFILE ); + if( logfile && *logfile ) { + if( *logfile == '~' ) + logfile = tilde_expand( logfile ); + vchat_logfile = fopen( logfile, "a+" ); + } + } } /* render colorized line to window */ @@ -1169,6 +1288,8 @@ exitui (void) rl_callback_handler_remove (); endwin (); ui_init = 0; + if( vchat_logfile ) + fclose( vchat_logfile ); } } @@ -1414,7 +1535,7 @@ addfilter( char colour, unsigned char *regex ) { /* couldn't compile regex ... print error, return */ free( newflt ); - snprintf( tmpstr, TMPSTRSIZE, " %s ", regex); + snprintf( tmpstr, TMPSTRSIZE, " %s ", regex); writeout( " Bad regular expression: "); writeout( tmpstr ); showout( ); -- cgit v1.2.3