diff options
Diffstat (limited to 'vchat-commands.c')
| -rwxr-xr-x | vchat-commands.c | 368 |
1 files changed, 368 insertions, 0 deletions
diff --git a/vchat-commands.c b/vchat-commands.c new file mode 100755 index 0000000..c81bf36 --- /dev/null +++ b/vchat-commands.c | |||
| @@ -0,0 +1,368 @@ | |||
| 1 | /* | ||
| 2 | * vchat-client - alpha version | ||
| 3 | * vchat-commands.c - handling of client commands | ||
| 4 | * | ||
| 5 | * Copyright (C) 2001 Andreas Kotes <count@flatline.de> | ||
| 6 | * | ||
| 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 | ||
| 9 | * distributed in the hope that it will be useful, but without any warranty; | ||
| 10 | * without even the implied warranty of merchantability or fitness for a | ||
| 11 | * particular purpose. In no event shall the copyright holder be liable for | ||
| 12 | * any direct, indirect, incidental or special damages arising in any way out | ||
| 13 | * of the use of this software. | ||
| 14 | * | ||
| 15 | */ | ||
| 16 | |||
| 17 | /* general includes */ | ||
| 18 | #include <unistd.h> | ||
| 19 | #include <errno.h> | ||
| 20 | #include <stdio.h> | ||
| 21 | #include <string.h> | ||
| 22 | |||
| 23 | /* local includes */ | ||
| 24 | #include "vchat.h" | ||
| 25 | #include "vchat-help.h" | ||
| 26 | |||
| 27 | /* version of this module */ | ||
| 28 | unsigned char *vchat_cm_version = "$Id$"; | ||
| 29 | |||
| 30 | /* our "/command " table */ | ||
| 31 | enum { | ||
| 32 | COMMAND_VERSION, | ||
| 33 | COMMAND_FILTERS, | ||
| 34 | COMMAND_LSFLT, | ||
| 35 | COMMAND_RMFLT, | ||
| 36 | COMMAND_CLFLT, | ||
| 37 | COMMAND_HELP, | ||
| 38 | COMMAND_KEYS, | ||
| 39 | COMMAND_QUIT, | ||
| 40 | COMMAND_USER, | ||
| 41 | COMMAND_FLT, | ||
| 42 | COMMAND_PM, | ||
| 43 | COMMAND_ACTION, | ||
| 44 | COMMAND_PMSHORT, | ||
| 45 | COMMAND_PLAIN, | ||
| 46 | COMMAND_NONE | ||
| 47 | }; | ||
| 48 | |||
| 49 | static void command_quit ( unsigned char *tail); | ||
| 50 | static void command_user ( unsigned char *tail); | ||
| 51 | static void command_pm ( unsigned char *tail); | ||
| 52 | static void command_action ( unsigned char *tail); | ||
| 53 | static void command_help ( unsigned char *tail); | ||
| 54 | static void command_flt ( unsigned char *tail); | ||
| 55 | static void command_lsflt ( unsigned char *tail); | ||
| 56 | static void command_clflt ( unsigned char *tail); | ||
| 57 | static void command_rmflt ( unsigned char *tail); | ||
| 58 | void command_version ( unsigned char *tail); | ||
| 59 | static void command_none ( unsigned char *line); | ||
| 60 | |||
| 61 | static void output_default ( unsigned char *tail); | ||
| 62 | |||
| 63 | /* commandentry defined in vchat.h */ | ||
| 64 | |||
| 65 | static commandentry | ||
| 66 | commandtable[] = { | ||
| 67 | { COMMAND_VERSION, "VERSION", 7, command_version, SHORT_HELPTEXT_VERSION, LONG_HELPTEXT_VERSION }, | ||
| 68 | { COMMAND_LSFLT, "LSFLT", 5, command_lsflt, NULL, LONG_HELPTEXT_LSFLT }, | ||
| 69 | { COMMAND_RMFLT, "RMFLT", 5, command_rmflt, NULL, LONG_HELPTEXT_RMFLT }, | ||
| 70 | { COMMAND_CLFLT, "CLFLT", 5, command_clflt, NULL, LONG_HELPTEXT_CLFLT }, | ||
| 71 | { COMMAND_HELP, "HELP", 4, command_help, SHORT_HELPTEXT_HELP, LONG_HELPTEXT_HELP }, | ||
| 72 | { COMMAND_FILTERS, "FILTERS", 7, command_help, SHORT_HELPTEXT_FILTERS, LONG_HELPTEXT_FILTERS }, | ||
| 73 | { COMMAND_KEYS, "KEYS", 4, command_help, SHORT_HELPTEXT_KEYS, LONG_HELPTEXT_KEYS }, | ||
| 74 | { 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 }, | ||
| 76 | { COMMAND_FLT, "FLT", 3, command_flt, NULL, LONG_HELPTEXT_FLT }, | ||
| 77 | { 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 }, | ||
| 79 | { COMMAND_PMSHORT, "M", 1, command_pm, NULL, SHORT_HELPTEXT_MSG }, | ||
| 80 | { COMMAND_PLAIN, "/", 1, output_default, NULL, NULL }, | ||
| 81 | { COMMAND_NONE, "", 0, command_none, NULL, NULL } | ||
| 82 | }; | ||
| 83 | |||
| 84 | /* parse "/command" */ | ||
| 85 | static int | ||
| 86 | translatecommand( unsigned char **cmd) | ||
| 87 | { | ||
| 88 | int result; | ||
| 89 | int cut = 0; | ||
| 90 | int maxcut = 0; | ||
| 91 | |||
| 92 | while( (*cmd)[maxcut] && ((*cmd)[maxcut] != 0x20) && ((*cmd)[maxcut] != '\n')) maxcut++; | ||
| 93 | if( maxcut ) maxcut--; | ||
| 94 | |||
| 95 | do { | ||
| 96 | for( result = 0; | ||
| 97 | (result != COMMAND_NONE) && | ||
| 98 | (strncasecmp(*cmd, commandtable[result].name, commandtable[result].len - | ||
| 99 | ((commandtable[result].len - maxcut - cut > 0) ? cut : 0))); | ||
| 100 | result++); | ||
| 101 | } while ((cut < commandtable[0].len) && (commandtable[result].number == COMMAND_NONE) && (++cut)); | ||
| 102 | |||
| 103 | (*cmd) += commandtable[result].len; | ||
| 104 | if( commandtable[result].number != COMMAND_NONE ) | ||
| 105 | (*cmd) -= cut; | ||
| 106 | |||
| 107 | return result; | ||
| 108 | } | ||
| 109 | |||
| 110 | /* handle action */ | ||
| 111 | static void | ||
| 112 | doaction( unsigned char *tail ) | ||
| 113 | { | ||
| 114 | while( *tail == ' ' ) tail++; | ||
| 115 | |||
| 116 | if( *tail ) { | ||
| 117 | /* send users message to server */ | ||
| 118 | snprintf (tmpstr, TMPSTRSIZE, ".a %s", tail); | ||
| 119 | networkoutput (tmpstr); | ||
| 120 | |||
| 121 | /* show action in channel window */ | ||
| 122 | snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_TXPUBACTION), nick, tail); | ||
| 123 | writechan (tmpstr); | ||
| 124 | } else { | ||
| 125 | |||
| 126 | /* missing action */ | ||
| 127 | snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_BGTXPUBACTION)); | ||
| 128 | writechan (tmpstr); | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 132 | /* handle private message outgoing */ | ||
| 133 | static void | ||
| 134 | privatemessagetx ( unsigned char *tail ) { | ||
| 135 | unsigned char *mesg; | ||
| 136 | |||
| 137 | /* find nick */ | ||
| 138 | while( *tail==' ') tail++; | ||
| 139 | |||
| 140 | /* find message */ | ||
| 141 | mesg = tail; | ||
| 142 | while ( *mesg && *mesg!=' ') mesg++; | ||
| 143 | |||
| 144 | /* check for nick && message */ | ||
| 145 | if(*tail && *mesg) { | ||
| 146 | |||
| 147 | /* terminate nick, move to rel start */ | ||
| 148 | *mesg++ = '\0'; | ||
| 149 | |||
| 150 | /* form message and send to server */ | ||
| 151 | snprintf (tmpstr, TMPSTRSIZE, ".m %s %s", tail, mesg); | ||
| 152 | networkoutput (tmpstr); | ||
| 153 | |||
| 154 | /* show message in private window */ | ||
| 155 | snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_TXPRIVMSG), tail, mesg); | ||
| 156 | writepriv (tmpstr); | ||
| 157 | |||
| 158 | /* note we messaged someone */ | ||
| 159 | ul_msgto(tail); | ||
| 160 | |||
| 161 | } else { | ||
| 162 | |||
| 163 | /* missing nick or message body inform user */ | ||
| 164 | snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_BGPRIVMSG)); | ||
| 165 | writepriv (tmpstr); | ||
| 166 | } | ||
| 167 | } | ||
| 168 | |||
| 169 | /* handle line entered by user */ | ||
| 170 | void | ||
| 171 | handleline (unsigned char *line) | ||
| 172 | { | ||
| 173 | #ifdef DEBUG | ||
| 174 | /* debugging? log users input! */ | ||
| 175 | fprintf (stderr, "=| %s\n", line); | ||
| 176 | #endif | ||
| 177 | |||
| 178 | switch ( line[0] ) | ||
| 179 | { | ||
| 180 | case '.': | ||
| 181 | switch ( line[1] ) { | ||
| 182 | case 'm': /* sending a private message? */ | ||
| 183 | privatemessagetx( line+2 ); | ||
| 184 | break; | ||
| 185 | case 'a': | ||
| 186 | doaction( line+2 ); | ||
| 187 | break; | ||
| 188 | case '.': | ||
| 189 | /* .. on start of line is public */ | ||
| 190 | if( line[2] != 'm' ) { | ||
| 191 | output_default( line ); | ||
| 192 | } else { | ||
| 193 | /* oopsi, "..m " detected */ | ||
| 194 | /* dunno what to do */ | ||
| 195 | flushout( ); | ||
| 196 | writeout("? You probably misstyped ?"); | ||
| 197 | writeout(" "); | ||
| 198 | writeout(line ); | ||
| 199 | showout( ); | ||
| 200 | } | ||
| 201 | break; | ||
| 202 | default: | ||
| 203 | |||
| 204 | /* generic server command, send to server, show to user */ | ||
| 205 | snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_COMMAND), line); | ||
| 206 | networkoutput (line); | ||
| 207 | writechan (tmpstr); | ||
| 208 | break; | ||
| 209 | } | ||
| 210 | break; | ||
| 211 | case '/': | ||
| 212 | line++; | ||
| 213 | commandtable[translatecommand(&line)].handler(line); | ||
| 214 | break; | ||
| 215 | case '0': | ||
| 216 | break; | ||
| 217 | default: | ||
| 218 | output_default( line ); | ||
| 219 | break; | ||
| 220 | } | ||
| 221 | } | ||
| 222 | |||
| 223 | static void | ||
| 224 | output_default( unsigned char *line ) { | ||
| 225 | /* prepare for output on display */ | ||
| 226 | snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_TXPUBMSG), nick, line); | ||
| 227 | |||
| 228 | /* send original line to server */ | ||
| 229 | networkoutput (line); | ||
| 230 | |||
| 231 | /* output message to channel window */ | ||
| 232 | writechan (tmpstr); | ||
| 233 | } | ||
| 234 | |||
| 235 | /* handle a "/user " request */ | ||
| 236 | static void | ||
| 237 | command_user( unsigned char *tail) | ||
| 238 | { | ||
| 239 | while( *tail == ' ') tail++; | ||
| 240 | if( strlen(tail) >= 3) { | ||
| 241 | unsigned char * out = ul_matchuser( tail); | ||
| 242 | if( *out ) { | ||
| 243 | snprintf( tmpstr, TMPSTRSIZE, getformatstr(FS_USMATCH), tail, out); | ||
| 244 | } else { | ||
| 245 | snprintf( tmpstr, TMPSTRSIZE, getformatstr(FS_ERR), "No user matched that substring"); | ||
| 246 | } | ||
| 247 | } else { | ||
| 248 | snprintf( tmpstr, TMPSTRSIZE, getformatstr(FS_ERR), "Specify at least 3 characters to match users"); | ||
| 249 | } | ||
| 250 | writechan( tmpstr ); | ||
| 251 | } | ||
| 252 | |||
| 253 | /* handle a "/msg " request */ | ||
| 254 | static void | ||
| 255 | command_pm (unsigned char *tail) | ||
| 256 | { | ||
| 257 | privatemessagetx( tail ); | ||
| 258 | } | ||
| 259 | |||
| 260 | /* handle a help request */ | ||
| 261 | static void | ||
| 262 | command_help (unsigned char *line) { | ||
| 263 | flushout( ); | ||
| 264 | while( *line==' ') line++; | ||
| 265 | if( *line ) { /* Get help on command */ | ||
| 266 | int i; | ||
| 267 | if( ( i = translatecommand( &line ) ) != COMMAND_NONE ) { | ||
| 268 | snprintf( tmpstr, TMPSTRSIZE, "Help on command: %s", commandtable[i].name); | ||
| 269 | writeout( tmpstr ); | ||
| 270 | writeout(" "); | ||
| 271 | if( commandtable[i].short_help && !commandtable[i].help ) | ||
| 272 | writeout(commandtable[i].short_help ); | ||
| 273 | line = commandtable[i].help; | ||
| 274 | if( line ) { | ||
| 275 | while( *line ) { | ||
| 276 | unsigned char *tmp = tmpstr; | ||
| 277 | while( *line && (*line != '\n') ) | ||
| 278 | *tmp++ = *line++; | ||
| 279 | *tmp = '\0'; if( *line == '\n') line++; | ||
| 280 | writeout ( tmpstr ); | ||
| 281 | } | ||
| 282 | } | ||
| 283 | } else { | ||
| 284 | command_help( " " ); | ||
| 285 | } | ||
| 286 | } else { /* Get overall help */ | ||
| 287 | int i; | ||
| 288 | for( i = 0; commandtable[i].number != COMMAND_NONE; i++ ) { | ||
| 289 | if( commandtable[i].short_help ) | ||
| 290 | writeout( commandtable[i].short_help ); | ||
| 291 | } | ||
| 292 | } | ||
| 293 | showout(); | ||
| 294 | } | ||
| 295 | |||
| 296 | /* handle an unknown command */ | ||
| 297 | static void | ||
| 298 | command_none( unsigned char *line) { | ||
| 299 | flushout( ); | ||
| 300 | snprintf(tmpstr, TMPSTRSIZE, " Unknown client command: %s ", line); | ||
| 301 | writeout(tmpstr); | ||
| 302 | showout( ); | ||
| 303 | } | ||
| 304 | |||
| 305 | /* handle a "/flt " request */ | ||
| 306 | static void | ||
| 307 | command_flt( unsigned char *tail){ | ||
| 308 | unsigned char colour; | ||
| 309 | while(*tail==' ') tail++; | ||
| 310 | colour = *tail++; | ||
| 311 | while( colour && *tail == ' ') tail++; | ||
| 312 | if( colour && *tail) { | ||
| 313 | addfilter( colour, tail); | ||
| 314 | } | ||
| 315 | } | ||
| 316 | |||
| 317 | /* handle a "/clflt " request */ | ||
| 318 | static void | ||
| 319 | command_clflt ( unsigned char *tail) { | ||
| 320 | while( *tail == ' ') tail++; | ||
| 321 | clearfilters( *tail ); | ||
| 322 | } | ||
| 323 | |||
| 324 | /* handle a "/rmflt " request */ | ||
| 325 | static void | ||
| 326 | command_rmflt ( unsigned char *tail) { | ||
| 327 | while( *tail == ' ') tail++; | ||
| 328 | removefilter( tail ); | ||
| 329 | } | ||
| 330 | |||
| 331 | /* list filters */ | ||
| 332 | static void | ||
| 333 | command_lsflt ( unsigned char *tail) { | ||
| 334 | listfilters(); | ||
| 335 | } | ||
| 336 | |||
| 337 | /* handle a "/me " action */ | ||
| 338 | static void | ||
| 339 | command_action( unsigned char *tail) | ||
| 340 | { | ||
| 341 | doaction( tail); | ||
| 342 | } | ||
| 343 | |||
| 344 | /* handle a "/quit " exit */ | ||
| 345 | static void | ||
| 346 | command_quit ( unsigned char *tail) | ||
| 347 | { | ||
| 348 | /* send users message to server */ | ||
| 349 | snprintf (tmpstr, TMPSTRSIZE, ".x %s", tail); | ||
| 350 | networkoutput (tmpstr); | ||
| 351 | |||
| 352 | /* show action in channel window */ | ||
| 353 | writechan (tmpstr); | ||
| 354 | } | ||
| 355 | |||
| 356 | /* print out version */ | ||
| 357 | void | ||
| 358 | command_version( unsigned char *tail) | ||
| 359 | { | ||
| 360 | /* output internal versions of all modules */ | ||
| 361 | flushout(); | ||
| 362 | writeout (vchat_cl_version); | ||
| 363 | writeout (vchat_ui_version); | ||
| 364 | writeout (vchat_io_version); | ||
| 365 | writeout (vchat_us_version); | ||
| 366 | writeout (vchat_cm_version); | ||
| 367 | showout(); | ||
| 368 | } | ||
