]> jfr.im git - irc.git/blame - software/ircd/www.irc.org/ftp/irc/clients/vms/ircII-for-vms/builtin.c
init
[irc.git] / software / ircd / www.irc.org / ftp / irc / clients / vms / ircII-for-vms / builtin.c
CommitLineData
3bd189cb
JR
1#include <stdio.h>
2#include <string.h>
3#ifdef __GNUC__
4#else
5#include <unixio.h>
6#endif
7#include <file.h>
8#include <ctype.h>
9#include <stdlib.h>
10#include <time.h>
11#include <descrip.h>
12#include <lib$routines.h>
13#include "base_includes.h"
14#include "qio.h"
15#include "on.h"
16#include "window_i.h"
17#include "split.h"
18#include "winfunc.h"
19#include "system.h"
20#include "ff.h"
21#include "chan.h"
22#include "dcc.h"
23#include "builtin.h"
24#include "mycompare.h"
25#include "sock.h"
26#include "window.h"
27#include "alias.h"
28
29extern int sys$setddir(); /* not in header files */
30extern char userhost[], curr_time_s[];
31extern server_ptr gsrv;
32
33/* ---------------------------------------------------------------------- */
34/* --------------------------------------------------------------------- */
35/* This is where we handle all of the builtin functions. */
36/* --------------------------------------------------------------------- */
37struct command_node2 {
38 char *name;
39 void (*routine)();
40};
41
42/* ---------------------------------------------------------------------- */
43extern long myaddress;
44static void built_ip(char *str, char *ret, int len)
45{
46 sprintf(ret, "%u", tcp_htonl(myaddress));
47}
48
49/* ---------------------------------------------------------------------- */
50static void built_index(char *str, char *ret, int len)
51{
52 char *word;
53 int ind, l0, l1, good = -1;
54 word = next_arg(&str);
55 for (l0=0; (l0<strlen(str)) && (good == -1) ;l0++)
56 for (l1=0;l1<strlen(word);l1++)
57 if (tolower(word[l1]) == tolower(str[l0])) good = l0;
58 (void)sprintf(ret, "%d\0", good);
59}
60
61/* ---------------------------------------------------------------------- */
62static void built_rindex(char *str, char *ret, int len)
63{
64 int loop1, loop2, good = -1;
65 char *word;
66 word = next_arg(&str);
67 for (loop1 = strlen(str)-1; (loop1>=0) && (good==-1); loop1--)
68 for (loop2 = 0; loop2<strlen(word); loop2++)
69 if (tolower(word[loop2]) == tolower(str[loop1])) good = loop1;
70 (void)sprintf(ret, "%d\0", good);
71}
72
73/* ---------------------------------------------------------------------- */
74static void built_ischannel(char *str, char *ret, int len)
75{
76 if (is_chan(str)) strcpy(ret, "1");
77 else (void)strcpy(ret, "0");
78}
79
80/* ---------------------------------------------------------------------- */
81static void built_ischanop(char *str, char *ret, int len)
82{
83 char *nick, *chan;
84 nick = next_arg(&str);
85 chan = next_arg(&str);
86 if (gsrv) sprintf(ret, "%ld",is_chanop(get_server_chanlist(gsrv),chan,nick));
87 else (void)strcpy(ret, "0");
88}
89
90/* ---------------------------------------------------------------------- */
91static void built_userhost(char *str, char *ret, int len)
92{
93 (void)strcpy(ret, userhost);
94}
95
96/* ---------------------------------------------------------------------- */
97static void built_left(char *str, char *ret, int len)
98{
99 int x;
100 char *word;
101 word = next_arg(&str);
102 x = atoi(word);
103 if (x<0)
104 ret[0] = 0;
105 else {
106/* IF there aren't x characters, then it will copy up to and including NULL */
107 (void)strncpy(ret, str, x);
108 ret[x] = 0;
109 }
110}
111
112/* ---------------------------------------------------------------------- */
113static void built_right(char *str, char *ret, int len)
114{
115 char *word;
116 int wlen, x;
117 word = next_arg(&str);
118 wlen = strlen(str);
119 x = atoi(word);
120 if (x>wlen) x = wlen;
121 if (x < 0) *ret = 0;
122 else strcpy(ret, &str[wlen-x]);
123}
124
125/* ---------------------------------------------------------------------- */
126static void built_rand(char *str, char *ret, int len)
127{
128 int xx;
129 xx = atoi(str);
130 (void)sprintf(ret, "%d\0", rand()%xx);
131}
132
133/* ---------------------------------------------------------------------- */
134static void built_tolower(char *str, char *ret, int len)
135{
136 while (*str) *ret++ = tolower(*str++);
137 *ret = 0;
138}
139
140/* ---------------------------------------------------------------------- */
141static void built_toupper(char *str, char *ret, int len)
142{
143 while (*str) *ret++ = toupper(*str++);
144 *ret = 0;
145}
146
147/* ---------------------------------------------------------------------- */
148static void built_mid(char *str, char *ret, int len)
149{
150 char *w1, *w2;
151 int left, count, wlen;
152 w1 = next_arg(&str);
153 w2 = next_arg(&str);
154 left = atoi(w1);
155 count = atoi(w2);
156 wlen = strlen(str);
157 if ((left>=wlen) || (left<0) || (count<0)) *ret = 0;
158 else {
159 if ((left+count) > wlen) count = wlen-left;
160 (void)strncpy(ret, &str[left], count);
161 ret[count] = 0;
162 }
163}
164
165/* ---------------------------------------------------------------------- */
166static void built_match(char *str, char *ret, int len)
167{
168 char *pattern, *word;
169 int xx = 1, good = 0;
170
171 pattern = next_arg(&str);
172 do {
173 word = next_arg(&str);
174 if (wild_match(pattern, word)!=-1) good = xx;
175 xx++;
176 } while ((good==0) && (*str));
177 (void)sprintf(ret, "%d\0", good);
178}
179
180/* ---------------------------------------------------------------------- */
181static void built_time(char *str, char *ret, int len)
182{
183 (void)sprintf(ret, "%d\0", time(0));
184}
185
186/* ---------------------------------------------------------------------- */
187static void built_srand(char *str, char *ret, int len)
188{
189 unsigned some_time;
190 some_time = time(NULL);
191 srand(some_time);
192 sprintf(ret, "%d", some_time);
193}
194/* ---------------------------------------------------------------------- */
195static void built_stime(char *str, char *ret, int len)
196{
197 unsigned time;
198 time = atoi(str);
199 (void)sprintf(ret, "%s\0", ctime( (unsigned long *) (&time)) );
200 ret[strlen(ret)-1] = 0;
201}
202
203/* ---------------------------------------------------------------------- */
204static void built_strip(char *str, char *ret, int len)
205{
206 char *word;
207 word = next_arg(&str);
208 while (*str) {
209 if (!strchr(word, *str)) *ret++ = *str;
210 str++;
211 }
212 *ret = 0;
213}
214
215/* ---------------------------------------------------------------------- */
216static void built_rmatch(char *str, char *ret, int len)
217{
218 char *word1, *word2;
219 int count = 0, best_num, this, best = 0;
220 best_num = -1;
221 word1 = next_arg(&str);
222 word2 = next_arg(&str);
223 while (*word2) {
224 count++;
225 this = wild_match(word2, word1);
226 if (this>best_num) {
227 best_num = this;
228 best = count;
229 }
230 word2 = next_arg(&str);
231 }
232 (void)sprintf(ret, "%d\0", best);
233}
234
235/* ---------------------------------------------------------------------- */
236static void built_encode(char *str, char *ret, int len)
237{
238 while (*str) {
239 *ret++ = (*str >> 4) + 'A';
240 *ret++ = (*str & 0x0f) + 'A';
241 str++;
242 }
243 *ret = 0;
244}
245
246/* ---------------------------------------------------------------------- */
247static void built_decode(char *str, char *ret, int len)
248{
249 while (*str && *(str + 1)) {
250 *ret++ = ((*str - 'A') << 4) | (*(str+1) - 'A');
251 str = (char *)((int)str + 2);
252 }
253 *ret = 0;
254}
255
256/* ---------------------------------------------------------------------- */
257static void built_word(char *str, char *ret, int len)
258{
259 char *word, *start;
260 word = next_arg(&str);
261 start = find_word_num(str, atoi(word));
262 while (!isspace(*start) && *start && (--len > 0))
263 *ret++ = *start++;
264 *ret = 0;
265}
266
267/* ---------------------------------------------------------------------- */
268static void built_tdiff(char *str, char *ret, int len)
269{
270 int num, days, hours, minutes, seconds, time;
271 time = atoi(str);
272 days = time / (60 * 60 * 24);
273 hours = (time / (60 * 60)) % 24;
274 minutes = (time / 60) % 60;
275 seconds = (time) % 60;
276 *ret = 0;
277 if (days>0) sprintf(ret, "%d days ", days);
278 ret += strlen(ret);
279 if (hours>0) sprintf(ret, "%d hours ", hours);
280 ret += strlen(ret);
281 if (minutes>0) sprintf(ret, "%d minutes ", minutes);
282 ret += strlen(ret);
283 sprintf(ret, "%d seconds", seconds);
284}
285
286/* ---------------------------------------------------------------------- */
287int read_raw_exit(connect_node *node)
288{
289 char line[80];
290 sprintf(line, "%d host C", node->iochan);
291 handle_on(o_dcc_raw, line, 0);
292 return 1;
293}
294
295/* ---------------------------------------------------------------------- */
296int read_raw_connect(connect_node *node)
297{
298 char *walk, *back, line[MAXLEN];
299 node->buffer[node->iosb.length] = 0;
300 for (back = walk = node->buffer; *walk; walk++)
301 {
302 if (*walk == '\n') {
303 *walk = 0;
304 if ((walk > node->buffer) && (walk[-1]=='\015')) walk[-1] = 0;
305 sprintf(line, "%d host D %s", node->iochan, back);
306 if (!handle_on(o_dcc_raw, line, 0))
307 say("+ %s", back);
308 back = walk + 1;
309 }
310 }
311 if (*back) say("+ %s", back);
312 return 1;
313}
314
315/* ---------------------------------------------------------------------- */
316static int lame_routine(short chan)
317{
318 char line[80];
319 short nchan;
320 SIN sin;
321 nchan = tcp_accept_after_wait(chan, chan, &sin, sizeof(sin));
322 sprintf(line, "%d host N %d", nchan, tcp_htons(sin.sin_port));
323 handle_on(o_dcc_raw, line, 0);
324 start_read(chan, nchan, read_raw_connect, read_raw_exit);
325 return 1;
326}
327
328/* ---------------------------------------------------------------------- */
329void built_write(char *str, char *ret, int len)
330{
331 int crlf, num, chan;
332 char line[MAXLEN], *send;
333
334 send = line;
335 chan = atoi(next_arg(&str));
336 crlf = atoi(next_arg(&str));
337 if (crlf) sprintf(line, "%s\015\012", str);
338 else send = str;
339 num = tcp_send(chan, send, strlen(send));
340 sprintf(ret, "%d", num);
341}
342
343/* ---------------------------------------------------------------------- */
344static void built_connect_start(char *str, char *ret, int len)
345{
346 int chan;
347 chan = atoi(str);
348 start_read(chan, chan, read_raw_connect, read_raw_exit);
349}
350/* ---------------------------------------------------------------------- */
351static void built_connect(char *str, char *ret, int len)
352{
353 extern int nslookup(char *host, char *ns, char *answer);
354 char *serv, errmsg[80];
355 short chan, port, wait;
356 SIN sin, *new_sin;
357 strcpy(ret, "-1 -1");
358 serv = next_arg(&str);
359 port = atoi(next_arg(&str));
360 wait = atoi(next_arg(&str));
361 memset(&sin, 0, sizeof(sin));
362 if (!good_host((unsigned char *)&sin.sin_address, serv))
363 if (!nslookup(getvar(VAR_NAMESERVER), serv, (char *)&sin.sin_address))
364 {
365 yell("*** could not resolve %s via [%s]\n", serv,
366 getvar(VAR_NAMESERVER));
367 return;
368 }
369 sin.sin_port = tcp_htons(port);
370 sin.sin_family = AF_INET;
371 chan = tcp_socket_and_connect(&sin, sizeof(sin));
372 if (chan!=-1)
373 {
374 sprintf(ret, "%d", chan);
375 new_sin = (SIN *)mymalloc(sizeof(sin));
376 memcpy(new_sin, &sin, sizeof(sin));
377 add_connect_to_list(chan, new_sin, NULL, CONNECT_RAW);
378 if (!wait) start_read(chan, chan, read_raw_connect, read_raw_exit);
379 } else {
380 get_socket_error(errmsg);
381 yell("qio_socket_and_connect: %s", errmsg);
382 }
383}
384
385/* ---------------------------------------------------------------------- */
386static void built_listen(char *str, char *ret, int len)
387{
388 SIN *sin;
389 short chan;
390 sin = tcp_bind_and_listen(&chan, lame_routine);
391 if (sin) {
392 sprintf(ret, "%d", tcp_htons(sin->sin_port));
393 add_connect_to_list(chan, sin, NULL, CONNECT_RAW);
394 }
395 else strcpy(ret, "-1");
396}
397
398/* ---------------------------------------------------------------------- */
399static void built_fopenw(char *str, char *ret, int len)
400{
401 char *tmp;
402 tmp = next_arg(&str);
403 if (atoi(str))
404 sprintf(ret, "%d", open(tmp, O_WRONLY|O_CREAT|O_APPEND, 0700));
405 else
406 sprintf(ret, "%d", open(tmp, O_WRONLY|O_CREAT|O_TRUNC, 0700));
407}
408
409/* ---------------------------------------------------------------------- */
410static void built_fopenr(char *str, char *ret, int len)
411{
412 sprintf(ret, "%d", open(str, O_RDONLY, 0700));
413}
414
415/* ---------------------------------------------------------------------- */
416static void built_fclose(char *str, char *ret, int len)
417{
418 sprintf(ret, "%d", close(atoi(str)));
419}
420
421/* ---------------------------------------------------------------------- */
422static void built_fread(char *str, char *ret, int len)
423{
424 char *word;
425 int crlf;
426 word = next_arg(&str);
427 sprintf(ret, "%d", read(atoi(word), ret, 512));
428}
429
430/* ---------------------------------------------------------------------- */
431static void built_fwrite(char *str, char *ret, int len)
432{
433 char *word;
434 int crlf;
435 word = next_arg(&str);
436 crlf = atoi(next_arg(&str));
437 sprintf(ret, "%d", write(atoi(word), str, strlen(str)));
438 if (crlf) write(atoi(word), "\n", strlen("\n"));
439}
440
441/* ---------------------------------------------------------------------- */
442static void built_mychannels(char *str, char *ret, int len)
443{
444 win_ptr win;
445 server_ptr tsrv = gsrv;
446 if (*str) {
447 win = get_win_by_name(str);
448 if (win) tsrv = win->server;
449 else tsrv = NULL;
450 }
451 get_channels_from_server(tsrv, ret, len);
452}
453
454/* ---------------------------------------------------------------------- */
455static void built_currtime(char *str, char *ret, int len)
456{
457 real_time();
458 sprintf(ret, "%s", curr_time_s);
459}
460
461/* ---------------------------------------------------------------------- */
462static void built_logdcc(char *str, char *ret, int len)
463{
464 SIN *sin;
465 char *file, *send;
466 short chan;
467 int flags;
468 file = next_arg(&str);
469 send = next_arg(&str);
470 if (atoi(send)) flags = DCC_SEND|DCC_FILE;
471 else flags = DCC_GET|DCC_FILE;
472 sin = dcc_bind(&chan);
473 if (sin)
474 if (logdcc_request(0, 0, "FTP", file, flags, sin, chan))
475 sprintf(ret, "%d", tcp_htons(sin->sin_port));
476 else strcpy(ret, "0");
477 else strcpy(ret, "0");
478}
479
480/* ---------------------------------------------------------------------- */
481static void built_getalias(char *str, char *ret, int len)
482{
483 char *exp = get_alias_text(str, TRUE);
484 if (!exp) *ret = 0;
485 else {
486 strncpy(ret, exp, len-1);
487 ret[len-1] = 0;
488 }
489}
490
491/* ---------------------------------------------------------------------- */
492static void built_menu_choice(char *str, char *ret, int len)
493{
494 int num_words, ind, ret_ind = -1, loop;
495 char **word_list;
496 num_words = word_count(str);
497 word_list = (char **)mymalloc(num_words * sizeof(char *));
498 if (word_list)
499 {
500 for (loop=0; loop<num_words; loop++)
501 word_list[loop] = next_arg(&str);
502 ret_ind = get_menu_choice(num_words, word_list);
503 }
504 sprintf(ret, "%d", ret_ind);
505}
506/* ---------------------------------------------------------------------- */
507static void built_winnum(char *str, char *ret, int len)
508{
509 sl_window2(get_curr_win(), ret);
510}
511/* ---------------------------------------------------------------------- */
512static void built_cwd(char *str, char *ret, int len)
513{
514 char werd[512];
515 int status, mlen, prefix, context = 0;
516 struct dsc$descriptor_s old_d, new_d;
517 new_d.dsc$b_dtype = old_d.dsc$b_dtype = DSC$K_DTYPE_T;
518 new_d.dsc$b_class = old_d.dsc$b_class = DSC$K_CLASS_S;
519 if (str && *str)
520 {
521 new_d.dsc$w_length = sizeof(werd);
522 new_d.dsc$a_pointer = werd;
523 old_d.dsc$w_length = strlen(str);
524 old_d.dsc$a_pointer = str;
525 status = lib$find_file(&old_d, &new_d, &context);
526
527 str = strrchr(werd, ']');
528 if (!str) str = strrchr(werd, '>');
529 if (str) str[1] = 0;
530
531 str = strchr(werd, ' ');
532 if (str) *str = 0;
533
534 str = strchr(werd, ':');
535 if (str) *str++ = 0;
536 if (str)
537 {
538 new_d.dsc$a_pointer = werd;
539 new_d.dsc$w_length = strlen(werd);
540 lib$set_logical("SYS$DISK", &new_d);
541 new_d.dsc$a_pointer = str;
542 new_d.dsc$w_length = strlen(str);
543 status = sys$setddir(&new_d, NULL, NULL);
544 }
545 }
546 get_logical("SYS$DISK", ret, FALSE);
547 prefix = strlen(ret);
548 len -= prefix;
549 old_d.dsc$w_length = len;
550 old_d.dsc$a_pointer = &ret[strlen(ret)];
551 status = sys$setddir(0, &len, &old_d);
552 if (status & 1)
553 ret[len+prefix] = 0;
554 else
555 strcpy(ret, "ERROR");
556}
557/* ---------------------------------------------------------------------- */
558static struct command_node2 in_functions[] =
559{
560 {{"ALIAS"}, built_getalias},
561 {{"CONNECT"}, built_connect},
562 {{"CONNECT_START"}, built_connect_start},
563 {{"CURRTIME"}, built_currtime},
564 {{"CWD"}, built_cwd},
565 {{"DECODE"}, built_decode},
566 {{"ENCODE"}, built_encode},
567 {{"FCLOSE"}, built_fclose},
568 {{"FOPEN_READ"}, built_fopenr},
569 {{"FOPEN_WRITE"}, built_fopenw},
570 {{"FREAD"}, built_fread},
571 {{"FWRITE"}, built_fwrite},
572 {{"INDEX"}, built_index},
573 {{"IP"}, built_ip},
574 {{"ISCHANNEL"}, built_ischannel},
575 {{"ISCHANOP"}, built_ischanop},
576 {{"LEFT"}, built_left},
577 {{"LISTEN"}, built_listen},
578 {{"LOGDCC"}, built_logdcc},
579 {{"MATCH"}, built_match},
580/* {{"MENU_CHOICE"}, built_menu_choice}, */
581 {{"MID"}, built_mid},
582 {{"MYCHANNELS"}, built_mychannels},
583 {{"RAND"}, built_rand},
584 {{"RIGHT"}, built_right},
585 {{"RINDEX"}, built_rindex},
586 {{"RMATCH"}, built_rmatch},
587 {{"SRAND"}, built_srand},
588 {{"STIME"}, built_stime},
589 {{"STRIP"}, built_strip},
590 {{"TDIFF"}, built_tdiff},
591 {{"TIME"}, built_time},
592 {{"TOLOWER"}, built_tolower},
593 {{"TOUPPER"}, built_toupper},
594 {{"USERHOST"}, built_userhost},
595/*
596 {{"WINNAME"}, built_winname},
597*/
598 {{"WINNUM"}, built_winnum},
599 {{"WORD"}, built_word},
600 {{"WRITE"}, built_write},
601 {{NULL}, NULL}
602};
603
604/* ------------------------------------------------------------------------ */
605int is_builtin(char *func, char *args, char *ret, int len)
606{
607 char dummy[MAXLEN];
608 int ddd,indx;
609 ddd = lookup_command((command_node *)in_functions, func, &indx);
610 if (ddd<0) return 0;
611 (in_functions[ddd].routine)(args, ret, len);
612 return 1;
613}
614/* ------------------------------------------------------------------------ */