23
23
#define CHA_MAX 200
24
24
#define NIC_MAX 26
25
25
#define HIS_MAX 100
26
+ #define CBUF_SIZ 1024
26
27
27
- static char cdef [MSG_MAX ] = "?" ; /* default PRIVMSG channel */
28
- static int conn ; /* connection socket */
29
- static int verb = 0 ; /* verbose output */
30
- static int sasl = 0 ; /* SASL method */
31
- static int isu8 = 0 ; /* UTF-8 flag */
32
- static char * host = "irc.libera.chat" ; /* host address */
33
- static char * port = "6667" ; /* port */
34
- static char * chan = NULL ; /* channel(s) */
35
- static char * nick = NULL ; /* nickname */
36
- static char * pass = NULL ; /* password */
37
- static char * user = NULL ; /* user name */
38
- static char * auth = NULL ; /* PLAIN SASL token */
39
- static char * real = NULL ; /* real name */
40
- static char * olog = NULL ; /* chat log path*/
41
- static char * inic = NULL ; /* additional server command */
28
+ static char cdef [MSG_MAX ] = "?" ; /* default PRIVMSG channel */
29
+ static int conn ; /* connection socket */
30
+ static int verb = 0 ; /* verbose output */
31
+ static int sasl = 0 ; /* SASL method */
32
+ static int isu8 = 0 ; /* UTF-8 flag */
33
+ static char * host = "irc.libera.chat" ; /* host address */
34
+ static char * port = "6667" ; /* port */
35
+ static char * chan = NULL ; /* channel(s) */
36
+ static char * nick = NULL ; /* nickname */
37
+ static char * pass = NULL ; /* password */
38
+ static char * user = NULL ; /* user name */
39
+ static char * auth = NULL ; /* PLAIN SASL token */
40
+ static char * real = NULL ; /* real name */
41
+ static char * olog = NULL ; /* chat log path*/
42
+ static char * inic = NULL ; /* additional server command */
43
+ static int cmds = 0 ; /* indicates additional server commands */
44
+ static char cbuf [CBUF_SIZ ]; /* additional stdin server commands */
42
45
43
46
struct Param {
44
47
char * prefix ;
@@ -53,6 +56,7 @@ struct Param {
53
56
int nicklen ;
54
57
};
55
58
59
+ static int ttyinfd = STDIN_FILENO ;
56
60
static struct termios orig ;
57
61
static int rawmode = 0 ;
58
62
static int atexit_registered = 0 ;
@@ -92,14 +96,14 @@ static void freeHistory(void) {
92
96
}
93
97
94
98
static void disableRawMode (void ) {
95
- if (rawmode && tcsetattr (STDIN_FILENO ,TCSAFLUSH ,& orig ) != -1 ) {
99
+ if (rawmode && tcsetattr (ttyinfd ,TCSAFLUSH ,& orig ) != -1 ) {
96
100
rawmode = 0 ;
97
101
}
98
102
freeHistory ();
99
103
}
100
104
101
105
static int enableRawMode (int fd ) {
102
- if (!isatty (STDIN_FILENO )) {
106
+ if (!isatty (ttyinfd )) {
103
107
goto fatal ;
104
108
}
105
109
if (!atexit_registered ) {
@@ -297,7 +301,7 @@ static void refreshLine(struct State *l) {
297
301
size_t posu8 = l -> posu8 ;
298
302
size_t ch = plenu8 , txtlenb = 0 ;
299
303
struct abuf ab ;
300
- l -> cols = getColumns (STDIN_FILENO , STDOUT_FILENO );
304
+ l -> cols = getColumns (ttyinfd , STDOUT_FILENO );
301
305
while ((plenu8 + posu8 ) >= l -> cols ) {
302
306
buf += u8Next (buf , 0 );
303
307
posu8 -- ;
@@ -510,12 +514,12 @@ static void editEnter(void) {
510
514
}
511
515
512
516
static void editEscSequence (struct State * l , char seq [3 ]) {
513
- if (read (STDIN_FILENO , seq , 1 ) == -1 ) return ;
514
- if (read (STDIN_FILENO , seq + 1 , 1 ) == -1 ) return ;
517
+ if (read (ttyinfd , seq , 1 ) == -1 ) return ;
518
+ if (read (ttyinfd , seq + 1 , 1 ) == -1 ) return ;
515
519
if (seq [0 ] == '[' ) { /* ESC [ sequences. */
516
520
if ((seq [1 ] >= '0' ) && (seq [1 ] <= '9' )) {
517
521
/* Extended escape, read additional byte. */
518
- if (read (STDIN_FILENO , seq + 2 , 1 ) == -1 ) {
522
+ if (read (ttyinfd , seq + 2 , 1 ) == -1 ) {
519
523
return ;
520
524
}
521
525
if ((seq [2 ] == '~' ) && (seq [1 ] == 3 )) {
@@ -542,7 +546,7 @@ static void editEscSequence(struct State *l, char seq[3]) {
542
546
static int edit (struct State * l ) {
543
547
char c , seq [3 ];
544
548
int ret = 0 ;
545
- ssize_t nread = read (STDIN_FILENO , & c , 1 );
549
+ ssize_t nread = read (ttyinfd , & c , 1 );
546
550
if (nread <= 0 ) {
547
551
ret = 1 ;
548
552
} else {
@@ -577,7 +581,7 @@ static int edit(struct State *l) {
577
581
aux [0 ] = c ;
578
582
int size = u8CharSize (c );
579
583
for (int i = 1 ; i < size ; i ++ ) {
580
- nread = read (STDIN_FILENO , aux + i , 1 );
584
+ nread = read (ttyinfd , aux + i , 1 );
581
585
if ((aux [i ] & 0xC0 ) != 0x80 ) {
582
586
break ;
583
587
}
@@ -803,7 +807,7 @@ static void rawParser(char *string) {
803
807
p .command = strtok (p .suffix , "#& " );
804
808
p .channel = strtok (NULL , " \r" );
805
809
p .params = strtok (NULL , ":\r" );
806
- p .maxcols = getColumns (STDIN_FILENO , STDOUT_FILENO );
810
+ p .maxcols = getColumns (ttyinfd , STDOUT_FILENO );
807
811
p .nicklen = (p .maxcols / 3 > NIC_MAX ? NIC_MAX : p .maxcols / 3 );
808
812
p .offset = 0 ;
809
813
if (!strncmp (p .command , "001" , 3 ) && chan != NULL ) {
@@ -922,26 +926,41 @@ static void version(void) {
922
926
exit (0 );
923
927
}
924
928
929
+ static void opentty ()
930
+ {
931
+ if ((ttyinfd = open ("/dev/tty" , 0 )) == -1 ) {
932
+ perror ("failed to open /dev/tty" );
933
+ exit (1 );
934
+ }
935
+ }
936
+
925
937
int main (int argc , char * * argv ) {
938
+ opentty ();
926
939
int cval ;
927
- while ((cval = getopt (argc , argv , "s:p:o:n:k:c:u:r:x:a:evV " )) != -1 ) {
940
+ while ((cval = getopt (argc , argv , "s:p:o:n:k:c:u:r:a:exvV " )) != -1 ) {
928
941
switch (cval ) {
929
- case 'v' : version (); break ;
930
- case 'V' : ++ verb ; break ;
931
- case 'e' : ++ sasl ; break ;
932
- case 's' : host = optarg ; break ;
933
- case 'p' : port = optarg ; break ;
934
- case 'r' : real = optarg ; break ;
935
- case 'u' : user = optarg ; break ;
936
- case 'a' : auth = optarg ; break ;
937
- case 'o' : olog = optarg ; break ;
938
- case 'n' : nick = optarg ; break ;
939
- case 'k' : pass = optarg ; break ;
940
- case 'c' : chan = optarg ; break ;
941
- case 'x' : inic = optarg ; break ;
942
+ case 'v' : version (); break ;
943
+ case 'V' : ++ verb ; break ;
944
+ case 'e' : ++ sasl ; break ;
945
+ case 's' : host = optarg ; break ;
946
+ case 'p' : port = optarg ; break ;
947
+ case 'r' : real = optarg ; break ;
948
+ case 'u' : user = optarg ; break ;
949
+ case 'a' : auth = optarg ; break ;
950
+ case 'o' : olog = optarg ; break ;
951
+ case 'n' : nick = optarg ; break ;
952
+ case 'k' : pass = optarg ; break ;
953
+ case 'c' : chan = optarg ; break ;
954
+ case 'x' : cmds = 1 ; inic = argv [ optind ] ; break ;
942
955
case '?' : usage (); break ;
943
956
}
944
957
}
958
+ if (cmds > 0 ) {
959
+ int flag = 0 ;
960
+ for (int i = 0 ; i < CBUF_SIZ && flag > -1 ; i ++ ) {
961
+ flag = read (STDIN_FILENO , & cbuf [i ], 1 );
962
+ }
963
+ }
945
964
if (!nick ) {
946
965
fputs ("Nick not specified\n" , stderr );
947
966
usage ();
@@ -961,11 +980,16 @@ int main(int argc, char **argv) {
961
980
if (pass ) {
962
981
raw ("PASS %s\r\n" , pass );
963
982
}
964
- if (inic ) {
965
- raw ("%s\r\n" , inic );
983
+ if (cmds > 0 ) {
984
+ for (char * tok = strtok (cbuf , "\n" ); tok ; tok = strtok (NULL , "\n" )) {
985
+ raw ("%s\r\n" , tok );
986
+ }
987
+ if (inic ) {
988
+ raw ("%s\r\n" , inic );
989
+ }
966
990
}
967
991
struct pollfd fds [2 ];
968
- fds [0 ].fd = STDIN_FILENO ;
992
+ fds [0 ].fd = ttyinfd ;
969
993
fds [1 ].fd = conn ;
970
994
fds [0 ].events = POLLIN ;
971
995
fds [1 ].events = POLLIN ;
@@ -976,10 +1000,10 @@ int main(int argc, char **argv) {
976
1000
l .prompt = cdef ;
977
1001
stateReset (& l );
978
1002
int rc , editReturnFlag = 0 ;
979
- if (enableRawMode (STDIN_FILENO ) == -1 ) {
1003
+ if (enableRawMode (ttyinfd ) == -1 ) {
980
1004
return 1 ;
981
1005
}
982
- if (setIsu8_C (STDIN_FILENO , STDOUT_FILENO ) == -1 ) {
1006
+ if (setIsu8_C (ttyinfd , STDOUT_FILENO ) == -1 ) {
983
1007
return 1 ;
984
1008
}
985
1009
for (;;) {
0 commit comments