|
|
1.1 root 1: /* imiscd.c - miscellaneous network service -- responder */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/imisc/RCS/imiscd.c,v 7.2 90/07/09 14:38:48 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/imisc/RCS/imiscd.c,v 7.2 90/07/09 14:38:48 mrose Exp $
9: *
10: *
11: * $Log: imiscd.c,v $
12: * Revision 7.2 90/07/09 14:38:48 mrose
13: * sync
14: *
15: * Revision 7.1 90/07/01 21:04:05 mrose
16: * pepsy
17: *
18: * Revision 7.0 89/11/23 21:57:39 mrose
19: * Release 6.0
20: *
21: */
22:
23: /*
24: * NOTICE
25: *
26: * Acquisition, use, and distribution of this module and related
27: * materials are subject to the restrictions of a license agreement.
28: * Consult the Preface in the User's Manual for the full terms of
29: * this agreement.
30: *
31: */
32:
33:
34: #include <ctype.h>
35: #include <stdio.h>
36: #include "IMISC-types.h" /* IMISC type definitions */
37: #include "ryresponder.h" /* for generic idempotent responders */
38: #include "IMISC-ops.h" /* IMISC operation definitions */
39: #include <utmp.h>
40: #ifdef SYS5
41: #include <sys/times.h>
42: #endif
43: #include <sys/stat.h>
44:
45: /* DATA */
46:
47: static char *myservice = "isode miscellany"; /* should be something else */
48:
49: static int execuid = 1;
50: static int execgid = 1;
51:
52:
53: /* OPERATIONS */
54: int op_utcTime (), op_genTime (), op_timeOfDay (), op_users (),
55: op_charGen (), op_pwdGen (), op_exec (), op_tellUser (), op_data ();
56:
57: static struct dispatch dispatches[] = {
58: "utcTime", operation_IMISC_utcTime, op_utcTime,
59:
60: "genTime", operation_IMISC_genTime, op_genTime,
61:
62: "timeOfDay", operation_IMISC_timeOfDay, op_timeOfDay,
63:
64: "users", operation_IMISC_users, op_users,
65:
66: "chargen", operation_IMISC_charGen, op_charGen,
67:
68: "pwdGen", operation_IMISC_pwdGen, op_pwdGen,
69:
70: "qotd", operation_IMISC_qotd, op_exec,
71:
72: "finger", operation_IMISC_finger, op_exec,
73:
74: "tellUser", operation_IMISC_tellUser, op_tellUser,
75:
76: "ping", operation_IMISC_ping, op_data,
77:
78: "sink", operation_IMISC_sink, op_data,
79:
80: "echo", operation_IMISC_echo, op_data,
81:
82: NULL
83: };
84:
85:
86: /* TYPES */
87: struct type_IMISC_IA5List *str2ia5list ();
88:
89:
90: extern int errno;
91:
92:
93: long time ();
94: char *ctime ();
95:
96: /* MAIN */
97:
98: /* ARGSUSED */
99:
100: main (argc, argv, envp)
101: int argc;
102: char **argv,
103: **envp;
104: {
105: ryresponder (argc, argv, PLocalHostName (), myservice, NULLCP,
106: dispatches, table_IMISC_Operations, NULLIFP, NULLIFP);
107:
108: exit (0); /* NOTREACHED */
109: }
110:
111: /* OPERATIONS */
112:
113: /* ARGSUSED */
114:
115: static int op_utcTime (sd, ryo, rox, in, roi)
116: int sd;
117: struct RyOperation *ryo;
118: struct RoSAPinvoke *rox;
119: caddr_t in;
120: struct RoSAPindication *roi;
121: {
122: long clock;
123: char *cp;
124: register struct tm *tm;
125: struct UTCtime uts;
126: register struct UTCtime *ut = &uts;
127: register struct type_IMISC_UTCResult *ur;
128:
129: if (rox -> rox_nolinked == 0) {
130: advise (LLOG_EXCEPTIONS, NULLCP,
131: "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
132: sd, ryo -> ryo_name, rox -> rox_linkid);
133: return ureject (sd, ROS_IP_LINKED, rox, roi);
134: }
135: advise (LLOG_NOTICE, NULLCP, "RO-INVOKE.INDICATION/%d: %s",
136: sd, ryo -> ryo_name);
137:
138: if (time (&clock) == NOTOK || (tm = gmtime (&clock)) == NULL)
139: return error (sd, error_IMISC_unableToDetermineTime, (caddr_t) NULL,
140: rox, roi);
141:
142: tm2ut (tm, ut);
143:
144: if ((cp = utct2str (ut)) == NULLCP
145: || (ur = str2qb (cp, strlen (cp), 1)) == NULL)
146: return error (sd, error_IMISC_congested, (caddr_t) NULL, rox, roi);
147:
148: if (RyDsResult (sd, rox -> rox_id, (caddr_t) ur, ROS_NOPRIO, roi) == NOTOK)
149: ros_adios (&roi -> roi_preject, "RESULT");
150:
151: free_IMISC_UTCResult (ur);
152:
153: return OK;
154: }
155:
156: /* */
157:
158: /* ARGSUSED */
159:
160: static int op_genTime (sd, ryo, rox, in, roi)
161: int sd;
162: struct RyOperation *ryo;
163: struct RoSAPinvoke *rox;
164: caddr_t in;
165: struct RoSAPindication *roi;
166: {
167: long clock;
168: char *cp;
169: #if defined(BSD42) || defined (HPUX)
170: struct timeval tvs;
171: #endif
172: register struct tm *tm;
173: struct UTCtime uts;
174: register struct UTCtime *ut = &uts;
175: register struct type_IMISC_GenResult *gr;
176:
177: if (rox -> rox_nolinked == 0) {
178: advise (LLOG_EXCEPTIONS, NULLCP,
179: "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
180: sd, ryo -> ryo_name, rox -> rox_linkid);
181: return ureject (sd, ROS_IP_LINKED, rox, roi);
182: }
183: advise (LLOG_NOTICE, NULLCP, "RO-INVOKE.INDICATION/%d: %s",
184: sd, ryo -> ryo_name);
185:
186: #if defined(BSD42) || defined (HPUX)
187: if (gettimeofday (&tvs, (struct timezone *) 0) == NOTOK)
188: return error (sd, error_IMISC_unableToDetermineTime, (caddr_t) NULL,
189: rox, roi);
190: clock = tvs.tv_sec;
191: #else
192: if (time (&clock) == NOTOK)
193: return error (sd, error_IMISC_unableToDetermineTime, (caddr_t) NULL,
194: rox, roi);
195: #endif
196: if ((tm = gmtime (&clock)) == NULL)
197: return error (sd, error_IMISC_unableToDetermineTime, (caddr_t) NULL,
198: rox, roi);
199: tm2ut (tm, ut);
200: #ifdef BSD42
201: ut -> ut_flags |= UT_USEC;
202: ut -> ut_usec = tvs.tv_usec;
203: #endif
204:
205: if ((cp = gent2str (ut)) == NULLCP
206: || (gr = str2qb (cp, strlen (cp), 1)) == NULL)
207: return error (sd, error_IMISC_congested, (caddr_t) NULL, rox, roi);
208:
209: if (RyDsResult (sd, rox -> rox_id, (caddr_t) gr, ROS_NOPRIO, roi) == NOTOK)
210: ros_adios (&roi -> roi_preject, "RESULT");
211:
212: free_IMISC_GenResult (gr);
213:
214: return OK;
215: }
216:
217: /* */
218:
219: /* Return the number of seconds since 00:00 (midnight) 1 January 1900 GMT */
220:
221: /* ARGSUSED */
222:
223: static int op_timeOfDay (sd, ryo, rox, in, roi)
224: int sd;
225: struct RyOperation *ryo;
226: struct RoSAPinvoke *rox;
227: caddr_t in;
228: struct RoSAPindication *roi;
229: {
230: long clock;
231: struct type_IMISC_TimeResult trs;
232: register struct type_IMISC_TimeResult *tr = &trs;
233:
234: if (rox -> rox_nolinked == 0) {
235: advise (LLOG_EXCEPTIONS, NULLCP,
236: "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
237: sd, ryo -> ryo_name, rox -> rox_linkid);
238: return ureject (sd, ROS_IP_LINKED, rox, roi);
239: }
240: advise (LLOG_NOTICE, NULLCP, "RO-INVOKE.INDICATION/%d: %s",
241: sd, ryo -> ryo_name);
242:
243: if (time (&clock) == NOTOK)
244: return error (sd, error_IMISC_unableToDetermineTime, (caddr_t) NULL,
245: rox, roi);
246: tr -> parm = clock + 2208988800;
247:
248: if (RyDsResult (sd, rox -> rox_id, (caddr_t) tr, ROS_NOPRIO, roi) == NOTOK)
249: ros_adios (&roi -> roi_preject, "RESULT");
250:
251: return OK;
252: }
253:
254: /* */
255:
256: #ifdef sun
257: #define BSD42
258: #undef SYS5
259: #endif
260:
261: #ifdef bsd43_ut_host
262: #undef BSD42
263: #define SYS5
264: #endif
265:
266: #ifdef BSD42
267: #define HMAX (sizeof (ut -> ut_host))
268: #endif
269: #define LMAX (sizeof (ut -> ut_line))
270: #define NMAX (sizeof (ut -> ut_name))
271:
272: #ifdef SYS5
273: struct utmp *getutent ();
274: #endif
275:
276:
277: /* ARGSUSED */
278:
279: static int op_users (sd, ryo, rox, in, roi)
280: int sd;
281: struct RyOperation *ryo;
282: struct RoSAPinvoke *rox;
283: caddr_t in;
284: struct RoSAPindication *roi;
285: {
286: #ifndef SYS5
287: int ud;
288: #endif
289: register char *dp;
290: char buffer[BUFSIZ];
291: struct utmp uts;
292: register struct utmp *ut = &uts;
293: struct type_IMISC_IA5List *ia5;
294: register struct type_IMISC_IA5List **ia5p;
295:
296: if (rox -> rox_nolinked == 0) {
297: advise (LLOG_EXCEPTIONS, NULLCP,
298: "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
299: sd, ryo -> ryo_name, rox -> rox_linkid);
300: return ureject (sd, ROS_IP_LINKED, rox, roi);
301: }
302: advise (LLOG_NOTICE, NULLCP, "RO-INVOKE.INDICATION/%d: %s",
303: sd, ryo -> ryo_name);
304:
305: ia5 = NULL;
306: ia5p = &ia5;
307:
308: #ifndef SYS5
309: if ((ud = open ("/etc/utmp", 0)) == NOTOK) {
310: int result;
311:
312: (void) sprintf (buffer, "/etc/utmp: %s", sys_errname (errno));
313: if ((*ia5p = str2ia5list (buffer)) == NULL)
314: goto congested;
315: ia5p = &((*ia5p) -> next);
316:
317: result = error (sd, error_IMISC_unableToOpenFile, (caddr_t) ia5, rox,
318: roi);
319:
320: free_IMISC_IA5List (ia5);
321:
322: return result;
323: }
324:
325: while (read (ud, (char *) ut, sizeof *ut) == sizeof *ut) {
326: if (ut -> ut_name[0] == NULL)
327: continue;
328: if ((dp = ctime (&ut -> ut_time)) == NULL)
329: goto congested;
330: (void) sprintf (buffer, "%-*.*s %-*.*s %.12s",
331: NMAX, NMAX, ut -> ut_name, LMAX, LMAX, ut -> ut_line, dp + 4);
332: #ifdef BSD42
333: if (ut -> ut_host[0])
334: (void) sprintf (buffer + strlen (buffer), "\t(%.*s)",
335: HMAX, ut -> ut_host);
336: #endif
337:
338: if ((*ia5p = str2ia5list (buffer)) == NULL)
339: goto congested;
340: ia5p = &((*ia5p) -> next);
341: }
342: (void) close (ud);
343: #else
344: setutent ();
345: while (ut = getutent ()) {
346: if (ut -> ut_type != USER_PROCESS)
347: continue;
348: if ((dp = ctime (&ut -> ut_time)) == NULL)
349: goto congested;
350: (void) sprintf (buffer, "%-*.*s %-*.*s %.12s",
351: NMAX, NMAX, ut -> ut_name, LMAX, LMAX, ut -> ut_line,
352: dp + 4);
353:
354: if ((*ia5p = str2ia5list (buffer)) == NULL)
355: goto congested;
356: ia5p = &((*ia5p) -> next);
357: }
358: endutent ();
359: #endif
360:
361: if (RyDsResult (sd, rox -> rox_id, (caddr_t) ia5, ROS_NOPRIO, roi)
362: == NOTOK)
363: ros_adios (&roi -> roi_preject, "RESULT");
364: free_IMISC_IA5List (ia5);
365:
366: return OK;
367:
368: congested: ;
369: free_IMISC_IA5List (ia5);
370:
371: return error (sd, error_IMISC_congested, (caddr_t) NULL, rox, roi);
372: }
373:
374:
375: #ifdef bsd43_ut_host
376: #define BSD42
377: #undef SYS5
378: #endif
379:
380: /* */
381:
382: #define NBYTES 512
383: #define LINSIZ 72
384:
385:
386: /* ARGSUSED */
387:
388: static int op_charGen (sd, ryo, rox, in, roi)
389: int sd;
390: struct RyOperation *ryo;
391: struct RoSAPinvoke *rox;
392: caddr_t in;
393: struct RoSAPindication *roi;
394: {
395: register int i,
396: j;
397: register char *dp,
398: *de,
399: *rs,
400: *rp,
401: *re;
402: char line[LINSIZ + 1],
403: ring[BUFSIZ];
404: struct type_IMISC_IA5List *ia5;
405: register struct type_IMISC_IA5List **ia5p;
406:
407: if (rox -> rox_nolinked == 0) {
408: advise (LLOG_EXCEPTIONS, NULLCP,
409: "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
410: sd, ryo -> ryo_name, rox -> rox_linkid);
411: return ureject (sd, ROS_IP_LINKED, rox, roi);
412: }
413: advise (LLOG_NOTICE, NULLCP, "RO-INVOKE.INDICATION/%d: %s",
414: sd, ryo -> ryo_name);
415:
416: re = ring;
417: for (i = 0; i < 0x80; i++)
418: if (isprint (i))
419: *re++ = i;
420:
421: ia5 = NULL;
422: ia5p = &ia5;
423:
424: for (rs = ring, i = NBYTES; i > 0; rs++, i -= j) {
425: if (rs >= re)
426: rs = ring;
427: j = i > LINSIZ ? LINSIZ : i;
428: for (de = (dp = line) + j, rp = rs; dp < de; dp++, rp++) {
429: if (rp >= re)
430: rp = ring;
431: *dp = *rp;
432: }
433:
434: *dp = NULL;
435: if ((*ia5p = str2ia5list (line)) == NULL)
436: goto congested;
437: ia5p = &((*ia5p) -> next);
438: }
439:
440: if (RyDsResult (sd, rox -> rox_id, (caddr_t) ia5, ROS_NOPRIO, roi)
441: == NOTOK)
442: ros_adios (&roi -> roi_preject, "RESULT");
443: free_IMISC_IA5List (ia5);
444:
445: return OK;
446:
447: congested: ;
448: free_IMISC_IA5List (ia5);
449:
450: return error (sd, error_IMISC_congested, (caddr_t) NULL, rox, roi);
451: }
452:
453: /* */
454:
455: #define NPASS 6
456:
457:
458: /* ARGSUSED */
459:
460: static int op_pwdGen (sd, ryo, rox, in, roi)
461: int sd;
462: struct RyOperation *ryo;
463: struct RoSAPinvoke *rox;
464: caddr_t in;
465: struct RoSAPindication *roi;
466: {
467: register int i;
468: char buffer[BUFSIZ];
469: struct type_IMISC_IA5List *ia5;
470: register struct type_IMISC_IA5List **ia5p;
471:
472: if (rox -> rox_nolinked == 0) {
473: advise (LLOG_EXCEPTIONS, NULLCP,
474: "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
475: sd, ryo -> ryo_name, rox -> rox_linkid);
476: return ureject (sd, ROS_IP_LINKED, rox, roi);
477: }
478: advise (LLOG_NOTICE, NULLCP, "RO-INVOKE.INDICATION/%d: %s",
479: sd, ryo -> ryo_name);
480:
481: ia5 = NULL;
482: ia5p = &ia5;
483:
484: for (i = NPASS; i > 0; i--) {
485: if (pwdgen (buffer) == NOTOK)
486: goto congested;
487:
488: if ((*ia5p = str2ia5list (buffer)) == NULL)
489: goto congested;
490: ia5p = &((*ia5p) -> next);
491: }
492:
493: if (RyDsResult (sd, rox -> rox_id, (caddr_t) ia5, ROS_NOPRIO, roi)
494: == NOTOK)
495: ros_adios (&roi -> roi_preject, "RESULT");
496: free_IMISC_IA5List (ia5);
497:
498: return OK;
499:
500: congested: ;
501: free_IMISC_IA5List (ia5);
502:
503: return error (sd, error_IMISC_congested, (caddr_t) NULL, rox, roi);
504: }
505:
506: /* */
507:
508: /* Based on an f77 algorithm supplied by Frank Wancho <Wancho@SIMTEL20>,
509: which was based on a basic algorithm by Paul D. Merillat and Arthur A. Key.
510:
511: Strings returned are built by alternating vowels and consonants.
512: However, there are "Digraphs", and these are presorted according to
513: END, MIDDLE, and START positions.
514:
515: Not going into combinatorial analysis (with 7 characters the "possible"
516: combinations exceed 20 million).
517: */
518:
519:
520: #define TOT 54636577
521:
522: static struct pair {
523: char *p_form;
524: int p_value;
525: } pairs[] = {
526: "cvcvcvce", 0,
527: "vcvcvcvc", 10827189,
528: "cpcpce", 13725209,
529: "dvcpce", 14036249,
530: "vcvcpce", 14327369,
531: "cvcpme", 15296369,
532: "dvcvcvc", 15746954,
533: "cpcvcvc", 16617618,
534: "cvmvcvc", 17547858,
535: "cvcpcvc", 23616474,
536: "cvcvmvc", 24546714,
537: "dpcvce", 30618378,
538: "dvmvce", 30908898,
539: "cpmvce", 32807107,
540: "vmvcvce", 34838173,
541: "vcpcvce", 41163763,
542: "vcvmvce", 42132163,
543: "vmvmvc", 48449078,
544: "vmpcvc", 51995642,
545: "vmvcpc", 52539386,
546: "vcvmpc", 52962661,
547: "vmpme", 53385611,
548: "dvmpc", 53648987,
549: "cpmpc", 53776002,
550: "cvcvcpc", 53912072,
551:
552: NULL, TOT
553: };
554:
555:
556: static char *Mx;
557: static char *Nx = /* XXX */
558: "BBBCBFBKBLBMBNBPBTBVCCCDCFCMCPDBDCDDDFDGDKDLDMDNDPDTDVDWDZFBFCFDFGFKFMFNF\
559: PFZGBGDGFGJGMGNGPGTGVKBKDKFKMKNKPKTKVKZLBLCLFLGLMLNLRLVLZMBMCMDMFMGMJMKMLMMMNM\
560: RMTMVMZNBNCNFNOSZTBTCTDTFTGTJTKTLTMTNTPTVVCVGVLVPNJNLNPNRPCPDPFPGPKPMPNPVPZRBR\
561: CRDRFRGRJRLSBSDSFSGSJSRSV";
562:
563: static char *Cx = /* consonants */
564: "BCDFGHJKLMNPRSTVWZ";
565:
566: static char *Vx = /* vowels */
567: "AEIOU";
568:
569: static char *Dx = /* consonant pairs */
570: "BRCHCLCRDRFLFRGLGRKLKRPHPLPRQUSCSHSKSLSMSNSPSTSWTHTRTW";
571:
572: static char *Lx = /* end-consonant pairs */
573: "BSCKCSCTDSFSFTGSHSKSLLLDLKLPLSLTMPMSNDNKNNNSNTPPPSPTRKRMRNRPRSSSTSVSWS";
574:
575: static char *Px = /* vowel pairs */
576: "AIEAEEIEIOOIOOOU";
577:
578: static char *Ex = /* end-vowels */
579: "EOAY";
580:
581: static char *Zx = /* end-vowel pairs */
582: "EEOOAYEYOY";
583:
584: static struct web {
585: char w_key;
586: int w_length;
587: int w_factor;
588: char **w_string;
589: char *w_special;
590: } webs[] = {
591: 'm', 189, 2, &Mx, NULL,
592: 'c', 18, 1, &Cx, "HWJ",
593: 'v', 5, 1, &Vx, NULL,
594: 'd', 27, 2, &Dx, NULL,
595: 'l', 35, 2, &Lx, NULL,
596: 'p', 8, 2, &Px, NULL,
597: 'e', 4, 1, &Ex, NULL,
598: 'z', 5, 2, &Zx, NULL,
599:
600: NULL, 0, 0, NULL, NULL
601: };
602:
603: /* */
604:
605: #define ifix(f) ((int) ((float) (f) + 0.5))
606: #ifndef SYS5
607: #define nrand() (((float) (random ()) / (float) 2147483647))
608:
609: long random ();
610: #else
611: #define nrand() (((float) (rand ()) / (float) 2147483647))
612:
613: int rand (), srand ();
614: #endif
615: #define rng(a,b) if (((i = ifix (a * nrand ()) * b) ? i -= b : i) < 0 \
616: || i >= a * b + (1 - b)) \
617: return NOTOK;
618:
619:
620: static int pwdgen (pw)
621: char *pw;
622: {
623: register int i,
624: j;
625: register char c,
626: *f,
627: *s;
628: register struct pair *pair;
629: register struct web *web;
630: static int latch = 0;
631:
632: if (!latch) {
633: if ((Mx = malloc
634: (((unsigned) (strlen (Dx) + strlen (Lx) + strlen (Nx)))))
635: == NULL)
636: return NOTOK;
637: (void) strcpy (s = Mx, Dx);
638: s += strlen (s);
639: (void) strcpy (s, Lx);
640: s += strlen (s);
641: (void) strcpy (s, Nx);
642: s += strlen (s);
643:
644: #ifndef SYS5
645: (void) srandom ((int) time ((long *) 0));
646: #else
647: (void) srand ((unsigned int) time ((long *) 0));
648: #endif
649:
650: latch++;
651: }
652:
653: rng (TOT, 1.0);
654: for (pair = pairs; pair -> p_form; pair++)
655: if (pair -> p_value < i)
656: f = pair -> p_form;
657: else
658: break;
659:
660: do {
661: for (s = pw; c = *f++;) {
662: for (web = webs; web -> w_key != c; web++)
663: if (web -> w_key == c)
664: break;
665: if (!web -> w_key)
666: return NOTOK;
667:
668: rng (web -> w_length, web -> w_factor);
669:
670: for (j = web -> w_factor; j > 0; j--)
671: *s++ = (*web -> w_string)[i++];
672: if (web -> w_special && *f == NULL) {
673: s--, i--;
674: while (index (web -> w_special, *s))
675: *s = (*web -> w_string)[--i];
676: s++;
677: }
678: }
679:
680: *s = NULL;
681: } while (object (pw));
682:
683: return OK;
684: }
685:
686: /* */
687:
688: static struct obj {
689: char *o_string;
690: int o_advance;
691: } objects[] = {
692: "TRAFLLEHPARCTIHS", 4,
693: "SIPSSATITDOGCUFKUF", 3,
694:
695: NULL, 0
696: };
697:
698:
699: static int object (pw)
700: register char *pw;
701: {
702: register int n;
703: register char *f,
704: *s;
705: char buffer[BUFSIZ];
706: register struct obj *o;
707:
708: for (f = buffer + strlen (s = pw), *f = NULL; *s; s++)
709: *--f = *s;
710:
711: for (o = objects; s = o -> o_string; o++)
712: for (n = o -> o_advance; *s; s += n)
713: if (strncmp (f, s, n) == 0)
714: return NOTOK;
715:
716: return OK;
717: }
718:
719: /* */
720:
721: #ifndef FORTUNE
722: #define FORTUNE "/usr/games/fortune"
723: #endif
724: #ifndef RFINGER
725: #ifndef SYS5
726: #define RFINGER "/usr/ucb/finger"
727: #else
728: #define RFINGER "/usr/bin/finger"
729: #endif
730: #endif
731:
732:
733: static int op_exec (sd, ryo, rox, in, roi)
734: int sd;
735: struct RyOperation *ryo;
736: struct RoSAPinvoke *rox;
737: caddr_t in;
738: struct RoSAPindication *roi;
739: {
740: int fd,
741: i,
742: result,
743: vecp,
744: vecq,
745: pd[2];
746: register char *bp,
747: *dp;
748: char buffer[BUFSIZ],
749: data[BUFSIZ],
750: *pgm,
751: *vec[NVEC + 1];
752: struct type_IMISC_IA5List *ia5;
753: register struct type_IMISC_IA5List **ia5p;
754:
755: vecp = vecq = 0;
756: if (rox -> rox_nolinked == 0) {
757: advise (LLOG_EXCEPTIONS, NULLCP,
758: "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
759: sd, ryo -> ryo_name, rox -> rox_linkid);
760: result = ureject (sd, ROS_IP_LINKED, rox, roi);
761: goto out;
762: }
763: advise (LLOG_NOTICE, NULLCP, "RO-INVOKE.INDICATION/%d: %s",
764: sd, ryo -> ryo_name);
765:
766: if (ryo -> ryo_op == operation_IMISC_qotd) {
767: vec[vecp++] = pgm = FORTUNE;
768: vecq = vecp;
769: }
770: else {
771: vec[vecp++] = pgm = RFINGER;
772: #ifdef RFOPT1
773: vec[vecp++] = RFOPT1;
774: #endif
775: #ifdef RFOPT2
776: vec[vecp++] = RFOPT2;
777: #endif
778: vecq = vecp;
779: for (ia5 = (struct type_IMISC_IA5List *) in; ia5; ia5 = ia5 -> next)
780: if (vecp >= NVEC
781: || (vec[vecp++] = qb2str (ia5 -> IA5String)) == NULLCP) {
782: result = error (sd, error_IMISC_congested, (caddr_t) NULL, rox,
783: roi);
784: goto out;
785: }
786: }
787: vec[vecp] = NULLCP;
788:
789: ia5 = NULL;
790: ia5p = &ia5;
791:
792: if (access (pgm, 1) == NOTOK) {
793: result = error_IMISC_unableToAccessFile;
794:
795: oops: ;
796: free_IMISC_IA5List (ia5);
797: ia5 = NULL;
798: ia5p = &ia5;
799:
800: (void) sprintf (buffer, "%s: %s", pgm, sys_errname (errno));
801: if ((*ia5p = str2ia5list (buffer)) == NULL)
802: goto congested;
803: ia5p = &((*ia5p) -> next);
804:
805: result = error (sd, result, (caddr_t) ia5, rox, roi);
806:
807: free_IMISC_IA5List (ia5);
808:
809: goto out;
810: }
811: if (pipe (pd) == NOTOK) {
812: result = error_IMISC_unableToPipe;
813: goto oops;
814: }
815:
816: switch (vfork ()) {
817: case NOTOK:
818: (void) close (pd[0]);
819: (void) close (pd[1]);
820: result = error_IMISC_unableToFork;
821: goto oops;
822:
823: case OK:
824: if ((fd = open ("/dev/null", 2)) != NOTOK) {
825: if (fd != 0)
826: (void) dup2 (fd, 0), (void) close (fd);
827: }
828: (void) dup2 (pd[1], 1);
829: (void) dup2 (pd[1], 2);
830: (void) close (pd[0]);
831: (void) close (pd[1]);
832: if (execuid != 0) {
833: (void) setgid (execgid);
834: (void) setuid (execuid);
835: }
836: execvp (pgm, vec);
837: _exit (1);
838:
839: default:
840: (void) close (pd[1]);
841: for (vecp = vecq; bp = vec[vecp]; vecp++) {
842: free (bp);
843: vec[vecp] = NULL;
844: }
845:
846: for (; vecq < vecp; vecq++)
847: if (bp = vec[vecq])
848: free (bp);
849: for (dp = data;;)
850: switch (i = read (pd[0], buffer, sizeof buffer)) {
851: case NOTOK:
852: i = errno;
853: (void) close (pd[0]);
854: errno = i;
855: result = error_IMISC_errorReading;
856: goto oops;
857:
858: case OK:
859: (void) close (pd[0]);
860: if (dp != data) {
861: *dp = NULL;
862: if ((*ia5p = str2ia5list (data)) == NULL)
863: goto congested;
864: ia5p = &((*ia5p) -> next);
865: }
866: if (RyDsResult (sd, rox -> rox_id, (caddr_t) ia5,
867: ROS_NOPRIO, roi) == NOTOK)
868: ros_adios (&roi -> roi_preject, "RESULT");
869: free_IMISC_IA5List (ia5);
870: result = OK;
871: goto out;
872:
873: default:
874: for (bp = buffer; i > 0; bp++, i--)
875: switch (*bp) {
876: case '\n':
877: *dp = NULL;
878: if ((*ia5p = str2ia5list (data)) == NULL)
879: goto congested;
880: ia5p = &((*ia5p) -> next);
881: dp = data;
882: break;
883:
884: case NULL:
885: break;
886:
887: default:
888: *dp++ = *bp;
889: break;
890: }
891: continue;
892: }
893: }
894:
895: congested: ;
896: free_IMISC_IA5List (ia5);
897: result = error (sd, error_IMISC_congested, (caddr_t) NULL, rox, roi);
898:
899: out: ;
900: for (vecp = vecq; bp = vec[vecp]; vecp++)
901: free (bp);
902:
903: return result;
904: }
905:
906: /* */
907:
908: /* ARGSUSED */
909:
910: static int op_tellUser (sd, ryo, rox, in, roi)
911: int sd;
912: struct RyOperation *ryo;
913: struct RoSAPinvoke *rox;
914: caddr_t in;
915: struct RoSAPindication *roi;
916: {
917: #ifndef SYS5
918: int ud;
919: #endif
920: int hit,
921: result,
922: vecp;
923: char *bp,
924: *fromuser,
925: *touser,
926: buffer[BUFSIZ],
927: **vec,
928: *vecl[NVEC + 1];
929: struct utmp uts;
930: register struct utmp *ut = &uts;
931: struct type_IMISC_IA5List *ia5;
932:
933: vecp = 0;
934: if (rox -> rox_nolinked == 0) {
935: advise (LLOG_EXCEPTIONS, NULLCP,
936: "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
937: sd, ryo -> ryo_name, rox -> rox_linkid);
938: result = ureject (sd, ROS_IP_LINKED, rox, roi);
939: goto out;
940: }
941: advise (LLOG_NOTICE, NULLCP, "RO-INVOKE.INDICATION/%d: %s",
942: sd, ryo -> ryo_name);
943:
944: for (ia5 = (struct type_IMISC_IA5List *) in; ia5; ia5 = ia5 -> next)
945: if (vecp >= NVEC
946: || (vecl[vecp++] = qb2str (ia5 -> IA5String)) == NULLCP)
947: goto congested;
948: vecl[vecp] = NULLCP;
949:
950: if (vecp < 3) {
951: advise (LLOG_EXCEPTIONS, NULLCP,
952: "too few arguments (got %d, wanted at least 3)", vecp);
953: result = ureject (sd, ROS_IP_MISTYPED, rox, roi);
954: goto out;
955: }
956: fromuser = vecl[0];
957: touser = vecl[1];
958: vec = &vecl[2], vecp -= 2;
959:
960: hit = 0;
961: result = error_IMISC_userNotLoggedIn;
962: #ifndef SYS5
963: if ((ud = open ("/etc/utmp", 0)) == NOTOK) {
964: (void) sprintf (buffer, "/etc/utmp: %s", sys_errname (errno));
965: if ((ia5 = str2ia5list (buffer)) == NULL)
966: goto congested;
967:
968: result = error (sd, error_IMISC_unableToOpenFile, (caddr_t) ia5, rox,
969: roi);
970:
971: free_IMISC_IA5List (ia5);
972:
973: goto out;
974: }
975:
976: while (read (ud, (char *) ut, sizeof *ut) == sizeof *ut) {
977: if (ut -> ut_name[0] == NULL)
978: continue;
979: if (strncmp (ut -> ut_name, touser, sizeof ut -> ut_name) == 0)
980: if (do_the_tell (ut, fromuser, vec, vecp) != NOTOK)
981: hit++;
982: else
983: result = error_IMISC_unableToOpenFile;
984: }
985: (void) close (ud);
986: #else
987: setutent ();
988: while (ut = getutent ()) {
989: if (ut -> ut_type != USER_PROCESS)
990: continue;
991: if (strncmp (ut -> ut_name, touser, sizeof ut -> ut_name) == 0)
992: if (do_the_tell (ut, fromuser, vec, vecp) != NOTOK)
993: hit++;
994: else
995: result = error_IMISC_unableToOpenFile;
996: }
997: endutent ();
998: #endif
999: if (hit == 0) {
1000: result = error (sd, result, (caddr_t) NULL, rox, roi);
1001: goto out;
1002: }
1003:
1004: if (RyDsResult (sd, rox -> rox_id, (caddr_t) NULL, ROS_NOPRIO, roi)
1005: == NOTOK)
1006: ros_adios (&roi -> roi_preject, "RESULT");
1007:
1008: result = OK;
1009: goto out;
1010:
1011: congested: ;
1012: result = error (sd, error_IMISC_congested, (caddr_t) NULL, rox, roi);
1013:
1014: out: ;
1015: for (vecp = 0; bp = vecl[vecp]; vecp++)
1016: free (bp);
1017:
1018: return result;
1019: }
1020:
1021: /* */
1022:
1023: static int do_the_tell (ut, from, vec, vecp)
1024: struct utmp *ut;
1025: char *from;
1026: char *vec[];
1027: int vecp;
1028: {
1029: int i,
1030: pid;
1031: char *bp,
1032: tty[5 + LMAX + 1];
1033: struct stat st;
1034: FILE *fp;
1035:
1036: (void) strcpy (bp = tty, "/dev/");
1037: bp += strlen (bp);
1038: (void) strncpy (bp, ut -> ut_line, LMAX);
1039: bp += LMAX;
1040: *bp = NULL;
1041: if (stat (tty, &st) == NOTOK
1042: || (st.st_mode & (S_IWRITE >> 3)) != (S_IWRITE >> 3))
1043: return NOTOK;
1044:
1045: for (i = 0; i < 5; i++) {
1046: switch (pid = fork ()) {
1047: case NOTOK:
1048: continue;
1049:
1050: case 0:
1051: break;
1052:
1053: default:
1054: return OK;
1055: }
1056: break;
1057: }
1058: if (pid == NOTOK)
1059: return NOTOK;
1060: if ((fp = fopen (tty, "w")) == NULL)
1061: _exit (1);
1062: fprintf (fp, "\r\nmessage from %s:\r\n\007", from);
1063: for (i = 0, bp = NULL; i < vecp; i++, bp = " ") {
1064: if (bp)
1065: fputs (bp, fp);
1066: fputs (vec[i], fp);
1067: }
1068: fputs ("\r\n", fp);
1069: (void) fclose (fp);
1070: _exit (0); /* NOTREACHED */
1071: }
1072:
1073: /* */
1074:
1075: static int op_data (sd, ryo, rox, in, roi)
1076: int sd;
1077: struct RyOperation *ryo;
1078: struct RoSAPinvoke *rox;
1079: caddr_t in;
1080: struct RoSAPindication *roi;
1081: {
1082: if (rox -> rox_nolinked == 0) {
1083: advise (LLOG_EXCEPTIONS, NULLCP,
1084: "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
1085: sd, ryo -> ryo_name, rox -> rox_linkid);
1086: return ureject (sd, ROS_IP_LINKED, rox, roi);
1087: }
1088: if (debug)
1089: advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s",
1090: sd, ryo -> ryo_name);
1091:
1092: if (RyDsResult (sd, rox -> rox_id, ryo -> ryo_op == operation_IMISC_echo
1093: ? in : (caddr_t) NULL, ROS_NOPRIO, roi) == NOTOK)
1094: ros_adios (&roi -> roi_preject, "RESULT");
1095:
1096: return OK;
1097: }
1098:
1099: /* ERROR */
1100:
1101: static int error (sd, err, param, rox, roi)
1102: int sd,
1103: err;
1104: caddr_t param;
1105: struct RoSAPinvoke *rox;
1106: struct RoSAPindication *roi;
1107: {
1108: if (RyDsError (sd, rox -> rox_id, err, param, ROS_NOPRIO, roi) == NOTOK)
1109: ros_adios (&roi -> roi_preject, "ERROR");
1110:
1111: return OK;
1112: }
1113:
1114: /* U-REJECT */
1115:
1116: static int ureject (sd, reason, rox, roi)
1117: int sd,
1118: reason;
1119: struct RoSAPinvoke *rox;
1120: struct RoSAPindication *roi;
1121: {
1122: if (RyDsUReject (sd, rox -> rox_id, reason, ROS_NOPRIO, roi) == NOTOK)
1123: ros_adios (&roi -> roi_preject, "U-REJECT");
1124:
1125: return OK;
1126: }
1127:
1128: /* TYPES */
1129:
1130: struct type_IMISC_IA5List *str2ia5list (s)
1131: char *s;
1132: {
1133: register struct type_IMISC_IA5List *ia5;
1134:
1135: if ((ia5 = (struct type_IMISC_IA5List *) calloc (1, sizeof *ia5)) == NULL)
1136: return NULL;
1137:
1138: if ((ia5 -> IA5String = str2qb (s, strlen (s), 1)) == NULL) {
1139: free ((char *) ia5);
1140: return NULL;
1141: }
1142:
1143: return ia5;
1144: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.