home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / bootpd-2.zip / BOOTPEF.C < prev    next >
C/C++ Source or Header  |  1995-09-04  |  8KB  |  352 lines

  1. /************************************************************************
  2.           Copyright 1988, 1991 by Carnegie Mellon University
  3.  
  4.                           All Rights Reserved
  5.  
  6. Permission to use, copy, modify, and distribute this software and its
  7. documentation for any purpose and without fee is hereby granted, provided
  8. that the above copyright notice appear in all copies and that both that
  9. copyright notice and this permission notice appear in supporting
  10. documentation, and that the name of Carnegie Mellon University not be used
  11. in advertising or publicity pertaining to distribution of the software
  12. without specific, written prior permission.
  13.  
  14. CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  15. SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
  16. IN NO EVENT SHALL CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
  17. DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  18. PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  19. ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  20. SOFTWARE.
  21. ************************************************************************/
  22.  
  23. /*
  24.  * bootpef - BOOTP Extension File generator
  25.  *    Makes an "Extension File" for each host entry that
  26.  *    defines an and Extension File. (See RFC1497, tag 18.)
  27.  *
  28.  * HISTORY
  29.  *    See ./Changes
  30.  *
  31.  * BUGS
  32.  *    See ./ToDo
  33.  */
  34.  
  35.  
  36.  
  37. #ifdef    __STDC__
  38. #include <stdarg.h>
  39. #else
  40. #include <varargs.h>
  41. #endif
  42.  
  43. #include <sys/types.h>
  44. #include <sys/time.h>
  45.  
  46. #include <netinet/in.h>
  47. #include <arpa/inet.h>            /* inet_ntoa */
  48.  
  49. #ifndef    NO_UNISTD
  50. #include <unistd.h>
  51. #endif
  52. #include <stdlib.h>
  53. #include <stdio.h>
  54. #include <string.h>
  55. #include <errno.h>
  56. #include <ctype.h>
  57. #include <syslog.h>
  58.  
  59. #ifndef    USE_BFUNCS
  60. #include <memory.h>
  61. /* Yes, memcpy is OK here (no overlapped copies). */
  62. #define bcopy(a,b,c)    memcpy(b,a,c)
  63. #define bzero(p,l)      memset(p,0,l)
  64. #define bcmp(a,b,c)     memcmp(a,b,c)
  65. #endif
  66.  
  67. #include "bootp.h"
  68. #include "hash.h"
  69. #include "hwaddr.h"
  70. #include "bootpd.h"
  71. #include "dovend.h"
  72. #include "readfile.h"
  73. #include "report.h"
  74. #include "tzone.h"
  75. #include "patchlevel.h"
  76.  
  77. #define    BUFFERSIZE           0x4000
  78.  
  79. #ifndef CONFIG_FILE
  80. #define CONFIG_FILE        "/etc/bootptab"
  81. #endif
  82.  
  83.  
  84.  
  85. /*
  86.  * Externals, forward declarations, and global variables
  87.  */
  88.  
  89. #ifdef    __STDC__
  90. #define P(args) args
  91. #else
  92. #define P(args) ()
  93. #endif
  94.  
  95. static void mktagfile P((struct host *));
  96. static void usage P((void));
  97.  
  98. #undef P
  99.  
  100.  
  101. /*
  102.  * General
  103.  */
  104.  
  105. char *progname;
  106. char *chdir_path;
  107. int debug = 0;                    /* Debugging flag (level) */
  108. byte *buffer;
  109.  
  110. /*
  111.  * Globals below are associated with the bootp database file (bootptab).
  112.  */
  113.  
  114. char *bootptab = CONFIG_FILE;
  115.  
  116.  
  117. /*
  118.  * Print "usage" message and exit
  119.  */
  120. static void
  121. usage()
  122. {
  123.     fprintf(stderr,
  124.        "usage:  $s [ -c chdir ] [-d level] [-f configfile] [host...]\n");
  125.     fprintf(stderr, "\t -c n\tset current directory\n");
  126.     fprintf(stderr, "\t -d n\tset debug level\n");
  127.     fprintf(stderr, "\t -f n\tconfig file name\n");
  128.     exit(1);
  129. }
  130.  
  131.  
  132. /*
  133.  * Initialization such as command-line processing is done and then the
  134.  * main server loop is started.
  135.  */
  136. void
  137. main(argc, argv)
  138.     int argc;
  139.     char **argv;
  140. {
  141.     struct host *hp;
  142.     char *stmp;
  143.     int n;
  144.  
  145. #ifdef __EMX__
  146.     static char bootptab_file[256];
  147.     char *etc = getenv("ETC");
  148.     if (etc != NULL)
  149.     {
  150.       strcpy(bootptab_file, etc);
  151.       strcat(bootptab_file, "\\bootptab");
  152.       bootptab = bootptab_file;
  153.     }
  154. #endif
  155.  
  156.     progname = strrchr(argv[0], '/');
  157.     if (progname) progname++;
  158.     else progname = argv[0];
  159.  
  160.     /* Get work space for making tag 18 files. */
  161.     buffer = (byte *) malloc(BUFFERSIZE);
  162.     if (!buffer) {
  163.         report(LOG_ERR, "malloc failed");
  164.         exit(1);
  165.     }
  166.     /*
  167.      * Set defaults that might be changed by option switches.
  168.      */
  169.     stmp = NULL;
  170.  
  171.     /*
  172.      * Read switches.
  173.      */
  174.     for (argc--, argv++; argc > 0; argc--, argv++) {
  175.         if (argv[0][0] != '-')
  176.             break;
  177.         switch (argv[0][1]) {
  178.  
  179.         case 'c':                /* chdir_path */
  180.             if (argv[0][2]) {
  181.                 stmp = &(argv[0][2]);
  182.             } else {
  183.                 argc--;
  184.                 argv++;
  185.                 stmp = argv[0];
  186.             }
  187.             if (!stmp || (stmp[0] != '/')) {
  188.                 fprintf(stderr,
  189.                         "bootpd: invalid chdir specification\n");
  190.                 break;
  191.             }
  192.             chdir_path = stmp;
  193.             break;
  194.  
  195.         case 'd':                /* debug */
  196.             if (argv[0][2]) {
  197.                 stmp = &(argv[0][2]);
  198.             } else if (argv[1] && argv[1][0] == '-') {
  199.                 /*
  200.                  * Backwards-compatible behavior:
  201.                  * no parameter, so just increment the debug flag.
  202.                  */
  203.                 debug++;
  204.                 break;
  205.             } else {
  206.                 argc--;
  207.                 argv++;
  208.                 stmp = argv[0];
  209.             }
  210.             if (!stmp || (sscanf(stmp, "%d", &n) != 1) || (n < 0)) {
  211.                 fprintf(stderr,
  212.                         "bootpd: invalid debug level\n");
  213.                 break;
  214.             }
  215.             debug = n;
  216.             break;
  217.  
  218.         case 'f':                /* config file */
  219.             if (argv[0][2]) {
  220.                 stmp = &(argv[0][2]);
  221.             } else {
  222.                 argc--;
  223.                 argv++;
  224.                 stmp = argv[0];
  225.             }
  226.             bootptab = stmp;
  227.             break;
  228.  
  229.         default:
  230.             fprintf(stderr, "bootpd: unknown switch: -%c\n",
  231.                     argv[0][1]);
  232.             usage();
  233.             break;
  234.         }
  235.     }
  236.  
  237.     /* Get the timezone. */
  238.     tzone_init();
  239.  
  240.     /* Allocate hash tables. */
  241.     rdtab_init();
  242.  
  243.     /*
  244.      * Read the bootptab file.
  245.      */
  246.     readtab(1);                    /* force read */
  247.  
  248.     /* Set the cwd (i.e. to /tftpboot) */
  249.     if (chdir_path) {
  250.         if (chdir(chdir_path) < 0)
  251.             report(LOG_ERR, "%s: chdir failed", chdir_path);
  252.     }
  253.     /* If there are host names on the command line, do only those. */
  254.     if (argc > 0) {
  255.         unsigned int tlen, hashcode;
  256.  
  257.         while (argc) {
  258.             tlen = strlen(argv[0]);
  259.             hashcode = hash_HashFunction((u_char *)argv[0], tlen);
  260.             hp = (struct host *) hash_Lookup(nmhashtable,
  261.                                              hashcode,
  262.                                              nmcmp, argv[0]);
  263.             if (!hp) {
  264.                 printf("%s: no matching entry\n", argv[0]);
  265.                 exit(1);
  266.             }
  267.             if (!hp->flags.exten_file) {
  268.                 printf("%s: no extension file\n", argv[0]);
  269.                 exit(1);
  270.             }
  271.             mktagfile(hp);
  272.             argv++;
  273.             argc--;
  274.         }
  275.         exit(0);
  276.     }
  277.     /* No host names specified.  Do them all. */
  278.     hp = (struct host *) hash_FirstEntry(nmhashtable);
  279.     while (hp != NULL) {
  280.         mktagfile(hp);
  281.         hp = (struct host *) hash_NextEntry(nmhashtable);
  282.     }
  283. }
  284.  
  285.  
  286.  
  287. /*
  288.  * Make a "TAG 18" file for this host.
  289.  * (Insert the RFC1497 options.)
  290.  */
  291.  
  292. static void
  293. mktagfile(hp)
  294.     struct host *hp;
  295. {
  296.     FILE *fp;
  297.     int bytesleft, len;
  298.     byte *vp;
  299.  
  300.     if (!hp->flags.exten_file)
  301.         return;
  302.  
  303.     vp = buffer;
  304.     bytesleft = BUFFERSIZE;
  305.     bcopy(vm_rfc1048, vp, 4);    /* Copy in the magic cookie */
  306.     vp += 4;
  307.     bytesleft -= 4;
  308.  
  309.     /*
  310.      * The "extension file" options are appended by the following
  311.      * function (which is shared with bootpd.c).
  312.      */
  313.     len = dovend_rfc1497(hp, vp, bytesleft);
  314.     vp += len;
  315.     bytesleft -= len;
  316.  
  317.     if (bytesleft < 1) {
  318.         report(LOG_ERR, "%s: too much option data",
  319.                hp->exten_file->string);
  320.         return;
  321.     }
  322.     *vp++ = TAG_END;
  323.     bytesleft--;
  324.  
  325.     /* Write the buffer to the extension file. */
  326.     printf("Updating \"%s\"\n", hp->exten_file->string);
  327.     if ((fp = fopen(hp->exten_file->string, "w")) == NULL) {
  328.         report(LOG_ERR, "error opening \"%s\": %s",
  329.                hp->exten_file->string, get_errmsg());
  330.         return;
  331.     }
  332.     len = vp - buffer;
  333.     if (len != fwrite(buffer, 1, len, fp)) {
  334.         report(LOG_ERR, "write failed on \"%s\" : %s",
  335.                hp->exten_file->string, get_errmsg());
  336.     }
  337.     fclose(fp);
  338.  
  339. } /* mktagfile */
  340.  
  341. /*
  342.  * Local Variables:
  343.  * tab-width: 4
  344.  * c-indent-level: 4
  345.  * c-argdecl-indent: 4
  346.  * c-continued-statement-offset: 4
  347.  * c-continued-brace-offset: -4
  348.  * c-label-offset: -4
  349.  * c-brace-offset: 0
  350.  * End:
  351.  */
  352.