Mercurial > hg > nnchat
comparison nnchat.c @ 108:f323b137ca08
Tab-completion now works with cycling, but bugs with names that have whitespaces.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 23 Oct 2010 02:01:00 +0300 |
parents | 8037a3a7e491 |
children | 1323a7f88c21 |
comparison
equal
deleted
inserted
replaced
107:8037a3a7e491 | 108:f323b137ca08 |
---|---|
360 THERR_V(fmt, ap2); | 360 THERR_V(fmt, ap2); |
361 va_end(ap2); | 361 va_end(ap2); |
362 } | 362 } |
363 | 363 |
364 | 364 |
365 int handleUser(int sock, char *str) | 365 int handleUser(int sock, const char *str) |
366 { | 366 { |
367 const char *msg = "</USER><MESSAGE>"; | 367 const char *msg = "</USER><MESSAGE>", *p = str; |
368 char *p = str, *q, *s, *t, *h; | 368 char *q, *s, *t, *h, *p2; |
369 | 369 |
370 (void) sock; | 370 (void) sock; |
371 | 371 |
372 s = strstr(str, msg); | 372 s = strstr(str, msg); |
373 if (!s) return 1; | 373 if (!s) return 1; |
379 *q = 0; | 379 *q = 0; |
380 | 380 |
381 s = nn_decode_str1(s); | 381 s = nn_decode_str1(s); |
382 if (!s) return -1; | 382 if (!s) return -1; |
383 | 383 |
384 p = nn_decode_str1(p); | 384 p2 = nn_decode_str1(p); |
385 if (!p) { | 385 if (!p2) { |
386 th_free(s); | 386 th_free(s); |
387 return -2; | 387 return -2; |
388 } | 388 } |
389 | 389 |
390 | 390 |
391 if (*s == '/') { | 391 if (*s == '/') { |
392 /* Ignore room join/leave messages */ | |
393 if (strstr(s, "left the room") || strstr(s, "joined the room from")) | |
394 goto error; | |
395 | |
392 t = nn_strip_tags(s + 1); | 396 t = nn_strip_tags(s + 1); |
393 if (!strncmp(t, "BPRV", 4)) { | 397 if (!strncmp(t, "BPRV", 4)) { |
394 h = nn_decode_str2(t + 1); | 398 h = nn_decode_str2(t + 1); |
395 printMsg("½11½%s½0½\n", h); | 399 printMsg("½11½%s½0½\n", h); |
396 } else { | 400 } else { |
398 printMsg("½9½* %s½0½\n", h); | 402 printMsg("½9½* %s½0½\n", h); |
399 } | 403 } |
400 th_free(h); | 404 th_free(h); |
401 th_free(t); | 405 th_free(t); |
402 } else { | 406 } else { |
403 BOOL isMine = strcmp(p, optUserName) == 0; | 407 BOOL isMine = strcmp(p2, optUserName) == 0; |
404 BOOL logOnly = FALSE; | 408 BOOL logOnly = FALSE; |
405 t = nn_strip_tags(s); | 409 t = nn_strip_tags(s); |
406 h = nn_decode_str2(t); | 410 h = nn_decode_str2(t); |
407 if (ignoreMode) { | 411 if (ignoreMode) { |
408 char **user = ignoreList; | 412 char **user = ignoreList; |
409 while (*user != NULL) { | 413 while (*user != NULL) { |
410 if (strcasecmp(p, *user) == 0) { | 414 if (strcasecmp(p2, *user) == 0) { |
411 logOnly = TRUE; | 415 logOnly = TRUE; |
412 break; | 416 break; |
413 } | 417 } |
414 user++; | 418 user++; |
415 } | 419 } |
416 } | 420 } |
417 printMsgQ(logOnly, "½5½<½%d½%s½5½>½0½ %s\n", isMine ? 14 : 15, p, h); | 421 printMsgQ(logOnly, "½5½<½%d½%s½5½>½0½ %s\n", isMine ? 14 : 15, p2, h); |
418 th_free(h); | 422 th_free(h); |
419 th_free(t); | 423 th_free(t); |
420 } | 424 } |
421 | 425 |
426 error: | |
422 th_free(s); | 427 th_free(s); |
423 th_free(p); | 428 th_free(p2); |
424 return 0; | 429 return 0; |
425 } | 430 } |
426 | 431 |
427 | 432 |
428 int handleLogin(int sock, char *str) | 433 int handleLogin(int sock, const char *str) |
429 { | 434 { |
430 char tmpStr[256] = ""; | 435 char tmpStr[256] = ""; |
431 time_t timeStamp; | 436 time_t timeStamp; |
432 struct tm *tmpTime;; | 437 struct tm *tmpTime;; |
433 | 438 |
446 } else | 451 } else |
447 return 1; | 452 return 1; |
448 } | 453 } |
449 | 454 |
450 | 455 |
451 int handleAddUser(int sock, char *str) | 456 int handleAddUser(int sock, const char *str) |
452 { | 457 { |
453 char *p, *s = strstr(str, "</ADD_USER>"); | 458 char *p, *s = strstr(str, "</ADD_USER>"); |
454 | 459 |
455 (void) sock; | 460 (void) sock; |
456 | 461 |
466 th_free(p); | 471 th_free(p); |
467 return 0; | 472 return 0; |
468 } | 473 } |
469 | 474 |
470 | 475 |
471 int handleDeleteUser(int sock, char *str) | 476 int handleDeleteUser(int sock, const char *str) |
472 { | 477 { |
473 char *p, *s = strstr(str, "</DELETE_USER>"); | 478 char *p, *s = strstr(str, "</DELETE_USER>"); |
474 | 479 |
475 (void) sock; | 480 (void) sock; |
476 | 481 |
486 th_free(p); | 491 th_free(p); |
487 return 0; | 492 return 0; |
488 } | 493 } |
489 | 494 |
490 | 495 |
491 int handleFoo(int sock, char *str) | 496 int handleFoo(int sock, const char *str) |
492 { | 497 { |
493 (void) sock; (void) str; | 498 (void) sock; (void) str; |
494 | 499 |
495 return 0; | 500 return 0; |
496 } | 501 } |
497 | 502 |
498 | 503 |
499 int handleBoot(int sock, char *str) | 504 int handleBoot(int sock, const char *str) |
500 { | 505 { |
501 (void) sock; (void) str; | 506 (void) sock; (void) str; |
502 errorMsg("Booted by server.\n"); | 507 errorMsg("Booted by server.\n"); |
503 return -1; | 508 return -1; |
504 } | 509 } |
505 | 510 |
506 | 511 |
507 typedef struct { | 512 typedef struct { |
508 char *cmd; | 513 char *cmd; |
509 int (*handler)(int, char *); | 514 int (*handler)(int, const char *); |
510 } protocmd_t; | 515 } protocmd_t; |
511 | 516 |
512 | 517 |
513 protocmd_t protoCmds[] = { | 518 static const protocmd_t protoCmds[] = { |
514 { "<USER>", handleUser }, | 519 { "<USER>", handleUser }, |
515 { "<LOGIN_", handleLogin }, | 520 { "<LOGIN_", handleLogin }, |
516 { "<DELETE_USER>", handleDeleteUser }, | 521 { "<DELETE_USER>", handleDeleteUser }, |
517 { "<ADD_USER>", handleAddUser }, | 522 { "<ADD_USER>", handleAddUser }, |
518 { "<NUMCLIENTS>", handleFoo }, | 523 { "<NUMCLIENTS>", handleFoo }, |
519 { "<BOOT />", handleBoot }, | 524 { "<BOOT />", handleBoot }, |
520 }; | 525 }; |
521 | 526 |
522 const int nprotoCmds = (sizeof(protoCmds) / sizeof(protoCmds[0])); | 527 static const int nprotoCmds = sizeof(protoCmds) / sizeof(protoCmds[0]); |
523 | 528 |
524 | 529 |
525 int handleProtocol(const int sock, char *buf, size_t bufLen) | 530 int handleProtocol(const int sock, const char *buf, const size_t bufLen) |
526 { | 531 { |
527 int i; | 532 int i; |
528 | 533 |
529 for (i = 0; i < nprotoCmds; i++) { | 534 for (i = 0; i < nprotoCmds; i++) { |
530 size_t cmdLen = strlen(protoCmds[i].cmd); | 535 size_t cmdLen = strlen(protoCmds[i].cmd); |
558 } | 563 } |
559 optUserColor = tmpInt; | 564 optUserColor = tmpInt; |
560 printMsg("Setting color to #%06x\n", optUserColor); | 565 printMsg("Setting color to #%06x\n", optUserColor); |
561 nn_send_msg(sock, optUserName2, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor); | 566 nn_send_msg(sock, optUserName2, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor); |
562 return 0; | 567 return 0; |
563 } else if (!strncmp(buf, "/flood ", 7)) { | 568 } else if (!strncmp(buf, "/w ", 3)) { |
564 int i; | 569 char *name = buf + 3; |
565 | 570 pid_t pud; |
566 snprintf(tmpBuf, sizeof(tmpBuf), "/prv -to %s -msg . .", | 571 tmpStr = nn_encode_str1(name); |
567 buf+7); | 572 snprintf(tmpBuf, sizeof(tmpBuf), "openurl(http://www.newbienudes.com/profile/%s/,new-tab)", tmpStr); |
568 | |
569 tmpStr = nn_dblencode_str(tmpBuf); | |
570 if (!tmpStr) return -2; | |
571 | |
572 result = TRUE; | |
573 for (i = 0; i < 50 && result; i++) { | |
574 result = nn_send_msg(sock, optUserName2, "%s", tmpStr); | |
575 usleep(250); | |
576 } | |
577 | |
578 th_free(tmpStr); | 573 th_free(tmpStr); |
579 return 0; | 574 |
575 printMsg("Opening profile for: %s\n", name); | |
576 printMsg("%s\n", tmpBuf); | |
577 /* | |
578 if ((pud = fork()) < 0) return 0; | |
579 if (getpid() == pud) { | |
580 execlp("firefox", "-remote", tmpBuf, (char *) NULL); | |
581 exit(0); | |
582 } else | |
583 */ | |
584 return 0; | |
580 } else if (!strncmp(buf, "/to ", 4)) { | 585 } else if (!strncmp(buf, "/to ", 4)) { |
581 th_free(setTarget); | 586 th_free(setTarget); |
582 setTarget = th_strdup(buf + 4); | 587 setTarget = th_strdup(buf + 4); |
583 printMsg("Set prv target to '%s'\n", setTarget); | 588 printMsg("Set prv target to '%s'\n", setTarget); |
584 return 0; | 589 return 0; |
628 | 633 |
629 void performTabCompletion(nn_editbuf_t *buf) | 634 void performTabCompletion(nn_editbuf_t *buf) |
630 { | 635 { |
631 static char *previous = NULL; | 636 static char *previous = NULL; |
632 static char *matsi = NULL; | 637 static char *matsi = NULL; |
633 char *s = NULL, *b = buf->data; | 638 char *b = buf->data; |
634 ssize_t pos2, pos1 = buf->pos; | 639 ssize_t pos2 = 0, pos1 = buf->pos; |
635 | 640 |
636 if (pos1 > 0) pos1--; | 641 if (pos1 > 0) pos1--; |
637 | 642 |
638 if (pos1 > 0 && b[pos1 - 1] == ':') { | 643 if (pos1 > 0 && b[pos1 - 1] == ':') { |
639 pos1 -= 2; | 644 pos1 -= 2; |
640 pos2 = pos1; | 645 pos2 = pos1; |
641 while (pos1 > 0 && b[pos1 - 1] != ' ') pos1--; | 646 while (pos1 > 0 && b[pos1 - 1] != ' ') pos1--; |
642 s = nn_editbuf_get_string(buf, pos1, pos2); | |
643 } else | 647 } else |
644 if (b[pos1] != ' ' && b[pos1] != ':') { | 648 if (b[pos1] != ' ' && b[pos1] != ':') { |
645 pos2 = pos1; | 649 pos2 = pos1; |
646 while (pos1 > 0 && b[pos1 - 1] != ' ') pos1--; | 650 while (pos1 > 0 && b[pos1 - 1] != ' ') pos1--; |
647 while (pos2 < buf->len && b[pos2] != ' ') pos2++; | 651 while (pos2 < buf->len && b[pos2] != ' ') pos2++; |
648 while (pos2 > 0 && b[pos2] == ' ') pos2--; | 652 while (pos2 > 0 && b[pos2] == ' ') pos2--; |
649 s = nn_editbuf_get_string(buf, pos1, pos2); | |
650 th_free(previous); | |
651 th_free(matsi); | 653 th_free(matsi); |
652 matsi = NULL; | 654 matsi = nn_editbuf_get_string(buf, pos1, pos2); |
653 previous = NULL; | 655 th_free(previous); previous = NULL; |
654 } | 656 } |
655 | 657 |
656 if (s) { | 658 if (matsi) { |
657 nn_user_t *m; | 659 nn_user_t *user = nn_user_match(nnUsers, matsi, previous); |
658 if (matsi) | 660 // printMsg("pattern '%s'\n", matsi); |
659 m = nn_user_match(nnUsers, matsi, previous); | 661 |
660 else | 662 if (user) { |
661 m = nn_user_match(nnUsers, s, previous); | |
662 | |
663 if (m) { | |
664 int i; | 663 int i; |
665 char *c = m->name; | 664 char *c = user->name; |
666 printMsg("match '%s'\n", m->name); | 665 // printMsg("match '%s'\n", user->name); |
667 | 666 |
668 for (i = pos1; i <= pos2; i++) | 667 for (i = pos1; i <= pos2; i++) |
669 nn_editbuf_delete(buf, pos1); | 668 nn_editbuf_delete(buf, pos1); |
670 | 669 |
671 for (i = pos1; *c; i++, c++) | 670 for (i = pos1; *c; i++, c++) |
673 | 672 |
674 if (previous == NULL) { | 673 if (previous == NULL) { |
675 nn_editbuf_insert(buf, i+1, ':'); | 674 nn_editbuf_insert(buf, i+1, ':'); |
676 nn_editbuf_insert(buf, i+2, ' '); | 675 nn_editbuf_insert(buf, i+2, ' '); |
677 } | 676 } |
678 nn_editbuf_setpos(buf, pos1 + 2 + strlen(m->name)); | 677 nn_editbuf_setpos(buf, pos1 + 2 + strlen(user->name)); |
679 | 678 |
680 if (previous == NULL) { | 679 th_free(previous); |
681 previous = th_strdup(m->name); | 680 previous = th_strdup(user->name); |
682 matsi = th_strdup(s); | 681 } |
683 } | |
684 } | |
685 th_free(s); | |
686 } | 682 } |
687 } | 683 } |
688 | 684 |
689 int main(int argc, char *argv[]) | 685 int main(int argc, char *argv[]) |
690 { | 686 { |