home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume25 / hostcvt / main.c < prev    next >
C/C++ Source or Header  |  1992-01-03  |  10KB  |  464 lines

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/socket.h>
  4. #include <netinet/in.h>
  5. #include <arpa/inet.h>
  6. #include <netdb.h>
  7. #include <sys/stat.h>
  8. #include <sys/file.h>
  9.  
  10. #ifndef lint
  11. static char *RCSid = "$Id: main.c,v 1.4 91/11/25 17:46:06 rogers Release $";
  12.  
  13. #endif
  14.  
  15. struct netlist {
  16.     char *nl_net;        /* Net number portion     */
  17.     int nl_netlen;        /* Length of above     */
  18.     char *nl_file;        /* File name          */
  19.     FILE *nl_fp;        /* Pointer to above     */
  20.     struct netlist *nl_next;    /* Next one         */
  21. };
  22.  
  23. typedef struct netlist nl_t;
  24. typedef struct netlist *nl_tp;
  25.  
  26. struct host_names {
  27.     char *h_name;
  28.     char **h_aliases;
  29.     struct host_names *h_next;
  30. };
  31.  
  32. typedef struct host_names hn_t;
  33. typedef struct host_names *hn_tp;
  34.  
  35. char *soa = NULL;        /* The soa from argv[]         */
  36. char *domain = NULL;        /* Domain name from argv[]     */
  37. nl_tp ntop = NULL;        /* Top of linked list         */
  38. hn_tp hntop = NULL;        /* Top of list of hostnames     */
  39. char *hostsfile, *netfile, *soafile, *outputfile;
  40. extern char *optarg;        /* for egetopt() */
  41.  
  42. extern int optind;        /* for egetopt() */
  43. extern int errno;
  44. extern char *sys_errlist[];
  45.  
  46. #define ERR    sys_errlist[errno], errno
  47.  
  48. void exit();
  49.  
  50. main(argc, argv)
  51. int argc;
  52. char *argv[];
  53. {
  54.     FILE *fopen();
  55.     char *strsave(), *malloc();
  56.     struct hostent *mygethostent();
  57.     register struct hostent *hp;
  58.     register FILE *fp;
  59.     register char *ipaddr, **cpp;
  60.     register nl_tp np;
  61.     struct in_addr foo;
  62.  
  63.     char ch;
  64.     int hostflag, soaflag, netflag, errflag, outputflag, domainflag;
  65.  
  66.     hostflag = soaflag = netflag = errflag = outputflag = domainflag = 0;
  67.     hostsfile = soafile = netfile = domain = outputfile = NULL;
  68.  
  69.  
  70.     while ((ch = egetopt(argc, argv, "h:n:o:s:")) != -1)
  71.     switch (ch) {
  72.         case 'h':        /* assign name for "hosts" file (sourcefile) */
  73.         if (hostflag){
  74.             errflag++;
  75.         }
  76.         else {
  77.             hostsfile = strsave(optarg);
  78.             hostflag++;
  79.         }
  80.         break;
  81.  
  82.         case 'n':        /* assign name for "netlist" */
  83.         if (netflag){
  84.             errflag++;
  85.         }
  86.         else {
  87.             netfile = strsave(optarg);
  88.             netflag++;
  89.         }
  90.         break;
  91.  
  92.         case 'o':        /* assign name for main output file */
  93.         if (outputflag){
  94.             errflag++;
  95.         }
  96.         else {
  97.             outputfile = strsave(optarg);
  98.             outputflag++;
  99.         }
  100.         break;
  101.  
  102.         case 's':        /* assign name for "soabasefile" */
  103.         if (soaflag){
  104.             errflag++;
  105.         }
  106.         else {
  107.             soafile = strsave(optarg);
  108.             soaflag++;
  109.         }
  110.         break;
  111.  
  112.         case '?':        /* anything else that might show up */
  113.         errflag++;
  114.  
  115.     }            /* switch */
  116.  
  117.     for (; optind < argc; optind++) {
  118.     if (domainflag) {
  119.         errflag++;
  120.         break;
  121.     }            /* if */
  122.     else {
  123.         domain = strsave(argv[optind]);
  124.         domainflag++;
  125.     }            /* else */
  126.     }                /* for */
  127.  
  128.     if (errflag || domain == NULL || (strlen(domain) < 2)) {
  129.     (void) fprintf(stderr, "usage: hostcvt [-h hostsfile] [-n netlistfile]\n\t\t[-s soabasefile] [-o outputfile] domain\n");
  130.     exit(2);
  131.     }
  132.  
  133.     if (!netflag){
  134.     netfile = strsave("netlist");
  135.     }
  136.  
  137.     if (!hostflag){
  138.     hostsfile = strsave("hosts.thisdomain");
  139.     }
  140.  
  141.     if (!soafile) {
  142.     soafile = strsave("soabasefile");
  143.     }
  144.     if (!outputflag){
  145.     outputfile = domain;
  146.     }
  147.  
  148.     rdsoa(soafile);
  149.  
  150.     (void)close(0);
  151.     (void)close(1);
  152.  
  153.     if((fp = fopen(outputfile, "w")) == NULL) {
  154.     (void) fprintf(stderr, "hostcvt: could not open %s\n", outputfile);
  155.     exit(1);
  156.     }
  157.  
  158.     if(access(hostsfile, R_OK) == -1) {
  159.     (void) fprintf(stderr, "hostcvt: no host file %s\n", hostsfile);
  160.     exit(1);
  161.     }
  162.  
  163.     if(soa != NULL) {
  164.     (void) fputs(soa, fp);
  165.     }
  166.  
  167.     rdnetlist();
  168.  
  169.     while ((hp = mygethostent(hostsfile)) != NULL) {
  170.     foo.s_addr = (u_long) * ((u_long *) hp->h_addr);
  171.     ipaddr = inet_ntoa(foo);
  172.     if (outnet(ipaddr, hp->h_name)) {
  173.  
  174.         if (isdup(hp)){
  175.         continue;
  176.         }
  177.  
  178.         if (strlen(hp->h_name) == 0) {
  179.         (void)fprintf(stderr, "No name found for %s -- ignoring...\n", ipaddr);
  180.         }
  181.         else {
  182.         savehp(hp);
  183.  
  184.         (void) fprintf(fp, "%s\t\tIN\tA\t%s\n", hp->h_name, ipaddr);
  185.  
  186.         for (cpp = hp->h_aliases; *cpp != NULL; cpp++) {
  187.             if (strcasecmp(*cpp, hp->h_name) != 0) {
  188.             (void) fprintf(fp, "%s\t\tIN\tCNAME\t%s\n", *cpp, hp->h_name);
  189.             }
  190.         }        /* else */
  191.         }
  192.     }
  193.     }
  194.     (void) fflush(fp);
  195.     (void) fclose(fp);
  196.     for (np = ntop; np != NULL; np = np->nl_next) {
  197.     (void) fflush(np->nl_fp);
  198.     (void) fclose(np->nl_fp);
  199.     }
  200.  
  201.     return(0);
  202. }
  203.  
  204. /*
  205.  * See if the new hostname or any of it's aliases
  206.  * are already known.
  207.  */
  208.  
  209. int
  210. isdup(hp)
  211. register struct hostent *hp;
  212. {
  213.     register hn_tp np;
  214.     register char **cpp, **acp;
  215.  
  216.     /*
  217.      * For each node in our linked list of known names....
  218.      */
  219.  
  220.     for (np = hntop; np != NULL; np = np->h_next) {
  221.  
  222.     /*
  223.      * See if the new name matches directly
  224.      */
  225.  
  226.     if (strcasecmp(hp->h_name, np->h_name) == 0) {
  227.         (void) fprintf(stderr, "hostcvt: duplicated name: %s\n", hp->h_name);
  228.         return (1);
  229.     }
  230.  
  231.     /*
  232.      * See if the new name matches an alias
  233.      */
  234.  
  235.     for (acp = np->h_aliases; *acp != NULL; acp++) {
  236.         if (strcasecmp(hp->h_name, *acp) == 0) {
  237.         (void) fprintf(stderr, "hostcvt: duplicated name to alias: %s\n", hp->h_name);
  238.         return (1);
  239.         }
  240.     }
  241.  
  242.     /*
  243.      * For each of the new machines aliases
  244.      */
  245.  
  246.     for (cpp = hp->h_aliases; *cpp != NULL; cpp++) {
  247.  
  248.         /*
  249.          * See if the alias matches the real name
  250.          */
  251.  
  252.         if (strcasecmp(*cpp, np->h_name) == 0) {
  253.         (void) fprintf(stderr, "hostcvt: duplicated alias to name: %s\n", hp->h_name);
  254.         return (1);
  255.         }
  256.  
  257.         /*
  258.          * See if the alias matches one of our aliases
  259.          */
  260.  
  261.         for (acp = np->h_aliases; *acp != NULL; acp++) {
  262.         if (strcasecmp(*acp, *cpp) == 0) {
  263.             (void) fprintf(stderr, "hostcvt: duplicated alias to alias: %s\n", hp->h_name);
  264.             return (1);
  265.         }
  266.         }
  267.     }
  268.     }
  269.  
  270.     return (0);            /* No match     */
  271. }
  272.  
  273. savehp(hp)
  274. register struct hostent *hp;
  275. {
  276.     char *malloc(), *strsave();
  277.     register char **cpp, **acp;
  278.     register int cnt;
  279.     register hn_tp np;
  280.  
  281.     if ((np = (hn_tp) malloc(sizeof(hn_t))) == NULL) {
  282.     (void) fprintf(stderr, "hostcvt: could not malloc in savehp()!\n");
  283.     exit(1);
  284.     }
  285.  
  286.     np->h_name = strsave(hp->h_name);
  287.  
  288.     for (cnt = 1, cpp = hp->h_aliases; *cpp != NULL; cpp++)
  289.     cnt++;
  290.  
  291.     if ((np->h_aliases = (char **) malloc((unsigned) (cnt * sizeof(char **)))) == NULL) {
  292.     (void) fprintf(stderr, "hostcvt: could not malloc in savehp()!\n");
  293.     exit(1);
  294.     }
  295.  
  296.     for (cpp = hp->h_aliases, acp = np->h_aliases; *cpp != NULL; cpp++, acp++) {
  297.     *acp = strsave(*cpp);
  298.     }
  299.     *acp = NULL;
  300.  
  301.     np->h_next = hntop;
  302.     hntop = np;
  303. }
  304.  
  305. /*
  306.  * Add the host named "name" at the IP address "ip" to
  307.  * the proper net file.  Return 1 if done OK, 0 if not.
  308.  */
  309.  
  310. int
  311. outnet(ip, name)
  312. char *ip, *name;
  313. {
  314.     char *strcpy(), *index(), *strsave();
  315.     register nl_tp np;
  316.     register int i;
  317.     register char *last, *cp, *ipaddr;
  318.     char dig[4][20];
  319.  
  320.     ipaddr = strsave(ip);
  321.  
  322.     for (np = ntop; np != NULL; np = np->nl_next) {
  323.     if (strncmp(ipaddr, np->nl_net, np->nl_netlen) == 0) {
  324.         last = ipaddr + np->nl_netlen;
  325.         bzero((char *) dig, sizeof(dig));
  326.  
  327.         for (i = 0; *last != '\0'; i++) {
  328.         if ((cp = index(last, '.')) == NULL){
  329.             break;
  330.         }
  331.  
  332.         *cp = '\0';
  333.         (void) strcpy(dig[i], last);
  334.         last = cp + 1;
  335.         }
  336.  
  337.         (void) fprintf(np->nl_fp, "%s", last);
  338.  
  339.         for (i = 3; i >= 0; i--) {
  340.         if (dig[i][0] != '\0'){
  341.             (void) fprintf(np->nl_fp, ".%s", dig[i]);
  342.         }
  343.         }
  344.         (void) fprintf(np->nl_fp, "\t\tIN\tPTR\t%s.%s.\n", name, domain);
  345.         return (1);
  346.     }
  347.     }
  348.     (void) fprintf(stderr, "hostcvt: could not find file for %s (add= %s)\n", name, ipaddr);
  349.     return (0);
  350. }
  351.  
  352. rdnetlist()
  353. {
  354.     char *strsave(), *malloc(), *index();
  355.     FILE *fopen();
  356.     register FILE *fp;
  357.     register nl_tp np;
  358.     register int i, cnt;
  359.     char nbuf[256], fbuf[512], buf[BUFSIZ];
  360.  
  361.     if ((fp = fopen(netfile, "r")) == NULL) {
  362.     (void) fprintf(stderr, "hostcvt: could not open %s\n", netfile);
  363.     exit(1);
  364.     }
  365.  
  366.     for (i = 1, cnt = 0; fgets(buf, BUFSIZ, fp) != NULL; i++) {
  367.     if (buf[0] == '#' || buf[0] == '\n'){    /* allow comments and blanks     */
  368.         continue;
  369.     }
  370.  
  371.     if (sscanf(buf, "%s %s", nbuf, fbuf) != 2) {
  372.         (void) fprintf(stderr, "hostcvt: error on line #%d in %s, contents= %s", i, netfile, buf);
  373.         continue;
  374.     }
  375.  
  376.     if ((np = (nl_tp) malloc(sizeof(nl_t))) == NULL) {
  377.         (void) fprintf(stderr, "hostcvt: could not malloc!\n");
  378.         exit(1);
  379.     }
  380.     np->nl_net = strsave(nbuf);
  381.     np->nl_netlen = strlen(nbuf);
  382.     np->nl_file = strsave(fbuf);
  383.     np->nl_fp = NULL;
  384.     np->nl_next = ntop;
  385.     ntop = np;
  386.     cnt++;
  387.     }
  388.     (void) fclose(fp);
  389.  
  390.     /*
  391.      * figure out how many open files we can have: Max (getdtablesize) minus:
  392.      * 1 for stderr (stdin & stdout closed) 1 for domain (output) file
  393.      * (argv[1])
  394.      */
  395.  
  396.     i = getdtablesize() - 2;
  397.     if (cnt > i) {
  398.     (void) fprintf(stderr, "hostcvt: can not have more than %d entries (you have %d)\n", i, cnt);
  399.     exit(1);
  400.     }
  401.  
  402.     for (np = ntop; np != NULL; np = np->nl_next) {
  403.     if ((np->nl_fp = fopen(np->nl_file, "w")) == NULL) {
  404.         (void) fprintf(stderr, "hostcvt: could not open %s for write\n", np->nl_file);
  405.         continue;
  406.     }
  407.     if (soa != NULL) {
  408.         (void) fputs(soa, np->nl_fp);
  409.     }
  410.     }
  411. }
  412.  
  413. rdsoa(file)
  414. char *file;
  415. {
  416.     int read(), open(), fstat();
  417.     register int fd, rv;
  418.     struct stat stb;
  419.  
  420.     if ((fd = open(file, O_RDONLY, 0)) == -1) {
  421.     soa = NULL;
  422.     (void) fprintf(stderr, "hostcvt: could not open SOA file, skipping\n");
  423.     return;
  424.     }
  425.  
  426.     if (fstat(fd, &stb) == -1) {
  427.     (void) fprintf(stderr, "hostcvt: could not fstat %s (%d)\n", ERR);
  428.     exit(1);
  429.     }
  430.  
  431.     if ((soa = malloc((unsigned) stb.st_size)) == NULL) {
  432.     (void) fprintf(stderr, "hostcvt: could not malloc enough for SOA file (%s)\n", file);
  433.     exit(1);
  434.     }
  435.  
  436.     if ((rv = read(fd, soa, (int) stb.st_size)) != stb.st_size) {
  437.     (void) fprintf(stderr, "hostcvt: asked to read %d, got %d", (int) stb.st_size, rv);
  438.     if (rv == -1){
  439.         (void) fprintf(stderr, " - %s (%d)", ERR);
  440.     }
  441.  
  442.     (void) fprintf(stderr, "\n");
  443.     exit(1);
  444.     }
  445.  
  446.     (void) close(fd);
  447. }
  448.  
  449. char *
  450. strsave(str)
  451. register char *str;
  452. {
  453.     char *malloc(), *strcpy();
  454.     register char *cp;
  455.  
  456.     if (str == NULL)
  457.     return (NULL);
  458.  
  459.     if ((cp = malloc((unsigned) (strlen(str) + 1))) != NULL)
  460.     (void) strcpy(cp, str);
  461.  
  462.     return (cp);
  463. }
  464.