home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / ns2tab / part03 < prev    next >
Encoding:
Text File  |  1993-04-03  |  35.0 KB  |  1,600 lines

  1. Newsgroups: comp.sources.unix
  2. From: i3558@newsie.dc.dk (Soeren Michael Roug)
  3. Subject: v26i094: ns2tab - Increasing the usefullnes of the nameserver, Part03/03
  4. Sender: unix-sources-moderator@vix.com
  5. Approved: paul@vix.com
  6.  
  7. Submitted-By: i3558@newsie.dc.dk (Soeren Michael Roug)
  8. Posting-Number: Volume 26, Issue 94
  9. Archive-Name: ns2tab/part03
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 3 (of 3)."
  18. # Contents:  list.c
  19. # Wrapped by i3558@ulrik.dc.dk on Fri Mar 26 15:05:36 1993
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'list.c' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'list.c'\"
  23. else
  24. echo shar: Extracting \"'list.c'\" \(32658 characters\)
  25. sed "s/^X//" >'list.c' <<'END_OF_FILE'
  26. X/*
  27. X *******************************************************************************
  28. X *
  29. X *  list.c --
  30. X *
  31. X *    Routines to obtain info from name and finger servers.
  32. X *
  33. X *    Adapted from 4.3BSD BIND ns_init.c and from finger.c.
  34. X *
  35. X *******************************************************************************
  36. X */
  37. X
  38. X#include <sys/types.h>
  39. X#include <sys/socket.h>
  40. X#include <netinet/in.h>
  41. X#include <netdb.h>
  42. X#include <stdio.h>
  43. X#include <string.h>
  44. X#include <ctype.h>
  45. X#include <errno.h>
  46. X#include <arpa/nameser.h>
  47. X#ifndef T_TXT
  48. X#define T_TXT 16
  49. X#endif
  50. X#include <arpa/inet.h>
  51. X#include <resolv.h>
  52. X#include "res.h"
  53. X#include "vtable.h"
  54. X
  55. X#ifndef __STDC__
  56. Xextern char *malloc();
  57. X#else
  58. X#include <stdlib.h>
  59. X#endif
  60. X
  61. Xextern void *htab_find();
  62. X
  63. X#define NOID -8472874   /* Something very unlikely */
  64. X/*
  65. X *  Imported from res_debug.c
  66. X */
  67. Xextern char *_res_resultcodes[];
  68. X
  69. Xextern int errno;
  70. Xstatic int lelmstyle;
  71. Xstatic int recursegroup;
  72. X
  73. Xtypedef union {
  74. X    HEADER qb1;
  75. X    char qb2[PACKETSZ];
  76. X} querybuf;
  77. X
  78. Xextern HostInfo    *defaultPtr;
  79. Xextern HostInfo    curHostInfo;
  80. Xextern char *vdomain;
  81. Xextern int    queryType;
  82. Xextern int    queryClass;
  83. X
  84. Xstatic int sockFD = -1;
  85. Xstatic int ListSubr();
  86. X
  87. Xstatic void AddAlias();
  88. Xstatic void ChangeMailList();
  89. Xstatic void ChangeAddr();
  90. Xstatic void ChangeMailBox();
  91. Xstatic void AddMailListMember();
  92. Xstatic void ChangeUGID();
  93. Xstatic void ChangeHInfo();
  94. X#ifdef EMULATE_HESIOD
  95. Xstatic void ChangeText();
  96. X#endif /* EMULATE_HESIOD */
  97. X/*
  98. X *  During a listing to a file, hash marks are printed
  99. X *  every HASH_SIZE records.
  100. X */
  101. X
  102. X#define HASH_SIZE 50
  103. X
  104. X
  105. X/*
  106. X *******************************************************************************
  107. X *
  108. X *  LoadHosts --
  109. X *
  110. X *    Requests the name server to do a zone transfer so we
  111. X *    find out what hosts it knows about.
  112. X *
  113. X *    For LoadHosts, there are five types of output:
  114. X *
  115. X *    To see all types of information sorted by name, do the following:
  116. X *      ls -d domain.edu > file
  117. X *      view file
  118. X *
  119. X *  Results:
  120. X *    SUCCESS        the listing was successful.
  121. X *    ERROR        the server could not be contacted because
  122. X *            a socket could not be obtained or an error
  123. X *            occured while receiving, or the output file
  124. X *            could not be opened.
  125. X *
  126. X *******************************************************************************
  127. X */
  128. X
  129. Xvoid
  130. XLoadHosts(domain)
  131. X    char *domain;
  132. X{
  133. X    int result;
  134. X
  135. X    if (domain && *domain)
  136. X    {
  137. X        result = ListSubr(domain);
  138. X        if (result != SUCCESS)
  139. X        fprintf(stderr, "*** Can't list domain %s: %s\n", 
  140. X            domain, DecodeError(result));
  141. X    }
  142. X    else
  143. X    {
  144. X        fprintf(stderr, "*** ns2tab: empty domain\n");
  145. X    }
  146. X        return;
  147. X}
  148. X
  149. Xstruct minfo_ent {
  150. X    char name[32];
  151. X    char request[32];
  152. X    char errors[32];
  153. X    vtable table; /* Table for the members */
  154. X};
  155. Xstruct mg_ent {
  156. X    char member[32];
  157. X};
  158. X
  159. Xstruct mb_ent {
  160. X    char name[32];
  161. X    char mailbox[32];
  162. X    int qtype;
  163. X    char *gecos;
  164. X    int gid;
  165. X    int uid;
  166. X};
  167. X
  168. Xstruct host_ent {
  169. X    char name[32];
  170. X    char *machtype;
  171. X    char *ostype;
  172. X    vtable aliases;
  173. X    vtable ipaddr;
  174. X};
  175. Xstruct host_ali {
  176. X    char name[32];
  177. X};
  178. Xstruct host_ip {
  179. X    int addr;
  180. X    int used;
  181. X};
  182. X
  183. Xstruct txt_ent {
  184. X    char name[32];
  185. X    char *txt;
  186. X};
  187. X
  188. Xstruct ns_ent {
  189. X    char name[32];
  190. X    int is_explicit;
  191. X};
  192. Xvtable subdomains; /* Table to hold subdomain list */
  193. X
  194. Xvoid *mailtab; /* The global hash table for maillists */
  195. Xvoid *mb_tab; /* The hash table for mailboxes */
  196. Xvoid *host_tab;
  197. X#ifdef EMULATE_HESIOD
  198. Xvoid *txt_tab;
  199. X#endif /* EMULATE_HESIOD */
  200. X
  201. Xint
  202. Xns_cmp(n1,n2)
  203. X    struct ns_ent *n1,*n2;
  204. X{
  205. X    return strncmp(n1->name,n2->name,sizeof(n1->name));
  206. X}
  207. X
  208. Xns_add(name,is_explicit)
  209. X    char *name;
  210. X    int is_explicit;
  211. X{
  212. X    struct ns_ent nb;
  213. X
  214. X    memcpy(nb.name,name,sizeof(nb.name));
  215. X    nb.is_explicit = is_explicit;
  216. X    if(!VTableLookup(&subdomains,&nb))
  217. X    VTableAppend(&subdomains,(char*)&nb);
  218. X}
  219. X
  220. Xint
  221. XInitTables()
  222. X{
  223. X    mailtab = htab_init(17,NULL,NULL,NULL);
  224. X    mb_tab = htab_init(231,NULL,NULL,NULL);
  225. X    host_tab = htab_init(231,NULL,NULL,NULL);
  226. X    VTableSet(&subdomains,sizeof(struct ns_ent));
  227. X    VTableSetCmp(&subdomains,ns_cmp);
  228. X#ifdef EMULATE_HESIOD
  229. X    txt_tab = htab_init(17,NULL,NULL,NULL);
  230. X#endif /* EMULATE_HESIOD */
  231. X}
  232. X
  233. Xstatic int
  234. XListSubr(domain)
  235. X    char *domain;
  236. X{
  237. X    querybuf        buf;
  238. X    struct sockaddr_in    sin;
  239. X    HEADER            *headerPtr;
  240. X    int            msglen;
  241. X    int            amtToRead;
  242. X    int            numRead;
  243. X    int            numAnswers = 0;
  244. X    int            result;
  245. X    int            soacnt = 0;
  246. X    u_short            len;
  247. X    char            *cp, *nmp;
  248. X    char            dname[2][NAME_LEN];
  249. X    char            file[NAME_LEN];
  250. X    static char        *answer = NULL;
  251. X    static int        answerLen = 0;
  252. X    enum {
  253. X        NO_ERRORS,
  254. X        ERR_READING_LEN,
  255. X        ERR_READING_MSG,
  256. X        ERR_PRINTING,
  257. X    } error = NO_ERRORS;
  258. X
  259. X    /*
  260. X     *  Create a query packet for the requested domain name.
  261. X     */
  262. X    msglen = res_mkquery(QUERY, domain, queryClass, T_AXFR,
  263. X                (char *)0, 0, (char *)0,
  264. X                (char *) &buf, sizeof(buf));
  265. X    if (msglen < 0) {
  266. X        if (_res.options & RES_DEBUG) {
  267. X        fprintf(stderr, "*** ls: res_mkquery failed\n");
  268. X        }
  269. X        return (ERROR);
  270. X    }
  271. X
  272. X    bzero((char *)&sin, sizeof(sin));
  273. X    sin.sin_family    = AF_INET;
  274. X    sin.sin_port    = htons(nsport);
  275. X
  276. X    /*
  277. X     *  Check to see if we have the address of the server or the
  278. X     *  address of a server who knows about this domain.
  279. X     *
  280. X     *  For now, just use the first address in the list.
  281. X     */
  282. X
  283. X    if (defaultPtr->addrList != NULL) {
  284. X      sin.sin_addr = *(struct in_addr *) defaultPtr->addrList[0];
  285. X    } else {
  286. X      sin.sin_addr = *(struct in_addr *)defaultPtr->servers[0]->addrList[0];
  287. X    }
  288. X
  289. X    /*
  290. X     *  Set up a virtual circuit to the server.
  291. X     */
  292. X    if ((sockFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  293. X        perror("ls: socket");
  294. X        return(ERROR);
  295. X    }
  296. X    if (connect(sockFD, &sin, sizeof(sin)) < 0) {
  297. X        int e;
  298. X        if (errno == ECONNREFUSED) {
  299. X        e = NO_RESPONSE;
  300. X        } else {
  301. X        perror("ls: connect");
  302. X        e = ERROR;
  303. X        }
  304. X        (void) close(sockFD);
  305. X        sockFD = -1;
  306. X        return e;
  307. X    }
  308. X
  309. X    /*
  310. X     * Send length & message for zone transfer
  311. X     */
  312. X
  313. X        len = htons(msglen);
  314. X
  315. X        if (write(sockFD, (char *)&len, sizeof(len)) != sizeof(len) ||
  316. X            write(sockFD, (char *) &buf, msglen) != msglen) {
  317. X        perror("ls: write");
  318. X        (void) close(sockFD);
  319. X        sockFD = -1;
  320. X        return(ERROR);
  321. X    }
  322. X
  323. X    dname[0][0] = '\0';
  324. X    while (1) {
  325. X        unsigned short tmp;
  326. X
  327. X        /*
  328. X         * Read the length of the response.
  329. X         */
  330. X
  331. X        cp = (char *) &tmp;
  332. X        amtToRead = sizeof(u_short);
  333. X        while (amtToRead > 0 && (numRead=read(sockFD, cp, amtToRead)) > 0) {
  334. X        cp      += numRead;
  335. X        amtToRead -= numRead;
  336. X        }
  337. X        if (numRead <= 0) {
  338. X        error = ERR_READING_LEN;
  339. X        break;
  340. X        }
  341. X
  342. X        if ((len = htons(tmp)) == 0) {
  343. X        break;    /* nothing left to read */
  344. X        }
  345. X
  346. X        /*
  347. X         * The server sent too much data to fit the existing buffer --
  348. X         * allocate a new one.
  349. X         */
  350. X        if (len > answerLen) {
  351. X        if (answerLen != 0) {
  352. X            free(answer);
  353. X        }
  354. X        answerLen = len;
  355. X        answer = malloc(answerLen);
  356. X        }
  357. X
  358. X        /*
  359. X         * Read the response.
  360. X         */
  361. X
  362. X        amtToRead = len;
  363. X        cp = answer;
  364. X        while (amtToRead > 0 && (numRead=read(sockFD, cp, amtToRead)) > 0) {
  365. X        cp += numRead;
  366. X        amtToRead -= numRead;
  367. X        }
  368. X        if (numRead <= 0) {
  369. X        error = ERR_READING_MSG;
  370. X        break;
  371. X        }
  372. X
  373. X        result = PrintListInfo(filePtr, answer, cp, dname[0]);
  374. X        if (result != SUCCESS) {
  375. X        error = ERR_PRINTING;
  376. X        break;
  377. X        }
  378. X
  379. X        numAnswers++;
  380. X        cp = answer + sizeof(HEADER);
  381. X        if (ntohs(((HEADER* )answer)->qdcount) > 0)
  382. X        cp += dn_skipname(cp, answer + len) + QFIXEDSZ;
  383. X        nmp = cp;
  384. X        cp += dn_skipname(cp, (u_char *)answer + len);
  385. X        if ((_getshort(cp) == T_SOA)) {
  386. X        dn_expand(answer, answer + len, nmp, dname[soacnt],
  387. X            sizeof(dname[0]));
  388. X            if (soacnt) {
  389. X            if (strcmp(dname[0], dname[1]) == 0)
  390. X            break;
  391. X        } else
  392. X            soacnt++;
  393. X        }
  394. X    } /* while */
  395. X
  396. X    (void) close(sockFD);
  397. X    sockFD = -1;
  398. X    switch (error) {
  399. X        case NO_ERRORS:
  400. X        return (SUCCESS);
  401. X
  402. X        case ERR_READING_LEN:
  403. X        return(ERROR);
  404. X
  405. X        case ERR_PRINTING:
  406. X        return(result);
  407. X
  408. X        case ERR_READING_MSG:
  409. X        headerPtr = (HEADER *) answer;
  410. X        fprintf(stderr,"*** ls: error receiving zone transfer:\n");
  411. X        fprintf(stderr,
  412. X           "  result: %s, answers = %d, authority = %d, additional = %d\n",
  413. X            _res_resultcodes[headerPtr->rcode],
  414. X            ntohs(headerPtr->ancount), ntohs(headerPtr->nscount),
  415. X            ntohs(headerPtr->arcount));
  416. X        return(ERROR);
  417. X        default:
  418. X        return(ERROR);
  419. X    }
  420. X}
  421. X
  422. X
  423. X/*
  424. X *******************************************************************************
  425. X *
  426. X *  PrintListInfo --
  427. X *
  428. X *    Used by the ListInfo routine to print the answer
  429. X *    received from the name server. Only the desired
  430. X *    information is printed.
  431. X *
  432. X *  Results:
  433. X *    SUCCESS        the answer was printed without a problem.
  434. X *    NO_INFO        the answer packet did not contain an answer.
  435. X *    ERROR        the answer was malformed.
  436. X *      Misc. errors    returned in the packet header.
  437. X *
  438. X *******************************************************************************
  439. X */
  440. X
  441. X#define NAME_FORMAT "%s"
  442. X
  443. Xstatic Boolean
  444. Xstrip_domain(string, domain)
  445. X    char *string, *domain;
  446. X{
  447. X    register char *dot;
  448. X
  449. X    if (*domain != '\0') {
  450. X    dot = string;
  451. X    while ((dot = strchr(dot, '.')) != NULL && strcasecmp(domain, ++dot))
  452. X        ;
  453. X    if (dot != NULL) {
  454. X        dot[-1] = '\0';
  455. X        return TRUE;
  456. X    }
  457. X    }
  458. X    return FALSE;
  459. X}
  460. X
  461. Xstatic char *
  462. Xdomain_start(string, domain)
  463. X    char *string, *domain;
  464. X{
  465. X    register char *dot;
  466. X
  467. X    if (*domain != '\0') {
  468. X    dot = string;
  469. X    while ((dot = strchr(dot, '.')) != NULL && strcasecmp(domain, ++dot))
  470. X        ;
  471. X    return dot;
  472. X    }
  473. X    return NULL;
  474. X}
  475. X
  476. Xstatic char *
  477. Xdomain_child(string, domain)
  478. X    char *string, *domain;
  479. X{
  480. X    register char *dot;
  481. X
  482. X    if (*domain != '\0') {
  483. X    dot = string;
  484. X    if((dot = strchr(dot, '.')) != NULL && !strcasecmp(domain, ++dot))
  485. X        return dot;
  486. X    }
  487. X    return NULL;
  488. X}
  489. X
  490. XPrintListInfo(file, msg, eom, domain)
  491. X    FILE    *file;
  492. X    char    *msg, *eom;
  493. X    char    *domain;
  494. X{
  495. X    register char    *cp;
  496. X    HEADER        *headerPtr;
  497. X    int            type, qclass, dlen, nameLen;
  498. X    u_long        ttl;
  499. X    int            n, pref;
  500. X    struct in_addr    inaddr;
  501. X    char        name[NAME_LEN];
  502. X    char        name2[NAME_LEN];
  503. X    Boolean        stripped;
  504. X
  505. X    /*
  506. X     * Read the header fields.
  507. X     */
  508. X    headerPtr = (HEADER *)msg;
  509. X    cp = msg + sizeof(HEADER);
  510. X    if (headerPtr->rcode != NOERROR) {
  511. X    return(headerPtr->rcode);
  512. X    }
  513. X
  514. X    /*
  515. X     *  We are looking for info from answer resource records.
  516. X     *  If there aren't any, return with an error. We assume
  517. X     *  there aren't any question records.
  518. X     */
  519. X
  520. X    if (ntohs(headerPtr->ancount) == 0) {
  521. X    return(NO_INFO);
  522. X    } else {
  523. X    if (ntohs(headerPtr->qdcount) > 0) {
  524. X        nameLen = dn_skipname(cp, eom);
  525. X        if (nameLen < 0)
  526. X        return (ERROR);
  527. X        cp += nameLen + QFIXEDSZ;
  528. X    }
  529. X    if ((nameLen = dn_expand(msg, eom, cp, name, sizeof(name))) < 0)
  530. X        return (ERROR);
  531. X    cp += nameLen;
  532. X
  533. X    type = _getshort(cp);
  534. X    cp += sizeof(u_short);
  535. X
  536. X    qclass = _getshort(cp);
  537. X    cp += sizeof(u_short);
  538. X    ttl = _getlong(cp);
  539. X    cp += sizeof(u_long);
  540. X    dlen = _getshort(cp);
  541. X    cp += sizeof(u_short);
  542. X
  543. X    if (name[0] == 0)
  544. X        strcpy(name, ".");
  545. X
  546. X    /* Strip the domain name from the data, if desired. */
  547. X    stripped = FALSE;
  548. X    if (type != T_A && type != T_HINFO && type != T_CNAME)
  549. X    {
  550. X        char *y;
  551. X
  552. X        stripped = strip_domain(name, vdomain);
  553. X        if ((y = strrchr(name,'.')) != 0)
  554. X        {
  555. X        if(stripped)
  556. X        {
  557. X            *y++ = '\0';
  558. X            ns_add(y,0); /* Adding implicit domain */
  559. X        }
  560. X        return(SUCCESS);
  561. X        }
  562. X    }
  563. X    else
  564. X    {
  565. X        char *y,*ds;
  566. X
  567. X        ds = domain_start(name,vdomain);
  568. X        if(!ds)  return(SUCCESS);
  569. X        ds[-1] = '\0';
  570. X        if(( y = strrchr(name,'.')) != 0)
  571. X        {
  572. X        *y++ = '\0';
  573. X        ns_add(y,0); /* Adding implicit domain */
  574. X        return (SUCCESS);
  575. X        }
  576. X        ds[-1] = '.';
  577. X    }
  578. X    if(strlen(name) == 0)
  579. X        return(SUCCESS); /* Ignore this record */
  580. X
  581. X/*
  582. X * The wildcard is a special case.
  583. X */
  584. X    if(!strcmp(name,"*")) return(SUCCESS);
  585. X
  586. X    switch (type)
  587. X    {
  588. X        case T_NS:
  589. X        if ((nameLen =
  590. X            dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) {
  591. X            return (ERROR);
  592. X        }
  593. X        strip_domain(name2, vdomain);
  594. X        ns_add(name,1); /* Add explicit domain */
  595. X        break;
  596. X        case T_MR:
  597. X        {
  598. X        char mailbox[64];
  599. X
  600. X        if ((nameLen =
  601. X            dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) {
  602. X            return (ERROR);
  603. X        }
  604. X        strip_domain(name2, domain);
  605. X        if(use_quotes(name2))
  606. X        {
  607. X            sprintf(mailbox,"\"%s\"",name2);
  608. X            ChangeMailBox(name,mailbox,NULL,type);
  609. X            /* fprintf(file, "%s:\"%s\"\n",name,name2); */
  610. X        }
  611. X        else
  612. X        {
  613. X            ChangeMailBox(name,name2,NULL,type);
  614. X            /* fprintf(file, "%s:%s\n",name,name2); */
  615. X        }
  616. X        break;
  617. X        }
  618. X        case T_MB:
  619. X        {
  620. X        char mailbox[64];
  621. X
  622. X        if ((nameLen =
  623. X            dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) {
  624. X            return (ERROR);
  625. X        }
  626. X/*        strip_domain(name2, vdomain); */
  627. X        if(use_quotes(name2))
  628. X        {
  629. X            fprintf(stderr,"Error in hostname: %s\n",name2);
  630. X            break;
  631. X        }
  632. X        sprintf(mailbox,"%s@%s",name,name2);
  633. X        ChangeMailBox(name,mailbox,NULL,type);
  634. X        /* fprintf(file, "%s:%s@%s\n",name,name, name2); */
  635. X        break;
  636. X        }
  637. X        case T_MG:
  638. X        if ((nameLen =
  639. X            dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0)
  640. X            return (ERROR);
  641. X        strip_domain(name2, domain);
  642. X        AddMailListMember(name,name2);
  643. X        break;
  644. X        case T_CNAME:
  645. X        if ((nameLen = dn_expand(msg, eom, cp, name2,
  646. X        sizeof(name2))) < 0)
  647. X            return (ERROR);
  648. X        strip_domain(name2, vdomain);
  649. X        AddAlias(name2,name);
  650. X        break;
  651. X
  652. X        case T_MINFO:
  653. X        {
  654. X        char req_name[32],err_name[32];
  655. X        int n;
  656. X
  657. X        if((n = dn_expand(msg,eom,cp,req_name,sizeof(req_name))) < 0)
  658. X            return(ERROR);
  659. X        cp += n;
  660. X        strip_domain(req_name, domain);
  661. X        if((n = dn_expand(msg,eom,cp,err_name,sizeof(err_name))) < 0)
  662. X            return(ERROR);
  663. X        cp += n;
  664. X        strip_domain(err_name, domain);
  665. X        ChangeMailList(name,req_name,err_name);
  666. X        }
  667. X        break;
  668. X        case T_UINFO:
  669. X        ChangeMailBox(name,NULL,cp,0);
  670. X        /* fprintf(file, "# %s -- %s\n",name, cp); */
  671. X        break;
  672. X        case T_HINFO:
  673. X        {
  674. X        char mach_name[128],os_name[128];
  675. X        int n;
  676. X
  677. X        *mach_name = '\0'; /* Reset machine_name */
  678. X        if(n = *cp++) {
  679. X            (void)sprintf(mach_name,"%.*s",n, cp);
  680. X            cp += n;
  681. X        } 
  682. X        *os_name = '\0'; /* Reset os_name */
  683. X        if(n = *cp++) {
  684. X            (void)sprintf(os_name,"%.*s",n, cp);
  685. X            cp += n;
  686. X        } 
  687. X        ChangeHInfo(name,mach_name,os_name);
  688. X        }
  689. X        break;
  690. X        case T_GID:
  691. X        ChangeUGID(name,NOID,_getlong(cp));
  692. X        break;
  693. X        case T_UID:
  694. X        ChangeUGID(name,_getlong(cp),NOID);
  695. X        break;
  696. X        case T_A:
  697. X        ChangeAddr(name,_getlong(cp));
  698. X        break;
  699. X#ifdef EMULATE_HESIOD
  700. X        case T_TXT:
  701. X        {
  702. X            int n;
  703. X            n = *cp++;
  704. X            ChangeText(name,cp,n);
  705. X            /* fprintf(file, "%s|%s\n",name,name2); */
  706. X        }
  707. X        break;
  708. X#endif /* EMULATE_HESIOD */
  709. X        default:
  710. X        break;
  711. X    } /* switch */
  712. X    }
  713. X    return(SUCCESS);
  714. X}
  715. X
  716. Xstatic int
  717. Xuse_quotes(name)
  718. X    char *name;
  719. X{
  720. X    char *wildp;
  721. X    int noquotes = 1;
  722. X
  723. X    while(*name && noquotes)
  724. X    {
  725. X    for(wildp = " \t\n|/"; *wildp && noquotes; )
  726. X        if(*wildp++ == *name)
  727. X        noquotes=0;
  728. X    name++;
  729. X    }
  730. X    return !noquotes;
  731. X}
  732. X
  733. XListHost_close()
  734. X{
  735. X    if (sockFD != -1) {
  736. X    (void) close(sockFD);
  737. X    sockFD = -1;
  738. X    }
  739. X}
  740. X
  741. Xstruct mb_ent *
  742. XCreateMailBox(name)
  743. X   char *name;
  744. X{
  745. X    struct mb_ent *me;
  746. X
  747. X    me = (struct mb_ent*)malloc(sizeof(struct mb_ent));
  748. X    bzero(me,sizeof(struct mb_ent));
  749. X    me->gid = NOID;
  750. X    me->uid = NOID;
  751. X    strncpy(me->name,name,32);
  752. X    htab_enter(mb_tab,me,me);
  753. X    return me;
  754. X}
  755. X
  756. Xstatic void
  757. XChangeMailBox(name,box,gecos,qtype)
  758. X   char *name,*box,*gecos;
  759. X   int qtype;
  760. X{
  761. X    struct mb_ent *me;
  762. X    
  763. X    me = (struct mb_ent*)htab_find(mb_tab,name);
  764. X    if(!me) 
  765. X    me = CreateMailBox(name);
  766. X    if(qtype)
  767. X    me->qtype = qtype;
  768. X    if(box)
  769. X    {
  770. X    strncpy(me->mailbox,box,32);
  771. X        if(!strncmp(name,box,32))
  772. X        *me->mailbox = '\0'; /* Zeroing it. */
  773. X    }
  774. X/*
  775. X * This can have some size, and is probaly infrequent, so I malloc the space
  776. X */
  777. X    if(gecos)
  778. X    {
  779. X    if(me->gecos) free(me->gecos); /* Previos stuff */
  780. X    me->gecos = malloc(strlen(gecos) +1 );
  781. X    strcpy(me->gecos,gecos);
  782. X    }
  783. X}
  784. X
  785. X#ifdef EMULATE_HESIOD
  786. Xstatic void
  787. XChangeText(name,text,n)
  788. X    char *name,*text;
  789. X    int n;
  790. X{
  791. X    struct txt_ent *te;
  792. X
  793. X    te = (struct txt_ent*)htab_find(txt_tab,name);
  794. X    if(!te) 
  795. X    {
  796. X    te = (struct txt_ent*)malloc(sizeof(struct txt_ent));
  797. X    strncpy(te->name,name,32);
  798. X    htab_enter(txt_tab,te,te);
  799. X    }
  800. X    else
  801. X    free(te->txt);
  802. X    te->txt = malloc(n+1);
  803. X    strncpy(te->txt,text,n);
  804. X    te->txt[n] = '\0';
  805. X}
  806. X#endif /* EMULATE_HESIOD */
  807. X
  808. Xstatic void
  809. XChangeUGID(name,uid,gid)
  810. X    char *name;
  811. X    int uid,gid;
  812. X{
  813. X    struct mb_ent *me;
  814. X    
  815. X    me = (struct mb_ent*)htab_find(mb_tab,name);
  816. X    if(!me) 
  817. X    me = CreateMailBox(name);
  818. X    if(gid != NOID) me->gid = gid;
  819. X    if(uid != NOID) me->uid = uid;
  820. X}
  821. X
  822. Xstruct host_ent *
  823. XCreateAddr(name)
  824. X    char *name;
  825. X{
  826. X    struct host_ent *me;
  827. X
  828. X    me = (struct host_ent *)malloc(sizeof(struct host_ent));
  829. X    bzero(me,sizeof(struct host_ent));
  830. X    strncpy(me->name,name,32);
  831. X    VTableSet(&me->ipaddr,sizeof(struct host_ip));
  832. X    VTableSet(&me->aliases,sizeof(struct host_ali));
  833. X    htab_enter(host_tab,me,me);
  834. X    return me;
  835. X}
  836. X
  837. Xstatic void
  838. XChangeAddr(name,addr)
  839. X    char *name;
  840. X    int addr;
  841. X{
  842. X    struct host_ent *me;
  843. X    struct host_ip ip,*hi;
  844. X    int ix=0;
  845. X
  846. X#if 0
  847. Xfprintf(stderr,"In ChangeAddr with %s\n",name);
  848. X#endif
  849. X    me = (struct host_ent*)htab_find(host_tab,name);
  850. X    if(!me)
  851. X       me = CreateAddr(name);
  852. X    while(hi = (struct host_ip*)VTableNext(&me->ipaddr,&ix,1))
  853. X    {
  854. X       if(hi->addr == addr) return; /* Do not add same IP address twice */
  855. X    }
  856. X    ip.used = 0;
  857. X    ip.addr = addr;
  858. X    VTableAppend(&me->ipaddr,(char*)&ip);
  859. X}
  860. X
  861. Xstatic void
  862. XAddAlias(name,alias)
  863. X    char *name;
  864. X    char *alias;
  865. X{
  866. X    struct host_ent *me;
  867. X    struct host_ali ali;
  868. X
  869. X#if 0
  870. Xfprintf(stderr,"In AddAlias with %s\n",name);
  871. X#endif
  872. X    me = (struct host_ent*)htab_find(host_tab,name);
  873. X    if(!me)
  874. X       me = CreateAddr(name);
  875. X    strncpy(ali.name,alias,32);
  876. X    VTableAppend(&me->aliases,(char*)&ali);
  877. X}
  878. X
  879. Xstatic void
  880. XChangeHInfo(name,mach,os)
  881. X    char *name;
  882. X    char *mach;
  883. X    char *os;
  884. X{
  885. X    struct host_ent *me;
  886. X    char *mmach;
  887. X    char *mos;
  888. X
  889. X    me = (struct host_ent*)htab_find(host_tab,name);
  890. X    if(!me)
  891. X    me = CreateAddr(name);
  892. X    mmach = malloc(strlen(mach)+1);
  893. X    mos = malloc(strlen(os)+1);
  894. X    strcpy(mmach,mach);
  895. X    strcpy(mos,os);
  896. X
  897. X    me->ostype = mos;
  898. X    me->machtype = mmach;
  899. X}
  900. X
  901. Xstruct minfo_ent *
  902. XCreateMailList(name)
  903. X   char *name;
  904. X{
  905. X    struct minfo_ent *me;
  906. X
  907. X    me = (struct minfo_ent*)malloc(sizeof(struct minfo_ent));
  908. X    bzero(me,sizeof(struct minfo_ent));
  909. X    strncpy(me->name,name,32);
  910. X    VTableSet(&me->table,sizeof(struct mg_ent));
  911. X    htab_enter(mailtab,me,me);
  912. X    return me;
  913. X}
  914. X
  915. Xstatic void
  916. XChangeMailList(name,request,errors)
  917. X   char *name,*request,*errors;
  918. X{
  919. X    struct minfo_ent *me;
  920. X    
  921. X    me = (struct minfo_ent*)htab_find(mailtab,name);
  922. X    if(!me) 
  923. X    me = CreateMailList(name);
  924. X    if(request)
  925. X    strncpy(me->request,request,32);
  926. X    if(errors)
  927. X    strncpy(me->errors,errors,32);
  928. X}
  929. X
  930. Xstatic void
  931. XAddMailListMember(name,member)
  932. X    char *name,*member;
  933. X{
  934. X    struct minfo_ent *me;
  935. X    struct mg_ent mg;
  936. X    
  937. X    me = (struct minfo_ent*)htab_find(mailtab,name);
  938. X    if(!me) 
  939. X    me = CreateMailList(name);
  940. X    strncpy(mg.member,member,32);
  941. X    VTableAppend(&me->table,(char*)&mg);
  942. X}
  943. X
  944. XPrintMailLists(file)
  945. X    FILE    *file;
  946. X{
  947. X    int starting= TRUE;
  948. X    int pos,first,mlen;
  949. X    struct minfo_ent *me,*key;
  950. X    struct mg_ent *mg;
  951. X
  952. X    fprintf(file,"#\n# Maillists created by ns2tab\n#\n");
  953. X    while(htab_list(mailtab,starting,&me,&key))
  954. X    {
  955. X    int ix=0;
  956. X    int l,dnr;
  957. X    struct mb_ent *mb;
  958. X
  959. X    starting = FALSE;
  960. X    if(VTableSize(&me->table) == 0)
  961. X        continue;
  962. X    fprintf(file,"\n"); /* Start each list with a newline */
  963. X    if((mb = htab_find(mb_tab,me->name)) && mb->gecos)
  964. X       fprintf(file,"# %s\n",mb->gecos); /* Get comment */
  965. X    dnr =0;
  966. X    if(*me->request)
  967. X        fprintf(file,"%s-request: %s\n",me->name,me->request);
  968. X    if(*me->errors)
  969. X        fprintf(file,"owner-%s: %s\n",me->name,me->errors);
  970. X    fprintf(file,"%s: ",me->name);
  971. X    pos = strlen(me->name) +1;
  972. X    mlen = pos;
  973. X    first = TRUE;
  974. X        while(mg = (struct mg_ent*)VTableNext(&me->table,&ix,1))
  975. X    {
  976. X/*
  977. X * Do not include a listmember with the same name as the list it self
  978. X */
  979. X        if(!strcmp(me->name,mg->member)) continue;
  980. X
  981. X        l = strlen(mg->member) + 2;
  982. X/* I am told that because of restrictions in dbm an alias cannot contain
  983. X   more than approximately 1000 bytes of information. So I create
  984. X   dummy aliases.
  985. X*/
  986. X        mlen += l;
  987. X        if(mlen > 970)
  988. X        {
  989. X        if(!first) putc(',',file);
  990. X        dnr++;
  991. X        fprintf(file,"%s_%d,\n",me->name,dnr);
  992. X        fprintf(file,
  993. X    "# Dummy alias necesary because of restrictions in dbm(3x).\n");
  994. X        fprintf(file,"%s_%d: %s",me->name,dnr,mg->member);
  995. X        pos = strlen(me->name) + 4;
  996. X        mlen = pos + l;
  997. X        first = FALSE;
  998. X        }
  999. X        if((pos + l) > 76)
  1000. X        {
  1001. X        pos = l;
  1002. X        fprintf(file,",\n\t%s",mg->member);
  1003. X        }
  1004. X        else
  1005. X        {
  1006. X        pos += l;
  1007. X        if(!first) fprintf(file,", ");
  1008. X        first = FALSE;
  1009. X        fprintf(file,"%s",mg->member);
  1010. X        }
  1011. X    }
  1012. X    fprintf(file,"\n");
  1013. X    }
  1014. X}
  1015. X
  1016. XPrintMailBoxes(file)
  1017. X    FILE    *file;
  1018. X{
  1019. X    int starting= TRUE;
  1020. X    struct mb_ent *me,*key;
  1021. X
  1022. X    fprintf(file,"#\n# Mailboxes created by ns2tab\n#\n");
  1023. X    while(htab_list(mb_tab,starting,&me,&key))
  1024. X    {
  1025. X    starting = FALSE;
  1026. X    if(*me->mailbox)
  1027. X    {
  1028. X        if(me->gecos)
  1029. X        fprintf(file,"# %s +- %s\n",me->name,me->gecos);
  1030. X        fprintf(file,"%s: %s\n",me->name,me->mailbox);
  1031. X    }
  1032. X    }
  1033. X}
  1034. X
  1035. XPrintMail(file)
  1036. X    FILE    *file;
  1037. X{
  1038. X    fprintf(file,"# Aliases created from [%s] nameserver.\n",
  1039. X        (defaultPtr->addrList != NULL) ? defaultPtr->name :
  1040. X         defaultPtr->servers[0]->name);
  1041. X    PrintMailBoxes(file);
  1042. X    PrintMailLists(file);
  1043. X    return 0;
  1044. X}
  1045. X
  1046. X
  1047. XPrintElmLists(file)
  1048. X    FILE    *file;
  1049. X{
  1050. X    int starting= TRUE;
  1051. X    int pos,first,mlen;
  1052. X    struct minfo_ent *me,*key;
  1053. X    struct mg_ent *mg;
  1054. X
  1055. X    fprintf(file,"#\n# Maillists created by ns2tab (ELM) Style\n#\n");
  1056. X    while(htab_list(mailtab,starting,&me,&key))
  1057. X    {
  1058. X    int ix=0;
  1059. X    int l,dnr;
  1060. X    struct mb_ent *mb;
  1061. X
  1062. X    starting = FALSE;
  1063. X    if(VTableSize(&me->table) == 0)
  1064. X        continue;
  1065. X    fprintf(file,"\n"); /* Start each list with a newline */
  1066. X    mb = htab_find(mb_tab,me->name); /* Get Comment */
  1067. X    dnr =0;
  1068. X    if(*me->request)
  1069. X        if(lelmstyle)
  1070. X        fprintf(file,"%s-request = %s Request = %s-request\n",
  1071. X             me->name,me->name,me->name);
  1072. X        else
  1073. X        fprintf(file,"%s-request = %s Request = %s\n",
  1074. X             me->name,me->name,me->request);
  1075. X    if(*me->errors)
  1076. X        if(lelmstyle)
  1077. X        fprintf(file,"owner-%s = %s Errors = owner-%s\n",
  1078. X             me->name,me->name,me->name);
  1079. X        else
  1080. X        fprintf(file,"owner-%s = %s Errors = %s\n",
  1081. X             me->name,me->name,me->errors);
  1082. X    if(mb && mb->gecos)
  1083. X        fprintf(file,"%s = %s = ",me->name,mb->gecos);
  1084. X    else
  1085. X        fprintf(file,"%s = = ",me->name);
  1086. X/*
  1087. X * Local elm doesn't define the members in a maillist, but lets
  1088. X * /usr/lib/aliases handle that part.
  1089. X */
  1090. X    if(lelmstyle)
  1091. X    {
  1092. X        fprintf(file,"%s\n",me->name);
  1093. X        continue;
  1094. X    }
  1095. X    pos = strlen(me->name) +1;
  1096. X    mlen = pos;
  1097. X    first = TRUE;
  1098. X        while(mg = (struct mg_ent*)VTableNext(&me->table,&ix,1))
  1099. X    {
  1100. X/*
  1101. X * Do not include a listmember with the same name as the list itself
  1102. X */
  1103. X        if(!strcmp(me->name,mg->member)) continue;
  1104. X
  1105. X        l = strlen(mg->member) + 2;
  1106. X#if 0
  1107. X/* I am told that because of restrictions in dbm an alias cannot contain
  1108. X   more than approximately 1000 bytes of information. So I create
  1109. X   dummy aliases.
  1110. X*/
  1111. X        mlen += l;
  1112. X        if(mlen > 970)
  1113. X        {
  1114. X        if(!first) putc(',',file);
  1115. X        dnr++;
  1116. X        fprintf(file,"%s_%d\n",me->name,dnr);
  1117. X        fprintf(file,
  1118. X    "# Dummy alias necesary because of restrictions in dbm(3x).\n");
  1119. X        fprintf(file,"%s_%d = = %s",me->name,dnr,mg->member);
  1120. X        pos = strlen(me->name) + 4;
  1121. X        mlen = pos + l;
  1122. X        first = FALSE;
  1123. X        }
  1124. X#endif
  1125. X        if((pos + l) > 76)
  1126. X        {
  1127. X        pos = l;
  1128. X        fprintf(file,",\n   %s",mg->member);
  1129. X        }
  1130. X        else
  1131. X        {
  1132. X        pos += l;
  1133. X        if(!first) fprintf(file,", ");
  1134. X        first = FALSE;
  1135. X        fprintf(file,"%s",mg->member);
  1136. X        }
  1137. X    } /* while */
  1138. X    fprintf(file,"\n");
  1139. X    } /* while */
  1140. X}
  1141. X
  1142. XPrintElmBoxes(file)
  1143. X    FILE    *file;
  1144. X{
  1145. X    int starting= TRUE;
  1146. X    struct mb_ent *me,*key;
  1147. X
  1148. X    fprintf(file,"#\n# Mailboxes created by ns2tab (ELM style)\n#\n");
  1149. X    while(htab_list(mb_tab,starting,&me,&key))
  1150. X    {
  1151. X    starting = FALSE;
  1152. X    if(*me->mailbox)
  1153. X    {
  1154. X        if(lelmstyle)
  1155. X        {
  1156. X        if(me->qtype == T_MR)
  1157. X            fprintf(file,"%s = = %s\n",me->name,me->mailbox);
  1158. X        else
  1159. X            if(me->gecos)
  1160. X            fprintf(file,"%s = %s = %s\n"
  1161. X            ,me->name,me->gecos,me->name);
  1162. X        }
  1163. X        else /* Elm style with no /usr/lib/aliases */
  1164. X        {
  1165. X        fprintf(file,"%s = %s = %s\n",me->name,
  1166. X            (me->gecos)?me->gecos:"",me->mailbox);
  1167. X        }
  1168. X    }
  1169. X    } /* while */
  1170. X}
  1171. X
  1172. XPrintElmish(file)
  1173. X    FILE    *file;
  1174. X{
  1175. X    fprintf(file,"# Aliases created from [%s] nameserver.\n",
  1176. X        (defaultPtr->addrList != NULL) ? defaultPtr->name :
  1177. X         defaultPtr->servers[0]->name);
  1178. X    PrintElmBoxes(file);
  1179. X    PrintElmLists(file);
  1180. X    return 0;
  1181. X}
  1182. X
  1183. Xstatic void ExpandMember();
  1184. X
  1185. XPrintGroupish(file)
  1186. X    FILE    *file;
  1187. X{
  1188. X    int starting= TRUE;
  1189. X    int first;
  1190. X    struct minfo_ent *me,*key;
  1191. X    struct mg_ent *mg;
  1192. X
  1193. X    while(htab_list(mailtab,starting,&me,&key))
  1194. X    {
  1195. X    int ix=0;
  1196. X    struct mb_ent *mb;
  1197. X
  1198. X    starting = FALSE;
  1199. X    if(!(mb = htab_find(mb_tab,me->name)))
  1200. X       continue;  /* Ignore everything that doesn't have a MB */
  1201. X    if(mb->gid == NOID)
  1202. X       continue;  /* Ignore everything that doesn't have a GID */
  1203. X    fprintf(file,"%s:*:%d:",me->name,mb->gid);
  1204. X    first = TRUE;
  1205. X    ExpandMember(file,me);
  1206. X    fprintf(file,"\n");
  1207. X    } /* while */
  1208. X}
  1209. X
  1210. Xstatic void
  1211. XExpandMember(file,me)
  1212. X    FILE *file;
  1213. X    struct minfo_ent *me;
  1214. X{
  1215. X    struct mg_ent *mg;
  1216. X
  1217. X    int first=TRUE;
  1218. X    int ix=0;
  1219. X    while(mg = (struct mg_ent*)VTableNext(&me->table,&ix,1))
  1220. X    {
  1221. X    int doprint = 1;
  1222. X
  1223. X    if(!first) fprintf(file,",");
  1224. X    first = FALSE;
  1225. X/*
  1226. X * If we expand members, we must check them out. If a member has a UID
  1227. X * It should not be expanded.
  1228. X * Also, as an added security, if a member of a group has same
  1229. X * name the group it is not expanded.
  1230. X */
  1231. X    if(recursegroup && strcmp(me->name,mg->member))
  1232. X    {
  1233. X        struct minfo_ent *mm;
  1234. X        struct mb_ent *member;
  1235. X
  1236. X/* Check too see if this is a MINFO */
  1237. X        if(mm = htab_find(mailtab,mg->member))
  1238. X        {
  1239. X        member = htab_find(mb_tab,mg->member);
  1240. X        if ((member && member->uid == NOID) || !member)
  1241. X            if(VTableSize(&mm->table) != 0)
  1242. X            {
  1243. X            ExpandMember(file,mm);
  1244. X            doprint = 0;
  1245. X            }
  1246. X        }
  1247. X    }
  1248. X    if(doprint)
  1249. X        fprintf(file,"%s",mg->member);
  1250. X    }
  1251. X}
  1252. X
  1253. XPrintHosts(file,domain)
  1254. X    FILE    *file;
  1255. X    char *domain;
  1256. X{
  1257. X    int starting= TRUE;
  1258. X    int first;
  1259. X    struct host_ent *host,*key;
  1260. X
  1261. X    fprintf(file,"#\n# Hosttable - derived from ns2tab. Do not change\n#\n");
  1262. X/*
  1263. X * Run through all the canonical names.
  1264. X */
  1265. X    while(htab_list(host_tab,starting,&host,&key))
  1266. X    {
  1267. X    int aix,ix=0;
  1268. X    struct host_ali *ha;
  1269. X    struct host_ip *hi;
  1270. X    char *punkt;
  1271. X
  1272. X    starting = FALSE;
  1273. X        while(hi = (struct host_ip*)VTableNext(&host->ipaddr,&ix,1))
  1274. X    {
  1275. X        aix=0;
  1276. X#if 0
  1277. X        fprintf(file,"%-15s %s.%s %s",inet_ntoa(ntohl(hi->addr)),
  1278. X          host->name,vdomain,host->name);
  1279. X#else
  1280. X        fprintf(file,"%-15s %s",inet_ntoa(ntohl(hi->addr)),
  1281. X          host->name);
  1282. X        if(punkt = strchr(host->name,'.'))
  1283. X        {
  1284. X        *punkt = '\0';
  1285. X        fprintf(file," %s",host->name);
  1286. X        *punkt = '.';
  1287. X        }
  1288. X#endif
  1289. X        while(ha = (struct host_ali*)VTableNext(&host->aliases,&aix,1))
  1290. X        fprintf(file," %s",ha->name);
  1291. X        if(host->machtype || host->ostype)
  1292. X        fprintf(file,"\t#");
  1293. X        if(host->machtype)
  1294. X        fprintf(file," %s",host->machtype);
  1295. X        if(host->ostype)
  1296. X        fprintf(file," %s",host->ostype);
  1297. X        fprintf(file,"\n");
  1298. X    }
  1299. X    }
  1300. X}
  1301. X
  1302. X#include <pwd.h>
  1303. XPWUpd(file)
  1304. X    FILE    *file;
  1305. X{
  1306. X    struct passwd *pw;
  1307. X    struct mb_ent *mb;
  1308. X    char *gecostmp;
  1309. X
  1310. X    while(pw = getpwent())
  1311. X    {
  1312. X    gecostmp = pw->pw_gecos;
  1313. X    if((mb = htab_find(mb_tab,pw->pw_name)) && mb->gecos)
  1314. X        pw->pw_gecos = mb->gecos;
  1315. X    putpwent(pw,file);
  1316. X    pw->pw_gecos = gecostmp;
  1317. X    }
  1318. X    endpwent();
  1319. X}
  1320. X
  1321. Xstatic
  1322. XPrintElm(file)
  1323. X    FILE    *file;
  1324. X{
  1325. X    lelmstyle=0;
  1326. X    PrintElmish(file);
  1327. X}
  1328. X
  1329. Xstatic
  1330. XPrintLElm(file)
  1331. X    FILE    *file;
  1332. X{
  1333. X    lelmstyle=1;
  1334. X    PrintElmish(file);
  1335. X}
  1336. X
  1337. Xstatic
  1338. XPrintGroup(file)
  1339. X    FILE    *file;
  1340. X{
  1341. X    recursegroup=1;
  1342. X    PrintGroupish(file);
  1343. X}
  1344. X
  1345. Xstatic
  1346. XPrintNrGroup(file)
  1347. X    FILE    *file;
  1348. X{
  1349. X    recursegroup=0;
  1350. X    PrintGroupish(file);
  1351. X}
  1352. X
  1353. Xstatic
  1354. XPrintSubdomains(file)
  1355. X    FILE    *file;
  1356. X{
  1357. X    struct ns_ent *ns;
  1358. X    int ix = 0;
  1359. X
  1360. X    while(ns = (struct ns_ent*)VTableNext(&subdomains,&ix,1))
  1361. X    {
  1362. X    printf("%-32s %s\n",ns->name,(ns->is_explicit)?"explicit":"implicit");
  1363. X    }
  1364. X}
  1365. X
  1366. X#ifdef EMULATE_HESIOD
  1367. XPrintPrintcap(file)
  1368. X    FILE *file;
  1369. X{
  1370. X    int starting= TRUE;
  1371. X    int first;
  1372. X    struct txt_ent *name,*key;
  1373. X
  1374. X    fprintf(file,"#\n# Printcap - derived from ns2tab. Do not change\n#\n");
  1375. X/*
  1376. X * Run through all the canonical names.
  1377. X */
  1378. X    while(htab_list(txt_tab,starting,&name,&key))
  1379. X    {
  1380. X    register char *p;
  1381. X
  1382. X    starting = FALSE;
  1383. X/*    fprintf(file,"%s",name->txt); */
  1384. X    p = name->txt;
  1385. X    while(*p)
  1386. X    {
  1387. X       putc(*p,file);
  1388. X       if(*p == ':' && p[1] ) fprintf(file,"\\\n\t:");
  1389. X       p++;
  1390. X    }
  1391. X    }
  1392. X    return 0;
  1393. X}
  1394. X
  1395. Xvoid (*printfunc)();
  1396. X
  1397. XFilesysEngine(file)
  1398. X    FILE *file;
  1399. X{
  1400. X    int starting= TRUE;
  1401. X    int first;
  1402. X    struct txt_ent *name,*key;
  1403. X/*
  1404. X * Run through all the canonical names.
  1405. X */
  1406. X    while(htab_list(txt_tab,starting,&name,&key))
  1407. X    {
  1408. X    int x;
  1409. X    char fs_type[8];
  1410. X    char name_on_server[128], server_hostname[128];
  1411. X    char mount_mode[2],mount_point[128];
  1412. X
  1413. X    starting = FALSE;
  1414. X    x = sscanf(name->txt,"%s %s %s %s %s",
  1415. X        fs_type,name_on_server,
  1416. X        server_hostname,mount_mode,mount_point);
  1417. X    if(x != 5) continue;
  1418. X    (*printfunc)(file,fs_type,name_on_server,server_hostname,
  1419. X          mount_mode,mount_point);
  1420. X    }
  1421. X    return 0;
  1422. X}
  1423. X
  1424. Xvoid
  1425. XFstabEntry(file,fs_type,name_on_server,server_hostname,mount_mode,mount_point)
  1426. X    FILE *file;
  1427. X    char *fs_type,*name_on_server,*server_hostname,*mount_mode,*mount_point;
  1428. X{
  1429. X    char *p;
  1430. X    for(p = fs_type; *p; p++) *p = tolower(*p);
  1431. X    fprintf(file,"%s@%s:%s:r%s:0:0:%s:hard,intr:\n",
  1432. X    name_on_server,server_hostname,mount_point,
  1433. X    mount_mode,fs_type);
  1434. X}
  1435. X
  1436. XPrintFstab(file)
  1437. X    FILE *file;
  1438. X{
  1439. X    printfunc = FstabEntry;
  1440. X    FilesysEngine(file);
  1441. X}
  1442. X
  1443. X/*
  1444. X * /etc/default/filesys format as seen on SCO unix.
  1445. X */
  1446. Xvoid
  1447. XFilesysEntry(file,fs_type,name_on_server,server_hostname,mount_mode,mount_point)
  1448. X    FILE *file;
  1449. X    char *fs_type,*name_on_server,*server_hostname,*mount_mode,*mount_point;
  1450. X{
  1451. X    fprintf(file,"bdev=%s:%s mountdir=%s fsck=no rcfsck=no \\\n",
  1452. X       server_hostname,name_on_server,mount_point);
  1453. X    fprintf(file,"rcmount=yes mount=yes fstyp=%s nfsopts=\"hard,intr\"\n\n",
  1454. X       fs_type);
  1455. X}
  1456. X
  1457. XPrintFilesys(file)
  1458. X    FILE *file;
  1459. X{
  1460. X    printfunc = FilesysEntry;
  1461. X    FilesysEngine(file);
  1462. X}
  1463. X
  1464. Xvoid
  1465. XChecklistEntry(file,fs_type,
  1466. X  name_on_server,server_hostname,mount_mode,mount_point)
  1467. X    FILE *file;
  1468. X    char *fs_type,*name_on_server,*server_hostname,*mount_mode,*mount_point;
  1469. X{
  1470. X    char *p;
  1471. X    for(p = fs_type; *p; p++) *p = tolower(*p);
  1472. X    fprintf(file,"%s:%s %s %s r%s,hard,intr 0 0 # loaded from ns2tab\n",
  1473. X    server_hostname,name_on_server,mount_point,fs_type,mount_mode);
  1474. X}
  1475. X
  1476. XPrintChecklist(file)
  1477. X{
  1478. X    printfunc = ChecklistEntry;
  1479. X    FilesysEngine(file);
  1480. X}
  1481. X
  1482. Xvoid
  1483. XVfstabEntry(file,fs_type,
  1484. X  name_on_server,server_hostname,mount_mode,mount_point)
  1485. X    FILE *file;
  1486. X    char *fs_type,*name_on_server,*server_hostname,*mount_mode,*mount_point;
  1487. X{
  1488. X    char *p;
  1489. X    for(p = fs_type; *p; p++) *p = tolower(*p);
  1490. X    fprintf(file,"%s:%s - %s %s - yes r%s,hard,intr\n",
  1491. X    server_hostname,name_on_server,mount_point,fs_type,mount_mode);
  1492. X}
  1493. X
  1494. XPrintVfstab(file)
  1495. X{
  1496. X    printfunc = VfstabEntry;
  1497. X    FilesysEngine(file);
  1498. X}
  1499. X
  1500. Xvoid
  1501. XPrintPasswd(file)
  1502. X    FILE *file;
  1503. X{
  1504. X    int starting= TRUE;
  1505. X    int first;
  1506. X    struct txt_ent *name,*key;
  1507. X
  1508. X    while(htab_list(txt_tab,starting,&name,&key))
  1509. X    {
  1510. X    starting = FALSE;
  1511. X    fprintf(file,"%s\n",name->txt);
  1512. X    }
  1513. X}
  1514. X#endif /* EMULATE_HESIOD */
  1515. X
  1516. Xtypedef int (*intfunc)();
  1517. X
  1518. Xstruct stylerec {
  1519. X     char *name;
  1520. X     int  parselen;
  1521. X     intfunc func;
  1522. X     char *infix;
  1523. X} Styles[] = {
  1524. X    { "lelm",4,PrintLElm ,""},
  1525. X    { "elm",3, PrintElm ,""},
  1526. X    { "aliases",3, PrintMail ,""},
  1527. X    { "group",3, PrintGroup ,""},
  1528. X    { "nrgroup",3, PrintNrGroup ,""},
  1529. X    { "pwupd",5, PWUpd ,""},
  1530. X    { "hosts",5, PrintHosts ,""},
  1531. X    { "subdomain",4,PrintSubdomains,""},
  1532. X#ifdef EMULATE_HESIOD
  1533. X    { "printcap",8,PrintPrintcap,"pcap"},
  1534. X    { "fstab",5,PrintFstab,"filsys"},
  1535. X    { "vfstab",5,PrintVfstab,"filsys"},
  1536. X    { "filesys",7,PrintFilesys,"filsys"},
  1537. X    { "checklist",6,PrintChecklist,"filsys"},
  1538. X    { "passwd",7,PrintPasswd,"passwd"},
  1539. X#endif /* EMULATE_HESIOD */
  1540. X};
  1541. X
  1542. Xstatic intfunc stylefunc = PrintMail;
  1543. X
  1544. Xint
  1545. XSetStyle(style)
  1546. X    char *style;
  1547. X{
  1548. X    int x;
  1549. X
  1550. X    for(x = 0; x < (sizeof(Styles)/sizeof(Styles[0])); x++)
  1551. X    if(!strncmp(Styles[x].name,style,Styles[x].parselen))
  1552. X    {
  1553. X        stylefunc = Styles[x].func;
  1554. X#ifdef EMULATE_HESIOD
  1555. X        if(*Styles[x].infix)
  1556. X        {
  1557. X        char *v;
  1558. X        v = malloc(strlen(vdomain) + strlen(Styles[x].infix) + 4);
  1559. X        sprintf(v,"%s.%s",Styles[x].infix,vdomain);
  1560. X        vdomain = v;
  1561. X        }
  1562. X#endif /* EMULATE_HESIOD */
  1563. X        return 0;
  1564. X    }
  1565. X    fprintf(stderr,"Unimplemented style: %s\n",style);
  1566. X    return -1;
  1567. X}
  1568. X
  1569. Xextern int hasprinted;
  1570. X
  1571. XPrintStyle(file)
  1572. X    FILE *file;
  1573. X{
  1574. X    hasprinted = 1;
  1575. X    (*stylefunc)(file);
  1576. X}
  1577. END_OF_FILE
  1578. if test 32658 -ne `wc -c <'list.c'`; then
  1579.     echo shar: \"'list.c'\" unpacked with wrong size!
  1580. fi
  1581. # end of 'list.c'
  1582. fi
  1583. echo shar: End of archive 3 \(of 3\).
  1584. cp /dev/null ark3isdone
  1585. MISSING=""
  1586. for I in 1 2 3 ; do
  1587.     if test ! -f ark${I}isdone ; then
  1588.     MISSING="${MISSING} ${I}"
  1589.     fi
  1590. done
  1591. if test "${MISSING}" = "" ; then
  1592.     echo You have unpacked all 3 archives.
  1593.     rm -f ark[1-9]isdone
  1594. else
  1595.     echo You still need to unpack the following archives:
  1596.     echo "        " ${MISSING}
  1597. fi
  1598. ##  End of shell archive.
  1599. exit 0
  1600.