12
12
#include <sys/wait.h>
13
13
#include <termios.h>
14
14
15
- #define IRC_MSG_MAX 512 /* guaranteed max message length */
16
- #define IRC_CHAN_MAX 200 /* gauranteed max channel length */
15
+ #define IRC_MSG_MAX 512 /* guaranteed max message length */
16
+ #define IRC_CHAN_MAX 200 /* gauranteed max channel length */
17
+ #define STREAM_BUFF 2048 /* maximum stream buffer length */
17
18
18
19
static int conn ; /* connection socket */
19
20
static int verb = 0 ; /* verbose output (e.g. raw stream) */
@@ -59,26 +60,27 @@ kbhit(void) {
59
60
60
61
/* handle keyboard strokes for command input */
61
62
static char *
62
- input_handler (size_t size ) {
63
+ input_handler () {
63
64
64
- char * usrin = malloc (sizeof (char ) * (size + 1 ));
65
+ char * usrin = malloc (sizeof (char ) * (IRC_MSG_MAX + 1 ));
65
66
struct termios tp , save ;
66
67
67
68
tcgetattr (STDIN_FILENO , & tp );
68
69
save = tp ;
69
70
tp .c_cc [VERASE ] = 127 ;
70
71
tcsetattr (STDIN_FILENO , TCSANOW , & tp );
71
- fgets (usrin , size , stdin );
72
+ fgets (usrin , IRC_MSG_MAX , stdin );
72
73
tcsetattr (STDIN_FILENO , TCSANOW , & save );
73
74
74
75
return usrin ;
75
76
}
76
77
77
78
/* send command to irc server */
78
79
static void
79
- raw (char * cmd_str , char * fmt , ...) {
80
+ raw (char * fmt , ...) {
80
81
81
82
va_list ap ;
83
+ char * cmd_str = malloc (sizeof (char ) * (IRC_MSG_MAX + 1 ));
82
84
83
85
va_start (ap , fmt );
84
86
vsnprintf (cmd_str , IRC_MSG_MAX , fmt , ap );
@@ -92,9 +94,8 @@ raw(char *cmd_str, char *fmt, ...) {
92
94
93
95
/* initial irc server connection */
94
96
static void
95
- irc_init (size_t size ) {
97
+ irc_init () {
96
98
97
- char * s = malloc (sizeof (char ) * (size + 1 ));
98
99
struct addrinfo * res , hints = {
99
100
.ai_family = AF_INET ,
100
101
.ai_socktype = SOCK_STREAM
@@ -104,11 +105,11 @@ irc_init(size_t size) {
104
105
conn = socket (res -> ai_family , res -> ai_socktype , res -> ai_protocol );
105
106
connect (conn , res -> ai_addr , res -> ai_addrlen );
106
107
107
- if (nick ) raw (s , "NICK %s\r\n" , nick );
108
- if (user && real ) raw (s , "USER %s - - :%s\r\n" , user , real );
109
- if (user && !real && nick ) raw (s , "USER %s - - :%s\r\n" , user , nick );
110
- if (!user && !real && nick ) raw (s , "USER %s - - :%s\r\n" , nick , nick );
111
- if (pass ) raw (s , "PASS %s\r\n" , pass );
108
+ if (nick ) raw ("NICK %s\r\n" , nick );
109
+ if (user && real ) raw ("USER %s - - :%s\r\n" , user , real );
110
+ if (user && !real && nick ) raw ("USER %s - - :%s\r\n" , user , nick );
111
+ if (!user && !real && nick ) raw ("USER %s - - :%s\r\n" , nick , nick );
112
+ if (pass ) raw ("PASS %s\r\n" , pass );
112
113
113
114
fcntl (conn , F_SETFL , O_NONBLOCK );
114
115
}
@@ -136,8 +137,7 @@ printw(const char *format, ...) {
136
137
if ((wordwidth + spacewidth ) > spaceleft ) {
137
138
printf ("\n%*.s%s" , gutl + 2 , "" , tok );
138
139
spaceleft = cmax - (gutl + 2 + wordwidth );
139
- }
140
- else {
140
+ } else {
141
141
printf (" %s" , tok );
142
142
spaceleft = spaceleft - (wordwidth + spacewidth );
143
143
}
@@ -146,47 +146,38 @@ printw(const char *format, ...) {
146
146
147
147
/* parse irc stream */
148
148
static void
149
- parser (int sl , char * s ) {
149
+ parser (char * string ) {
150
150
151
- int len , i , o = -1 ;
152
- char buf_c [ IRC_MSG_MAX + 1 ] , ltr [200 ], cha [IRC_CHAN_MAX ], nic [200 ], hos [200 ], \
151
+ int len ;
152
+ char * in = string , * tok , ltr [200 ], cha [IRC_CHAN_MAX ], nic [200 ], hos [200 ], \
153
153
usr [200 ], cmd [200 ], msg [200 ], pre [200 ];
154
154
155
- for (i = 0 ; i < sl ; i ++ ) {
156
- o ++ ;
157
- buf_c [o ] = s [i ];
158
-
159
- if ((i > 0 && s [i ] == '\n' && s [i - 1 ] == '\r' ) || o == IRC_MSG_MAX ) {
160
- buf_c [o + 1 ] = '\0' ;
161
- o = -1 ;
162
-
163
- if (verb ) printf (">> %s" , buf_c );
164
-
165
- if (!strncmp (buf_c , "PING" , 4 )) {
166
- buf_c [1 ] = 'O' ;
167
- raw (s , buf_c );
168
- }
169
-
170
- else if (buf_c [0 ] == ':' ) {
171
- sscanf (buf_c , ":%[^ ] %[^:]:%[^\r]" , pre , cmd , msg );
172
- sscanf (pre , "%[^!]!%[^@]@%s" , nic , usr , hos );
173
- sscanf (cmd , "%[^#& ]%s" , ltr , cha );
174
- if (!strncmp (ltr , "001" , 3 )) raw (s , "JOIN #%s\r\n" , chan );
175
-
176
- if (!strncmp (ltr , "QUIT" , 4 )) {
177
- printw ("%*.*s \x1b[34;1m%s\x1b[0m\n" , gutl , gutl , "<--" , nic );
178
- }
179
- else if (!strncmp (ltr , "JOIN" , 4 )) {
180
- printw ("%*.*s \x1b[32;1m%s\x1b[0m\n" , gutl , gutl , "-->" , nic );
181
- }
182
- else {
183
- len = strlen (nic );
184
- printw ("%*s\x1b[33;1m%-.*s\x1b[0m %s\n" , \
185
- gutl - (len <= gutl ? len : gutl ), "" , gutl , nic , msg );
186
- }
155
+ do {
156
+ cmd [0 ] = msg [0 ] = pre [0 ] = '\0' ;
157
+ tok = strstr (in , "\r\n" );
158
+ if (tok ) * tok = '\0' ;
159
+ if (tok && verb ) printf (">> %s\n" , in );
160
+ if (!strncmp (in , "PING" , 4 )) {
161
+ in [string - in + 1 ] = 'O' ;
162
+ raw ("%s\r\n" , in );
163
+ }
164
+ else if (tok && in [0 ] == ':' ) {
165
+ sscanf (in , ":%[^ ] %[^:]:%[^\r]" , pre , cmd , msg );
166
+ sscanf (pre , "%[^!]!%[^@]@%s" , nic , usr , hos );
167
+ sscanf (cmd , "%[^#& ]%s" , ltr , cha );
168
+ if (!strncmp (ltr , "001" , 3 )) raw ("JOIN #%s\r\n" , chan );
169
+ if (!strncmp (ltr , "QUIT" , 4 )) {
170
+ printw ("%*.*s \x1b[34;1m%s\x1b[0m\n" , gutl , gutl , "<--" , nic );
171
+ } else if (!strncmp (ltr , "JOIN" , 4 )) {
172
+ printw ("%*.*s \x1b[32;1m%s\x1b[0m\n" , gutl , gutl , "-->" , nic );
173
+ } else {
174
+ len = strlen (nic );
175
+ printw ("%*s\x1b[33;1m%-.*s\x1b[0m %s\n" , \
176
+ gutl - (len <= gutl ? len : gutl ), "" , gutl , nic , msg );
187
177
}
188
178
}
189
- }
179
+ in = tok + strlen ("\r\n" );
180
+ } while (tok != NULL );
190
181
}
191
182
192
183
int
@@ -228,13 +219,13 @@ main(int argc, char **argv) {
228
219
int sl , i ;
229
220
char u [IRC_MSG_MAX ], s [IRC_MSG_MAX ];
230
221
231
- irc_init (IRC_MSG_MAX );
222
+ irc_init ();
232
223
233
- while ((sl = read (conn , s , IRC_MSG_MAX ))) {
234
- parser (sl , s );
224
+ while ((sl = read (conn , s , STREAM_BUFF ))) {
225
+ if (sl > 0 ) parser ( s );
235
226
if (read (fd [0 ], u , IRC_MSG_MAX ) > 0 ) {
236
227
for (i = 0 ; u [i ] != '\n' ; i ++ ) continue ;
237
- if (u [0 ] != ':' ) raw (s , "%-*.*s\r\n" , i , i , u );
228
+ if (u [0 ] != ':' ) raw ("%-*.*s\r\n" , i , i , u );
238
229
}
239
230
}
240
231
}
@@ -244,7 +235,7 @@ main(int argc, char **argv) {
244
235
while (waitpid (pid , NULL , WNOHANG ) == 0 ) {
245
236
if (!kbhit ()) dprintf (fd [1 ], ":\n" );
246
237
else {
247
- strcpy (usrin , input_handler (IRC_MSG_MAX ));
238
+ strcpy (usrin , input_handler ());
248
239
249
240
if (sscanf (usrin , ":%[M] %s %[^\n]\n" , & c1 , v2 , v1 ) == 3 ||
250
241
sscanf (usrin , ":%[Qnjpm] %[^\n]\n" , & c1 , v1 ) == 2 ||
0 commit comments