summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorerdgeist <>2003-04-03 10:05:44 +0000
committererdgeist <>2003-04-03 10:05:44 +0000
commit0a4125a7c136a09a5422ababa2263c2b05f44a76 (patch)
tree8a1d7d5dfd159c5513bdccc3c735ac252194f549
parent693ce0ee3faeda6333f8eee98adbf942a8a2f44c (diff)
fprintf -> fputs, etc...
-rwxr-xr-xvchat-commands.c60
-rwxr-xr-xvchat-config.h2
-rwxr-xr-xvchat-ui.c195
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 @@
2 * vchat-client - alpha version 2 * vchat-client - alpha version
3 * vchat-commands.c - handling of client commands 3 * vchat-commands.c - handling of client commands
4 * 4 *
5 * Copyright (C) 2001 Andreas Kotes <count@flatline.de> 5 * Copyright (C) 2003 Dirk Engling <erdgeist@erdgeist.org>
6 * 6 *
7 * This program is free software. It can be redistributed and/or modified, 7 * This program is free software. It can be redistributed and/or modified,
8 * provided that this copyright notice is kept intact. This program is 8 * provided that this copyright notice is kept intact. This program is
@@ -38,6 +38,7 @@ COMMAND_HELP,
38COMMAND_KEYS, 38COMMAND_KEYS,
39COMMAND_QUIT, 39COMMAND_QUIT,
40COMMAND_USER, 40COMMAND_USER,
41COMMAND_LOG,
41COMMAND_FLT, 42COMMAND_FLT,
42COMMAND_PM, 43COMMAND_PM,
43COMMAND_ACTION, 44COMMAND_ACTION,
@@ -57,6 +58,7 @@ static void command_clflt ( unsigned char *tail);
57static void command_rmflt ( unsigned char *tail); 58static void command_rmflt ( unsigned char *tail);
58 void command_version ( unsigned char *tail); 59 void command_version ( unsigned char *tail);
59static void command_none ( unsigned char *line); 60static void command_none ( unsigned char *line);
61static void command_log ( unsigned char *tail);
60 62
61static void output_default ( unsigned char *tail); 63static void output_default ( unsigned char *tail);
62 64
@@ -74,6 +76,7 @@ commandtable[] = {
74{ COMMAND_QUIT, "QUIT", 4, command_quit, SHORT_HELPTEXT_QUIT, LONG_HELPTEXT_QUIT }, 76{ COMMAND_QUIT, "QUIT", 4, command_quit, SHORT_HELPTEXT_QUIT, LONG_HELPTEXT_QUIT },
75{ COMMAND_USER, "USER", 4, command_user, SHORT_HELPTEXT_USER, LONG_HELPTEXT_USER }, 77{ COMMAND_USER, "USER", 4, command_user, SHORT_HELPTEXT_USER, LONG_HELPTEXT_USER },
76{ COMMAND_FLT, "FLT", 3, command_flt, NULL, LONG_HELPTEXT_FLT }, 78{ COMMAND_FLT, "FLT", 3, command_flt, NULL, LONG_HELPTEXT_FLT },
79{ COMMAND_LOG, "LOG", 3, command_log, NULL, NULL },
77{ COMMAND_PM, "MSG", 3, command_pm, SHORT_HELPTEXT_MSG, LONG_HELPTEXT_MSG }, 80{ COMMAND_PM, "MSG", 3, command_pm, SHORT_HELPTEXT_MSG, LONG_HELPTEXT_MSG },
78{ COMMAND_ACTION, "ME", 2, command_action, SHORT_HELPTEXT_ME, LONG_HELPTEXT_ME }, 81{ COMMAND_ACTION, "ME", 2, command_action, SHORT_HELPTEXT_ME, LONG_HELPTEXT_ME },
79{ COMMAND_PMSHORT, "M", 1, command_pm, NULL, SHORT_HELPTEXT_MSG }, 82{ COMMAND_PMSHORT, "M", 1, command_pm, NULL, SHORT_HELPTEXT_MSG },
@@ -89,18 +92,26 @@ translatecommand( unsigned char **cmd)
89 int cut = 0; 92 int cut = 0;
90 int maxcut = 0; 93 int maxcut = 0;
91 94
95 /* We do only want to allow Command abbrevation to
96 the next newline, so that /VRES won't expand to /V RES */
97
92 while( (*cmd)[maxcut] && ((*cmd)[maxcut] != 0x20) && ((*cmd)[maxcut] != '\n')) maxcut++; 98 while( (*cmd)[maxcut] && ((*cmd)[maxcut] != 0x20) && ((*cmd)[maxcut] != '\n')) maxcut++;
93 if( maxcut ) maxcut--; 99 if( maxcut ) maxcut--;
94 100
101 /* Repeatedly scan command table for command, with growing abbrevation cut off */
95 do { 102 do {
103 /* Looks ugly, needs rewrite for better understanding */
96 for( result = 0; 104 for( result = 0;
97 (result != COMMAND_NONE) && 105 (result != COMMAND_NONE) &&
98 (strncasecmp(*cmd, commandtable[result].name, commandtable[result].len - 106 (strncasecmp(*cmd, commandtable[result].name, commandtable[result].len -
99 ((commandtable[result].len - maxcut - cut > 0) ? cut : 0))); 107 ((commandtable[result].len - maxcut - cut > 0) ? cut : 0)));
100 result++); 108 result++);
101 } while ((cut < commandtable[0].len) && (commandtable[result].number == COMMAND_NONE) && (++cut)); 109 } while ((cut < commandtable[0].len) && (commandtable[result].number == COMMAND_NONE) && (++cut));
102 110
111 /* Just leave the tail... */
103 (*cmd) += commandtable[result].len; 112 (*cmd) += commandtable[result].len;
113
114 /* ... whose start may be affected by abbrevation */
104 if( commandtable[result].number != COMMAND_NONE ) 115 if( commandtable[result].number != COMMAND_NONE )
105 (*cmd) -= cut; 116 (*cmd) -= cut;
106 117
@@ -122,10 +133,8 @@ doaction( unsigned char *tail )
122 snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_TXPUBACTION), nick, tail); 133 snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_TXPUBACTION), nick, tail);
123 writechan (tmpstr); 134 writechan (tmpstr);
124 } else { 135 } else {
125
126 /* missing action */ 136 /* missing action */
127 snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_BGTXPUBACTION)); 137 msgout( " You do nothing. " );
128 writechan (tmpstr);
129 } 138 }
130} 139}
131 140
@@ -159,10 +168,8 @@ privatemessagetx ( unsigned char *tail ) {
159 ul_msgto(tail); 168 ul_msgto(tail);
160 169
161 } else { 170 } else {
162 171 /* Bump user to fill in missing parts */
163 /* missing nick or message body inform user */ 172 msgout( *tail ? " Won't send empty message. ":" Recipient missing. " );
164 snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_BGPRIVMSG));
165 writepriv (tmpstr);
166 } 173 }
167} 174}
168 175
@@ -200,7 +207,6 @@ handleline (unsigned char *line)
200 } 207 }
201 break; 208 break;
202 default: 209 default:
203
204 /* generic server command, send to server, show to user */ 210 /* generic server command, send to server, show to user */
205 snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_COMMAND), line); 211 snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_COMMAND), line);
206 networkoutput (line); 212 networkoutput (line);
@@ -237,17 +243,17 @@ static void
237command_user( unsigned char *tail) 243command_user( unsigned char *tail)
238{ 244{
239 while( *tail == ' ') tail++; 245 while( *tail == ' ') tail++;
240 if( strlen(tail) >= 3) { 246 if( *tail ) {
241 unsigned char * out = ul_matchuser( tail); 247 unsigned char * out = ul_matchuser( tail);
242 if( *out ) { 248 if( *out ) {
243 snprintf( tmpstr, TMPSTRSIZE, getformatstr(FS_USMATCH), tail, out); 249 snprintf( tmpstr, TMPSTRSIZE, getformatstr(FS_USMATCH), tail, out);
244 } else { 250 } else {
245 snprintf( tmpstr, TMPSTRSIZE, getformatstr(FS_ERR), "No user matched that substring"); 251 snprintf( tmpstr, TMPSTRSIZE, getformatstr(FS_ERR), " No user matched that regex. ");
246 } 252 }
247 } else { 253 } else {
248 snprintf( tmpstr, TMPSTRSIZE, getformatstr(FS_ERR), "Specify at least 3 characters to match users"); 254 snprintf( tmpstr, TMPSTRSIZE, getformatstr(FS_ERR), " Which user? ");
249 } 255 }
250 writechan( tmpstr ); 256 msgout( tmpstr );
251} 257}
252 258
253/* handle a "/msg " request */ 259/* handle a "/msg " request */
@@ -296,10 +302,8 @@ command_help (unsigned char *line) {
296/* handle an unknown command */ 302/* handle an unknown command */
297static void 303static void
298command_none( unsigned char *line) { 304command_none( unsigned char *line) {
299 flushout( );
300 snprintf(tmpstr, TMPSTRSIZE, " Unknown client command: %s ", line); 305 snprintf(tmpstr, TMPSTRSIZE, " Unknown client command: %s ", line);
301 writeout(tmpstr); 306 msgout(tmpstr);
302 showout( );
303} 307}
304 308
305/* handle a "/flt " request */ 309/* handle a "/flt " request */
@@ -366,3 +370,25 @@ command_version( unsigned char *tail)
366 writeout (vchat_cm_version); 370 writeout (vchat_cm_version);
367 showout(); 371 showout();
368} 372}
373
374/* Undocumented feature */
375void
376command_log ( unsigned char *tail)
377{
378 /* log to file */
379 FILE *logfile = NULL;
380 while( *tail == ' ' )
381 tail++;
382 if( (logfile = fopen( tail, "w")) ) {
383 if( *tail == '_' ) {
384 writelog_i(logfile);
385 } else {
386 writelog(logfile);
387 }
388 fclose( logfile );
389 msgout(" Log written. ");
390 } else {
391 snprintf(tmpstr, TMPSTRSIZE, " Can't open file: %s ", tail);
392 msgout(tmpstr);
393 }
394}
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[] = {
38 {CF_CERTFILE, CO_STR, "certfile", "~/.vchat/cert", NULL, NULL }, 38 {CF_CERTFILE, CO_STR, "certfile", "~/.vchat/cert", NULL, NULL },
39 {CF_KEYFILE, CO_STR, "keyfile", "~/.vchat/key", NULL, NULL }, 39 {CF_KEYFILE, CO_STR, "keyfile", "~/.vchat/key", NULL, NULL },
40 {CF_FORMFILE, CO_STR, "formatfile", "~/.vchat/formats", NULL, NULL }, 40 {CF_FORMFILE, CO_STR, "formatfile", "~/.vchat/formats", NULL, NULL },
41 {CF_LOGFILE, CO_STR, "logfile", "~/.vchat/log", NULL, NULL, },
41 {CF_USESSL, CO_INT, "usessl", (char *) 1, (char *)-1, (unsigned char **)&usessl }, 42 {CF_USESSL, CO_INT, "usessl", (char *) 1, (char *)-1, (unsigned char **)&usessl },
42 {CF_USECERT, CO_INT, "usecert", (char *) 1, (char *)-1, NULL }, 43 {CF_USECERT, CO_INT, "usecert", (char *) 1, (char *)-1, NULL },
43 {CF_USETIME, CO_INT, "usetime", (char *) 1, (char *)-1, (unsigned char **)&usetime }, 44 {CF_USETIME, CO_INT, "usetime", (char *) 1, (char *)-1, (unsigned char **)&usetime },
@@ -48,6 +49,7 @@ static volatile configoption configoptions[] = {
48 {CF_SCROLLBACK, CO_INT, "scrollback", (char *) 8192, (char *)-1, NULL }, 49 {CF_SCROLLBACK, CO_INT, "scrollback", (char *) 8192, (char *)-1, NULL },
49 {CF_SCROLLBPRIVT,CO_INT, "privscrollt",(char *) 0, (char *)-1, NULL }, 50 {CF_SCROLLBPRIVT,CO_INT, "privscrollt",(char *) 0, (char *)-1, NULL },
50 {CF_SCROLLBACKT, CO_INT, "scrolltime", (char *) 86400, (char *)-1, NULL }, 51 {CF_SCROLLBACKT, CO_INT, "scrolltime", (char *) 86400, (char *)-1, NULL },
52 {CF_KEEPLOG, CO_INT, "keeplog", (char *) 0, (char *)-1, NULL },
51 {CF_NIL, CO_NIL, NULL, NULL, NULL, NULL }, 53 {CF_NIL, CO_NIL, NULL, NULL, NULL, NULL },
52}; 54};
53 55
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;
46static WINDOW *channel = NULL; 46static WINDOW *channel = NULL;
47static WINDOW *private = NULL; 47static WINDOW *private = NULL;
48static WINDOW *output = NULL; 48static WINDOW *output = NULL;
49
50static FILE *vchat_logfile = NULL;
51
49/* our screen dimensions */ 52/* our screen dimensions */
50static int screensx = 0; 53static int screensx = 0;
51static int screensy = 0; 54static int screensy = 0;
@@ -75,6 +78,7 @@ struct sb_entry {
75 78
76struct sb_data { 79struct sb_data {
77 struct sb_entry *entries; 80 struct sb_entry *entries;
81 struct sb_entry *last;
78 int count; 82 int count;
79 int scroll; 83 int scroll;
80}; 84};
@@ -242,7 +246,10 @@ sb_add (struct sb_data *sb, unsigned char *line, time_t when) {
242 newone->what = strdup(line); 246 newone->what = strdup(line);
243 newone->link = sb->entries; 247 newone->link = sb->entries;
244 newone->stamp= 0xffff; 248 newone->stamp= 0xffff;
245 if( sb->entries ) sb->entries->link = (struct sb_entry*)((unsigned long)sb->entries->link ^ (unsigned long)newone); 249 if( sb->entries )
250 sb->entries->link = (struct sb_entry*)((unsigned long)sb->entries->link ^ (unsigned long)newone);
251 else
252 sb->last = newone;
246 sb->entries = newone; 253 sb->entries = newone;
247 } 254 }
248 return newone; 255 return newone;
@@ -258,8 +265,10 @@ void flushout ( )
258 265
259void hideout( ) 266void hideout( )
260{ 267{
261 outputshown = 0; 268 if( outputshown ) {
262 resize(0); 269 outputshown = 0;
270 resize(0);
271 }
263} 272}
264 273
265void showout (void) 274void showout (void)
@@ -284,6 +293,12 @@ int writechan (unsigned char *str) {
284 time_t now = time(NULL); 293 time_t now = time(NULL);
285 tmp = sb_add(sb_pub,str,now); 294 tmp = sb_add(sb_pub,str,now);
286 295
296 if( getintoption( CF_KEEPLOG ) && vchat_logfile ) {
297 char date[16];
298 strftime( date, sizeof(date), "%Y%m%d%H%M%S", localtime(&now));
299 fprintf( vchat_logfile, "%s0%s\n", date, str);
300 }
301
287 if ( (sb_pub->scroll == sb_pub->count) && ((filtertype == 0) || ( testfilter(tmp)))) { 302 if ( (sb_pub->scroll == sb_pub->count) && ((filtertype == 0) || ( testfilter(tmp)))) {
288 i = writescr(channel, tmp); 303 i = writescr(channel, tmp);
289 wnoutrefresh(channel); 304 wnoutrefresh(channel);
@@ -293,42 +308,56 @@ int writechan (unsigned char *str) {
293} 308}
294 309
295int writecf (formtstr id,unsigned char *str) { 310int writecf (formtstr id,unsigned char *str) {
296 struct sb_entry *tmp; 311 struct sb_entry *tmp;
297 int i = 0; 312 int i = 0;
298 time_t now = time(NULL); 313 time_t now = time(NULL);
299 snprintf(tmpstr,TMPSTRSIZE,getformatstr(id),str); 314 snprintf(tmpstr,TMPSTRSIZE,getformatstr(id),str);
300 tmp = sb_add(sb_pub,tmpstr,now); 315 tmp = sb_add(sb_pub,tmpstr,now);
301 if ( (sb_pub->scroll == sb_pub->count) && 316
302 ((filtertype == 0) || ( testfilter(tmp)))) { 317 if( getintoption( CF_KEEPLOG ) && vchat_logfile ) {
303 i = writescr(channel, tmp); 318 char date[16];
304 wnoutrefresh(channel); 319 strftime( date, sizeof(date), "%Y%m%d%H%M%S", localtime(&now));
305 } 320 fprintf( vchat_logfile, "%s0%s\n", date, str);
306 consoleline(NULL); 321 }
307 return i; 322
323 if ( (sb_pub->scroll == sb_pub->count) &&
324 ((filtertype == 0) || ( testfilter(tmp)))) {
325 i = writescr(channel, tmp);
326 wnoutrefresh(channel);
327 }
328 consoleline(NULL);
329 return i;
308} 330}
309 331
310int writepriv (unsigned char *str) { 332int writepriv (unsigned char *str) {
311 int i = 0; 333 int i = 0;
312 time_t now = time (NULL); 334 if (private) {
313 struct sb_entry *tmp; 335
314 336 time_t now = time (NULL);
315 if (private) { 337 struct sb_entry *tmp;
316 tmp = sb_add(sb_priv,str,now); 338 tmp = sb_add(sb_priv,str,now);
317 if ( (sb_priv->scroll == sb_priv->scroll) && 339
318 ((filtertype == 0) || ( testfilter(tmp)))) { 340 if( getintoption( CF_KEEPLOG ) && vchat_logfile ) {
319 i = writescr(private, tmp); 341 char date[16];
320 } 342 strftime( date, sizeof(date), "%Y%m%d%H%M%S", localtime(&now));
321 if( privwinhidden ) { 343 fprintf( vchat_logfile, "%s1%s\n", date, str);
322 privheight_desired = privwinhidden; 344 }
323 privwinhidden = 0; 345
324 resize(0); 346 if ( (sb_priv->scroll == sb_priv->scroll) &&
325 } 347 ((filtertype == 0) || ( testfilter(tmp)))) {
326 wnoutrefresh(private); 348 i = writescr(private, tmp);
327 topicline(NULL); 349 }
328 } else 350 if( privwinhidden ) {
329 i = writechan( str ); 351 privheight_desired = privwinhidden;
330 352 privwinhidden = 0;
331 return i; 353 resize(0);
354 }
355 wnoutrefresh(private);
356 topicline(NULL);
357 } else
358 i = writechan( str );
359
360 return i;
332} 361}
333 362
334/* Get #if 's out of code */ 363/* Get #if 's out of code */
@@ -468,6 +497,87 @@ writescr ( WINDOW *win, struct sb_entry *entry ) {
468} 497}
469 498
470static void 499static void
500writelog_processentry ( FILE *file, struct sb_entry* entry )
501{
502 char *outtmp;
503 int outoff = 0;
504 if( usetime ) {
505 outtmp = tmpstr+64;
506 strftime(outtmp,64,getformatstr(FS_TIME),localtime(&entry->when));
507 while(*outtmp)
508 if( *outtmp > 1 )
509 tmpstr[outoff++] = *(outtmp++);
510 else
511 if( *(++outtmp))
512 outtmp++;
513 }
514
515 outtmp = entry->what;
516 while(*outtmp)
517 while(*outtmp && ( outoff < TMPSTRSIZE-1) ) {
518 if( *outtmp > 1 )
519 tmpstr[outoff++] = *(outtmp++);
520 else
521 if( *(++outtmp))
522 outtmp++;
523 tmpstr[outoff]=0; outoff = 0;
524 fputs( tmpstr, file );
525 }
526
527 fputc( '\n', file);
528}
529
530void
531writelog_i ( FILE *file)
532{
533 if( !private ) {
534 writelog( file);
535 } else {
536 struct sb_entry *now1= sb_pub->last, *prev1 = NULL, *tmp;
537 struct sb_entry *now2= sb_priv->last, *prev2 = NULL;
538 fputs( "Interleaved messages:\n\n", file);
539 while( now1 || now2 ) {
540 int process;
541 if( now1 && now2 ) {
542 process = ( now1->when < now2->when ) ? 1 : 2;
543 } else {
544 process = now1 ? 1 : 2;
545 }
546
547 if( process == 1 ) {
548 writelog_processentry( file, now1 );
549 tmp = now1; now1 = (struct sb_entry*)((unsigned long)now1->link ^ (unsigned long)prev1); prev1 = tmp;
550 } else {
551 writelog_processentry( file, now2 );
552 tmp = now2; now2 = (struct sb_entry*)((unsigned long)now2->link ^ (unsigned long)prev2); prev2 = tmp;
553 }
554 }
555 }
556}
557
558void
559writelog ( FILE *file )
560{
561 if( sb_pub->last ) {
562 struct sb_entry *now = sb_pub->last, *prev = NULL, *tmp;
563 fputs( "Public messages:\n\n", file);
564 while( now ) {
565 writelog_processentry( file, now );
566 tmp = now; now = (struct sb_entry*)((unsigned long)now->link ^ (unsigned long)prev); prev = tmp;
567 }
568 putc( '\n', file );
569 }
570 if( private && sb_priv->last ) {
571 struct sb_entry *now = sb_priv->last, *prev = NULL, *tmp;
572 fputs( "Private messages:\n\n", file);
573 while( now ) {
574 writelog_processentry( file, now );
575 tmp = now; now = (struct sb_entry*)((unsigned long)now->link ^ (unsigned long)prev); prev = tmp;
576 }
577 }
578}
579
580static void
471resize_output ( ) 581resize_output ( )
472{ 582{
473 int outputwidth = (outputwidth_desired + 7 > screensx) ? screensx - 7 : outputwidth_desired; 583 int outputwidth = (outputwidth_desired + 7 > screensx) ? screensx - 7 : outputwidth_desired;
@@ -1068,6 +1178,15 @@ initui (void)
1068 writeout (vchat_us_version); 1178 writeout (vchat_us_version);
1069 writeout (vchat_cm_version); 1179 writeout (vchat_cm_version);
1070 showout( ); 1180 showout( );
1181
1182 if( getintoption( CF_KEEPLOG ) ) {
1183 unsigned char *logfile = getstroption( CF_LOGFILE );
1184 if( logfile && *logfile ) {
1185 if( *logfile == '~' )
1186 logfile = tilde_expand( logfile );
1187 vchat_logfile = fopen( logfile, "a+" );
1188 }
1189 }
1071} 1190}
1072 1191
1073/* render colorized line to window */ 1192/* render colorized line to window */
@@ -1169,6 +1288,8 @@ exitui (void)
1169 rl_callback_handler_remove (); 1288 rl_callback_handler_remove ();
1170 endwin (); 1289 endwin ();
1171 ui_init = 0; 1290 ui_init = 0;
1291 if( vchat_logfile )
1292 fclose( vchat_logfile );
1172 } 1293 }
1173} 1294}
1174 1295
@@ -1414,7 +1535,7 @@ addfilter( char colour, unsigned char *regex ) {
1414 /* couldn't compile regex ... print error, return */ 1535 /* couldn't compile regex ... print error, return */
1415 free( newflt ); 1536 free( newflt );
1416 1537
1417 snprintf( tmpstr, TMPSTRSIZE, " %s ", regex); 1538 snprintf( tmpstr, TMPSTRSIZE, " %s ", regex);
1418 writeout( " Bad regular expression: "); 1539 writeout( " Bad regular expression: ");
1419 writeout( tmpstr ); 1540 writeout( tmpstr );
1420 showout( ); 1541 showout( );