Annotation of 43BSDReno/contrib/isode-beta/imisc/imiscd.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.