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 {