home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / bootpd-2.zip / DUMPTAB.C < prev    next >
C/C++ Source or Header  |  1995-02-15  |  9KB  |  383 lines

  1. /*
  2.  * dumptab.c - handles dumping the database
  3.  */
  4.  
  5. #include <sys/types.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>            /* inet_ntoa */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <syslog.h>
  12. #include <time.h>
  13.  
  14. #ifndef USE_BFUNCS
  15. #include <memory.h>
  16. /* Yes, memcpy is OK here (no overlapped copies). */
  17. #define bcopy(a,b,c)    memcpy(b,a,c)
  18. #define bzero(p,l)      memset(p,0,l)
  19. #define bcmp(a,b,c)     memcmp(a,b,c)
  20. #endif
  21.  
  22. #include "bootp.h"
  23. #include "hash.h"
  24. #include "hwaddr.h"
  25. #include "report.h"
  26. #include "patchlevel.h"
  27. #include "bootpd.h"
  28.  
  29. #ifdef    __STDC__
  30. #define P(args) args
  31. #else
  32. #define P(args) ()
  33. #endif
  34.  
  35. static void dump_generic P((FILE *, struct shared_bindata *));
  36. static void dump_host P((FILE *, struct host *));
  37. static void list_ipaddresses P((FILE *, struct in_addr_list *));
  38.  
  39. #undef P
  40.  
  41. #ifndef    DEBUG
  42. void
  43. dumptab(filename)
  44.     char *filename;
  45. {
  46.     report(LOG_INFO, "No dumptab support!");
  47. }
  48.  
  49. #else /* DEBUG */
  50.  
  51. /*
  52.  * Dump the internal memory database to bootpd_dump.
  53.  */
  54.  
  55. void
  56. dumptab(filename)
  57.     char *filename;
  58. {
  59.     int n;
  60.     struct host *hp;
  61.     FILE *fp;
  62.     long t;
  63.     /* Print symbols in alphabetical order for reader's convenience. */
  64.     static char legend[] = "#\n# Legend:\t(see bootptab.5)\n\
  65. #\tfirst field -- hostname (not indented)\n\
  66. #\tbf -- bootfile\n\
  67. #\tbs -- bootfile size in 512-octet blocks\n\
  68. #\tcs -- cookie servers\n\
  69. #\tdf -- dump file name\n\
  70. #\tdn -- domain name\n\
  71. #\tds -- domain name servers\n\
  72. #\tef -- extension file\n\
  73. #\tex -- exec file (YORK_EX_OPTION)\n\
  74. #\tgw -- gateways\n\
  75. #\tha -- hardware address\n\
  76. #\thd -- home directory for bootfiles\n\
  77. #\thn -- host name set for client\n\
  78. #\tht -- hardware type\n\
  79. #\tim -- impress servers\n\
  80. #\tip -- host IP address\n\
  81. #\tlg -- log servers\n\
  82. #\tlp -- LPR servers\n\
  83. #\tms -- message size\n\
  84. #\tmw -- min wait (secs)\n\
  85. #\tns -- IEN-116 name servers\n\
  86. #\tnt -- NTP servers (RFC 1129)\n\
  87. #\tra -- reply address override\n\
  88. #\trl -- resource location protocol servers\n\
  89. #\trp -- root path\n\
  90. #\tsa -- boot server address\n\
  91. #\tsm -- subnet mask\n\
  92. #\tsw -- swap server\n\
  93. #\ttc -- template host (points to similar host entry)\n\
  94. #\ttd -- TFTP directory\n\
  95. #\tto -- time offset (seconds)\n\
  96. #\tts -- time servers\n\
  97. #\tvm -- vendor magic number\n\
  98. #\tyd -- YP (NIS) domain\n\
  99. #\tys -- YP (NIS) servers\n\
  100. #\tTn -- generic option tag n\n\
  101. \n";
  102.  
  103.     /*
  104.      * Open bootpd.dump file.
  105.      */
  106.     if ((fp = fopen(filename, "w")) == NULL) {
  107.         report(LOG_ERR, "error opening \"%s\": %s",
  108.                filename, get_errmsg());
  109.         exit(1);
  110.     }
  111.     t = time(NULL);
  112.     fprintf(fp, "\n# %s %s.%d\n", progname, VERSION, PATCHLEVEL);
  113.     fprintf(fp, "# %s: dump of bootp server database.\n", filename);
  114.     fprintf(fp, "# Dump taken %s", ctime(&t));
  115.     fwrite(legend, 1, sizeof(legend) - 1, fp);
  116.  
  117.     n = 0;
  118.     for (hp = (struct host *) hash_FirstEntry(nmhashtable); hp != NULL;
  119.          hp = (struct host *) hash_NextEntry(nmhashtable)) {
  120.         dump_host(fp, hp);
  121.         fprintf(fp, "\n");
  122.         n++;
  123.     }
  124.     fclose(fp);
  125.  
  126.     report(LOG_INFO, "dumped %d entries to \"%s\".", n, filename);
  127. }
  128.  
  129.  
  130.  
  131. /*
  132.  * Dump all the available information on the host pointed to by "hp".
  133.  * The output is sent to the file pointed to by "fp".
  134.  */
  135.  
  136. static void
  137. dump_host(fp, hp)
  138.     FILE *fp;
  139.     struct host *hp;
  140. {
  141.     /* Print symbols in alphabetical order for reader's convenience. */
  142.     if (hp) {
  143.         fprintf(fp, "%s:", (hp->hostname ?
  144.                             hp->hostname->string : "?"));
  145.         if (hp->flags.bootfile) {
  146.             fprintf(fp, "\\\n\t:bf=%s:", hp->bootfile->string);
  147.         }
  148.         if (hp->flags.bootsize) {
  149.             fprintf(fp, "\\\n\t:bs=");
  150.             if (hp->flags.bootsize_auto) {
  151.                 fprintf(fp, "auto:");
  152.             } else {
  153.                 fprintf(fp, "%d:", hp->bootsize);
  154.             }
  155.         }
  156.         if (hp->flags.cookie_server) {
  157.             fprintf(fp, "\\\n\t:cs=");
  158.             list_ipaddresses(fp, hp->cookie_server);
  159.             fprintf(fp, ":");
  160.         }
  161.         if (hp->flags.dump_file) {
  162.             fprintf(fp, "\\\n\t:df=%s:", hp->dump_file->string);
  163.         }
  164.         if (hp->flags.domain_name) {
  165.             fprintf(fp, "\\\n\t:dn=%s:", hp->domain_name->string);
  166.         }
  167.         if (hp->flags.domain_server) {
  168.             fprintf(fp, "\\\n\t:ds=");
  169.             list_ipaddresses(fp, hp->domain_server);
  170.             fprintf(fp, ":");
  171.         }
  172.         if (hp->flags.exten_file) {
  173.             fprintf(fp, "\\\n\t:ef=%s:", hp->exten_file->string);
  174.         }
  175.         if (hp->flags.exec_file) {
  176.             fprintf(fp, "\\\n\t:ex=%s:", hp->exec_file->string);
  177.         }
  178.         if (hp->flags.gateway) {
  179.             fprintf(fp, "\\\n\t:gw=");
  180.             list_ipaddresses(fp, hp->gateway);
  181.             fprintf(fp, ":");
  182.         }
  183.         /* FdC: swap_server (see below) */
  184.         if (hp->flags.homedir) {
  185.             fprintf(fp, "\\\n\t:hd=%s:", hp->homedir->string);
  186.         }
  187.         /* FdC: dump_file (see above) */
  188.         /* FdC: domain_name (see above) */
  189.         /* FdC: root_path (see below) */
  190.         if (hp->flags.name_switch && hp->flags.send_name) {
  191.             fprintf(fp, "\\\n\t:hn:");
  192.         }
  193.         if (hp->flags.htype) {
  194.             int hlen = haddrlength(hp->htype);
  195.             fprintf(fp, "\\\n\t:ht=%u:", (unsigned) hp->htype);
  196.             if (hp->flags.haddr) {
  197.                 fprintf(fp, "ha=\"%s\":",
  198.                         haddrtoa(hp->haddr, hlen));
  199.             }
  200.         }
  201.         if (hp->flags.impress_server) {
  202.             fprintf(fp, "\\\n\t:im=");
  203.             list_ipaddresses(fp, hp->impress_server);
  204.             fprintf(fp, ":");
  205.         }
  206.         /* NetBSD: swap_server (see below) */
  207.         if (hp->flags.iaddr) {
  208.             fprintf(fp, "\\\n\t:ip=%s:", inet_ntoa(hp->iaddr));
  209.         }
  210.         if (hp->flags.log_server) {
  211.             fprintf(fp, "\\\n\t:lg=");
  212.             list_ipaddresses(fp, hp->log_server);
  213.             fprintf(fp, ":");
  214.         }
  215.         if (hp->flags.lpr_server) {
  216.             fprintf(fp, "\\\n\t:lp=");
  217.             list_ipaddresses(fp, hp->lpr_server);
  218.             fprintf(fp, ":");
  219.         }
  220.         if (hp->flags.msg_size) {
  221.             fprintf(fp, "\\\n\t:ms=%d:", hp->msg_size);
  222.         }
  223.         if (hp->flags.min_wait) {
  224.             fprintf(fp, "\\\n\t:mw=%d:", hp->min_wait);
  225.         }
  226.         if (hp->flags.name_server) {
  227.             fprintf(fp, "\\\n\t:ns=");
  228.             list_ipaddresses(fp, hp->name_server);
  229.             fprintf(fp, ":");
  230.         }
  231.         if (hp->flags.ntp_server) {
  232.             fprintf(fp, "\\\n\t:nt=");
  233.             list_ipaddresses(fp, hp->ntp_server);
  234.             fprintf(fp, ":");
  235.         }
  236.         if (hp->flags.reply_addr) {
  237.             fprintf(fp, "\\\n\t:ra=%s:", inet_ntoa(hp->reply_addr));
  238.         }
  239.         if (hp->flags.rlp_server) {
  240.             fprintf(fp, "\\\n\t:rl=");
  241.             list_ipaddresses(fp, hp->rlp_server);
  242.             fprintf(fp, ":");
  243.         }
  244.         if (hp->flags.root_path) {
  245.             fprintf(fp, "\\\n\t:rp=%s:", hp->root_path->string);
  246.         }
  247.         if (hp->flags.bootserver) {
  248.             fprintf(fp, "\\\n\t:sa=%s:", inet_ntoa(hp->bootserver));
  249.         }
  250.         if (hp->flags.subnet_mask) {
  251.             fprintf(fp, "\\\n\t:sm=%s:", inet_ntoa(hp->subnet_mask));
  252.         }
  253.         if (hp->flags.swap_server) {
  254.             fprintf(fp, "\\\n\t:sw=%s:", inet_ntoa(hp->subnet_mask));
  255.         }
  256.         if (hp->flags.tftpdir) {
  257.             fprintf(fp, "\\\n\t:td=%s:", hp->tftpdir->string);
  258.         }
  259.         /* NetBSD: rootpath (see above) */
  260.         /* NetBSD: domainname (see above) */
  261.         /* NetBSD: dumpfile (see above) */
  262.         if (hp->flags.time_offset) {
  263.             fprintf(fp, "\\\n\t:to=%ld:", hp->time_offset);
  264.         }
  265.         if (hp->flags.time_server) {
  266.             fprintf(fp, "\\\n\t:ts=");
  267.             list_ipaddresses(fp, hp->time_server);
  268.             fprintf(fp, ":");
  269.         }
  270.         if (hp->flags.vm_cookie) {
  271.             fprintf(fp, "\\\n\t:vm=");
  272.             if (!bcmp(hp->vm_cookie, vm_rfc1048, 4)) {
  273.                 fprintf(fp, "rfc1048:");
  274.             } else if (!bcmp(hp->vm_cookie, vm_cmu, 4)) {
  275.                 fprintf(fp, "cmu:");
  276.             } else {
  277.                 fprintf(fp, "%d.%d.%d.%d:",
  278.                         (int) ((hp->vm_cookie)[0]),
  279.                         (int) ((hp->vm_cookie)[1]),
  280.                         (int) ((hp->vm_cookie)[2]),
  281.                         (int) ((hp->vm_cookie)[3]));
  282.             }
  283.         }
  284.         if (hp->flags.nis_domain) {
  285.             fprintf(fp, "\\\n\t:yd=%s:",
  286.                     hp->nis_domain->string);
  287.         }
  288.         if (hp->flags.nis_server) {
  289.             fprintf(fp, "\\\n\t:ys=");
  290.             list_ipaddresses(fp, hp->nis_server);
  291.             fprintf(fp, ":");
  292.         }
  293.         /*
  294.          * XXX - Add new tags here (or above,
  295.          * so they print in alphabetical order).
  296.          */
  297.  
  298.         if (hp->flags.generic) {
  299.             dump_generic(fp, hp->generic);
  300.         }
  301.     }
  302. }
  303.  
  304.  
  305. static void
  306. dump_generic(fp, generic)
  307.     FILE *fp;
  308.     struct shared_bindata *generic;
  309. {
  310.     u_char *bp = generic->data;
  311.     u_char *ep = bp + generic->length;
  312.     u_char tag;
  313.     int len;
  314.  
  315.     while (bp < ep) {
  316.         tag = *bp++;
  317.         if (tag == TAG_PAD)
  318.             continue;
  319.         if (tag == TAG_END)
  320.             return;
  321.         len = *bp++;
  322.         if (bp + len > ep) {
  323.             fprintf(fp, " #junk in generic! :");
  324.             return;
  325.         }
  326.         fprintf(fp, "\\\n\t:T%d=", tag);
  327.         while (len) {
  328.             fprintf(fp, "%02X", *bp);
  329.             bp++;
  330.             len--;
  331.             if (len)
  332.                 fprintf(fp, ".");
  333.         }
  334.         fprintf(fp, ":");
  335.     }
  336. }
  337.  
  338.  
  339.  
  340. /*
  341.  * Dump an entire struct in_addr_list of IP addresses to the indicated file.
  342.  *
  343.  * The addresses are printed in standard ASCII "dot" notation and separated
  344.  * from one another by a single space.  A single leading space is also
  345.  * printed before the first adddress.
  346.  *
  347.  * Null lists produce no output (and no error).
  348.  */
  349.  
  350. static void
  351. list_ipaddresses(fp, ipptr)
  352.     FILE *fp;
  353.     struct in_addr_list *ipptr;
  354. {
  355.     unsigned count;
  356.     struct in_addr *addrptr;
  357.  
  358.     if (ipptr) {
  359.         count = ipptr->addrcount;
  360.         addrptr = ipptr->addr;
  361.         while (count > 0) {
  362.             fprintf(fp, "%s", inet_ntoa(*addrptr++));
  363.             count--;
  364.             if (count)
  365.                 fprintf(fp, ", ");
  366.         }
  367.     }
  368. }
  369.  
  370. #endif /* DEBUG */
  371.  
  372. /*
  373.  * Local Variables:
  374.  * tab-width: 4
  375.  * c-indent-level: 4
  376.  * c-argdecl-indent: 4
  377.  * c-continued-statement-offset: 4
  378.  * c-continued-brace-offset: -4
  379.  * c-label-offset: -4
  380.  * c-brace-offset: 0
  381.  * End:
  382.  */
  383.