13
13
#include <termios.h>
14
14
#include <sys/ioctl.h>
15
15
16
- #define VERSION "0.2.3" /* version */
17
- #define AUTHORS "Michael Czigler" /* authors */
16
+ #define VERSION "0.2.4" /* version */
18
17
#define MSG_MAX 512 /* max message length */
19
18
#define CHA_MAX 200 /* max channel length */
20
19
#define NIC_MAX 26 /* max nickname length */
@@ -82,19 +81,16 @@ static int enableRawMode(int fd) {
82
81
}
83
82
if (tcgetattr (fd ,& orig ) == -1 )
84
83
goto fatal ;
85
-
86
84
struct termios raw = orig ;
87
85
raw .c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON );
88
86
raw .c_oflag &= ~(OPOST );
89
87
raw .c_cflag |= (CS8 );
90
88
raw .c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG );
91
89
raw .c_cc [VMIN ] = 1 ; raw .c_cc [VTIME ] = 0 ;
92
-
93
90
if (tcsetattr (fd ,TCSAFLUSH ,& raw ) < 0 )
94
91
goto fatal ;
95
92
rawmode = 1 ;
96
93
return 0 ;
97
-
98
94
fatal :
99
95
errno = ENOTTY ;
100
96
return -1 ;
@@ -123,7 +119,6 @@ static int getCursorPosition(int ifd, int ofd) {
123
119
124
120
static int getColumns (int ifd , int ofd ) {
125
121
struct winsize ws ;
126
-
127
122
if (ioctl (1 , TIOCGWINSZ , & ws ) == -1 || ws .ws_col == 0 ) {
128
123
int start = getCursorPosition (ifd , ofd );
129
124
if (start == -1 )
@@ -170,9 +165,7 @@ static void refreshLine(struct State * l) {
170
165
size_t len = l -> len ;
171
166
size_t pos = l -> pos ;
172
167
struct abuf ab ;
173
-
174
168
l -> cols = getColumns (STDIN_FILENO , STDOUT_FILENO );
175
-
176
169
while (plen + pos >= l -> cols ) {
177
170
buf ++ ;
178
171
len -- ;
@@ -271,12 +264,10 @@ static void editBackspace(struct State * l) {
271
264
272
265
static void editDeletePrevWord (struct State * l ) {
273
266
size_t old_pos = l -> pos ;
274
-
275
267
while (l -> pos > 0 && l -> buf [l -> pos - 1 ] == ' ' )
276
268
l -> pos -- ;
277
269
while (l -> pos > 0 && l -> buf [l -> pos - 1 ] != ' ' )
278
270
l -> pos -- ;
279
-
280
271
size_t diff = old_pos - l -> pos ;
281
272
memmove (l -> buf + l -> pos ,l -> buf + old_pos ,l -> len - old_pos + 1 );
282
273
l -> len -= diff ;
@@ -309,10 +300,8 @@ static void editSwapCharWithPrev(struct State * l) {
309
300
static int edit (struct State * l ) {
310
301
char c , seq [3 ];
311
302
ssize_t nread = read (STDIN_FILENO , & c , 1 );
312
-
313
303
if (nread <= 0 )
314
304
return 1 ;
315
-
316
305
switch (c ) {
317
306
case 13 : return 1 ; /* enter */
318
307
case 3 : errno = EAGAIN ; return -1 ; /* ctrl-c */
@@ -385,7 +374,6 @@ static char * ctime_now(char buf[26]) {
385
374
static void logAppend (char * str , char * path ) {
386
375
FILE * out ;
387
376
char buf [26 ];
388
-
389
377
if ((out = fopen (path , "a" )) == NULL ) {
390
378
perror ("fopen" );
391
379
exit (1 );
@@ -398,16 +386,13 @@ static void logAppend(char * str, char * path) {
398
386
static void raw (char * fmt , ...) {
399
387
va_list ap ;
400
388
char * cmd_str = malloc (MSG_MAX );
401
-
402
389
if (!cmd_str ) {
403
390
perror ("malloc" );
404
391
exit (1 );
405
392
}
406
-
407
393
va_start (ap , fmt );
408
394
vsnprintf (cmd_str , MSG_MAX , fmt , ap );
409
395
va_end (ap );
410
-
411
396
if (verb )
412
397
printf ("<< %s" , cmd_str );
413
398
if (olog )
@@ -416,7 +401,6 @@ static void raw(char * fmt, ...) {
416
401
perror ("write" );
417
402
exit (1 );
418
403
}
419
-
420
404
free (cmd_str );
421
405
}
422
406
@@ -426,12 +410,10 @@ static int initConnection(void) {
426
410
.ai_family = AF_UNSPEC ,
427
411
.ai_socktype = SOCK_STREAM
428
412
};
429
-
430
413
if ((gai_status = getaddrinfo (host , port , & hints , & res )) != 0 ) {
431
414
fprintf (stderr , "getaddrinfo: %s\n" , gai_strerror (gai_status ));
432
415
return -1 ;
433
416
}
434
-
435
417
struct addrinfo * p ;
436
418
for (p = res ; p != NULL ; p = p -> ai_next ) {
437
419
if ((conn = socket (p -> ai_family , p -> ai_socktype , p -> ai_protocol )) == -1 ) {
@@ -445,14 +427,11 @@ static int initConnection(void) {
445
427
}
446
428
break ;
447
429
}
448
-
449
430
freeaddrinfo (res );
450
-
451
431
if (p == NULL ) {
452
432
fputs ("Failed to connect\n" , stderr );
453
433
return -1 ;
454
434
}
455
-
456
435
int flags = fcntl (conn , F_GETFL , 0 );
457
436
flags |= O_NONBLOCK ;
458
437
fcntl (conn , F_SETFL , flags );
@@ -554,14 +533,13 @@ static void rawParser(char * string) {
554
533
raw ("%s\r\n" , string );
555
534
return ;
556
535
}
557
- if (string [0 ] != ':' )
536
+ if (string [0 ] != ':' || ( strnlen ( string , MSG_MAX ) < 4 ) )
558
537
return ;
559
538
printf ("\r\x1b[0K" );
560
539
if (verb )
561
540
printf (">> %s" , string );
562
541
if (olog )
563
542
logAppend (string , olog );
564
-
565
543
char * tok ;
566
544
struct Param p ;
567
545
p .prefix = strtok (string , " " ) + 1 ;
@@ -574,7 +552,6 @@ static void rawParser(char * string) {
574
552
p .maxcols = getColumns (STDIN_FILENO , STDOUT_FILENO );
575
553
p .nicklen = (p .maxcols / 3 > NIC_MAX ? NIC_MAX : p .maxcols / 3 );
576
554
p .offset = 0 ;
577
-
578
555
if (!strncmp (p .command , "001" , 3 ) && chan != NULL ) {
579
556
for (tok = strtok (chan , ",|" ); tok != NULL ; tok = strtok (NULL , ",|" )) {
580
557
strcpy (cdef , tok );
@@ -617,10 +594,8 @@ static int handleServerMessage(void) {
617
594
puts ("\r\x1b[E" );
618
595
return -1 ;
619
596
}
620
-
621
597
size_t i , old_message_end = message_end ;
622
598
message_end += nread ;
623
-
624
599
for (i = old_message_end ; i < message_end ; ++ i ) {
625
600
if (i != 0 && message_buffer [i - 1 ] == '\r' && message_buffer [i ] == '\n' ) {
626
601
char saved_char = message_buffer [i + 1 ];
@@ -640,10 +615,8 @@ static int handleServerMessage(void) {
640
615
static void handleUserInput (struct State * l ) {
641
616
if (l -> buf == NULL )
642
617
return ;
643
-
644
618
char * tok ;
645
619
size_t msg_len = strnlen (l -> buf , MSG_MAX );
646
-
647
620
if (msg_len > 0 && l -> buf [msg_len - 1 ] == '\n' )
648
621
l -> buf [msg_len - 1 ] = '\0' ;
649
622
printf ("\r\x1b[0K" );
@@ -679,13 +652,12 @@ static void usage(void) {
679
652
}
680
653
681
654
static void version (void ) {
682
- fputs ("kirc-" VERSION " © 2020 " AUTHORS " \n" , stdout );
655
+ fputs ("kirc-" VERSION "Copyright © 2021 Michael Czigler, MIT License \n" , stdout );
683
656
exit (0 );
684
657
}
685
658
686
659
int main (int argc , char * * argv ) {
687
660
int cval ;
688
-
689
661
while ((cval = getopt (argc , argv , "s:p:o:n:k:c:u:r:x:a:evV" )) != -1 ) {
690
662
switch (cval ) {
691
663
case 'v' : version (); break ;
@@ -704,15 +676,12 @@ int main(int argc, char **argv) {
704
676
case '?' : usage (); break ;
705
677
}
706
678
}
707
-
708
679
if (!nick ) {
709
680
fputs ("Nick not specified\n" , stderr );
710
681
usage ();
711
682
}
712
-
713
683
if (initConnection () != 0 )
714
684
return 1 ;
715
-
716
685
if (auth || sasl )
717
686
raw ("CAP REQ :sasl\r\n" );
718
687
raw ("NICK %s\r\n" , nick );
@@ -725,23 +694,18 @@ int main(int argc, char **argv) {
725
694
raw ("PASS %s\r\n" , pass );
726
695
if (inic )
727
696
raw ("%s\r\n" , inic );
728
-
729
697
struct pollfd fds [2 ];
730
698
fds [0 ].fd = STDIN_FILENO ;
731
699
fds [1 ].fd = conn ;
732
700
fds [0 ].events = POLLIN ;
733
701
fds [1 ].events = POLLIN ;
734
-
735
702
char usrin [MSG_MAX ];
736
-
737
703
struct State l ;
738
704
l .buf = usrin ;
739
705
l .buflen = MSG_MAX ;
740
706
l .prompt = cdef ;
741
707
stateReset (& l );
742
-
743
708
int rc , editReturnFlag = 0 ;
744
-
745
709
if (enableRawMode (STDIN_FILENO ) == -1 )
746
710
return 1 ;
747
711
for (;;) {
0 commit comments