home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / p / pcrte224.zip / SOURCE.ZIP / CONFIG.C < prev    next >
C/C++ Source or Header  |  1992-06-09  |  22KB  |  668 lines

  1. /**************************************************************************/
  2. /*                      config.c        config.c                          */
  3. /**************************************************************************/
  4.  
  5. /* config.c is an simple configuration program that creates 
  6.    (or edits) a file called 'pcroute.cfg' that containing configuration 
  7.    information for the pcroute program.  the pcroute file is a Binary
  8.    file whose structure is simply a PCROUTE_CONFIG structure followed
  9.    by a list of ROUTE structures */
  10.  
  11. /* AUTHOR: Vance Morrison
  12.    DATE  : 1/10/89
  13.    ADDRESS: morrison@accuvax.nwu.edu */
  14.  
  15. /**************************************************************************/
  16.  
  17. #include <stdio.h>
  18.  
  19. #define MAX_DATA    4096
  20.  
  21. typedef struct {
  22.     unsigned char   type;           /* type of configuration data */
  23.     unsigned char   version;        /* version of this piece of data */
  24.     unsigned short  len;            /* length of the DATA (that comes next) */
  25.     char            buff[MAX_DATA]; /* the config data */
  26.     } CONF;
  27.  
  28.         /*  types for the 'type' field  */
  29. #define CONF_GENERIC    1   /* interface that requires no special config data */
  30. #define CONF_LOCALTALK  2   /* Special localtalk extentions (zone name etc) */
  31. #define CONF_SLIP       3   /* Special SLIP extentions (speed) */
  32.  
  33. #define CONF_ROUTE  10      /* static route configuration data */
  34. #define CONF_BOOTP  20      /* Bootp configration data (forwarding host) */
  35. #define CONF_ADMIN  21      /* administrative data (admin host) */
  36. #define CONF_SYSLOG 22      /* host to send loging messages to */
  37.  
  38. typedef struct {
  39.     unsigned char addr[4];
  40.     } INET_ADDR;
  41.  
  42. typedef struct {
  43.     INET_ADDR address;
  44.     INET_ADDR mask;
  45.     unsigned short flags;
  46.     unsigned short metric;
  47.     } CONFIG_GENERIC;
  48.  
  49. typedef struct {
  50.     INET_ADDR address;
  51.     INET_ADDR mask;
  52.     unsigned short flags;
  53.     unsigned short metric;
  54.     unsigned char zones[64];                /* actually variable length */
  55.     } CONFIG_LOCALTALK;
  56.  
  57. typedef struct {
  58.     INET_ADDR address;
  59.     INET_ADDR mask;
  60.     unsigned short flags;
  61.     unsigned short metric;
  62.     unsigned short speed;                   /* actual 8250 divisor */
  63.     } CONFIG_SLIP;
  64.  
  65. typedef struct {
  66.     INET_ADDR net;
  67.     INET_ADDR gateway;
  68.     unsigned char metric;
  69.     unsigned char flags;
  70.     } CONFIG_ROUTE_ENTRY;
  71.  
  72. typedef struct {
  73.     unsigned short      len;
  74.     CONFIG_ROUTE_ENTRY  routes[1];          /* actually variable length */
  75.     } CONFIG_ROUTE;
  76.  
  77. typedef struct {
  78.     INET_ADDR forward_addr;
  79.     } CONFIG_BOOTP;
  80.  
  81. typedef struct {
  82.     INET_ADDR log_host;
  83.     short     log_priority;
  84.     short     log_mask;
  85.     } CONFIG_SYSLOG;
  86.  
  87. typedef struct {
  88.     INET_ADDR admin;
  89.     } CONFIG_ADMIN;
  90.  
  91.  
  92. /**************************************************************************/
  93. main()
  94. {
  95.     FILE *cfg_rfile, *cfg_wfile;
  96.     char config[64];
  97.  
  98.     printf("This program creates/edits the pcroute.cfg file\n");
  99.  
  100.     if (get_config(config, 64) != 0) {
  101.         fprintf(stderr, "Could not get configuration from 'pcroute.exe'\n");
  102.         return;
  103.         }
  104.  
  105.     cfg_wfile = fopen("pcroute.new", "wb");
  106.     if (cfg_wfile == NULL) {
  107.         fprintf(stderr, "Could not open 'pcroute.new'\n");
  108.         return;
  109.         }
  110.  
  111.     cfg_rfile = fopen("pcroute.cfg", "rb");
  112.  
  113.     if (update_config(cfg_wfile, cfg_rfile, config) == 0) {
  114.         fclose(cfg_wfile);
  115.         unlink("pcroute.cfg");
  116.         rename("pcroute.new", "pcroute.cfg");
  117.         }
  118.     else {
  119.         fclose(cfg_wfile);
  120.         unlink("pcroute.new");
  121.         fprintf(stderr, "Error generating configuration file\n");
  122.         }
  123. }
  124.  
  125.  
  126. /**************************************************************************/
  127. /* update_config writes out a configuration file 'cfg_wfile' conforming
  128.    to the configuration in 'config' using 'cfg_rfile' as defaults.  It
  129.    returns 0 on success */
  130.  
  131. int update_config(cfg_wfile, cfg_rfile, config)
  132.     FILE *cfg_wfile, *cfg_rfile;
  133.     char *config;
  134. {
  135.     CONF data, datain;
  136.     int len;
  137.  
  138.     datain.type = 0;
  139.     while(*config != 0) {
  140.             /* get the old data structure if possible */
  141.         while (datain.type < *config) {
  142.             read_config(&datain, cfg_rfile);
  143.             if (datain.type == 0)
  144.                 break;
  145.             }
  146.         if (datain.type == *config) {
  147.             memcpy(&data, &datain, sizeof(CONF));
  148.             datain.type = 0;
  149.             }
  150.         else
  151.             memset(&data, 0, sizeof(CONF));
  152.  
  153.         len = -1;
  154.         switch(config[0]) {
  155.             case CONF_GENERIC:
  156.                 len = config_generic(data.version, config[1], data.buff, MAX_DATA);
  157.                 break;
  158.  
  159.             case CONF_ROUTE:
  160.                 len = config_routes(data.version, config[1], data.buff, MAX_DATA);
  161.                 break;
  162.  
  163.             case CONF_LOCALTALK:
  164.                 len = config_localtalk(data.version, config[1], data.buff, MAX_DATA);
  165.                 break;
  166.  
  167.             case CONF_SLIP:
  168.                 len = config_slip(data.version, config[1], data.buff, MAX_DATA);
  169.                 break;
  170.  
  171.             case CONF_BOOTP:
  172.                 len = config_bootp(data.version, config[1], data.buff, MAX_DATA);
  173.                 break;
  174.  
  175.             case CONF_SYSLOG:
  176.                 len = config_syslog(data.version, config[1], data.buff, MAX_DATA);
  177.                 break;
  178.  
  179.             case CONF_ADMIN:
  180.                 break;
  181.             }
  182.         if (len < 0 || len > MAX_DATA) {
  183.             fprintf(stderr, "I do not understand the pcroute.exe config\n");
  184.             return(-1);
  185.             }
  186.         data.len = len;
  187.         data.type = *config++;
  188.         data.version = *config++;
  189.         fwrite(&data, data.len+4, 1, cfg_wfile);
  190.         }
  191.  
  192.     return(0);
  193. }
  194.  
  195.  
  196. /***************************************************************************/
  197. /* read_config reads in the next configuration object from the file 'cfg_rfile'
  198.    and puts in in the conf structure 'data'.  If any errors return, the conf
  199.    structure is nulled */
  200.  
  201. read_config(data, cfg_rfile)
  202.     CONF *data;
  203.     FILE *cfg_rfile;
  204. {
  205.     memset(data, 0, sizeof(CONF));
  206.     if (cfg_rfile != NULL) 
  207.         if (fread(data, 4, 1, cfg_rfile) == 1) 
  208.             if (data->len <= MAX_DATA) 
  209.                 if (fread(data->buff, data->len, 1, cfg_rfile) == 1)
  210.                     return;
  211.  
  212.     memset(data, 0, sizeof(CONF));
  213. }
  214.  
  215.  
  216. /**************************************************************************/
  217. /* config_generic prompts for the generic interface configuration data
  218.    it puts it in the buffer 'generic' of length 'len'.  The buffer is
  219.    loaded with version 'oldver' and should be inititialized for version
  220.    'newver' */
  221.  
  222. int config_generic(oldver, newver, generic, len)
  223.     unsigned int oldver, newver;
  224.     CONFIG_GENERIC *generic;
  225.     int len;
  226. {
  227.     int flags;
  228.  
  229.     if (len < sizeof(CONFIG_GENERIC) || newver != 2) {
  230.         fprintf(stderr,"Can't configure this version of PCroute's interface\n");
  231.         return(-1);
  232.         }
  233.     if (oldver == 1)
  234.         generic->metric = 0;
  235.     else if (oldver > 2)
  236.         memset(generic, 0, sizeof(CONFIG_GENERIC));
  237.  
  238.     printf("\nConfiguring an interface\n");
  239.     get_INET_addr(&generic->address, "Address for the interface");
  240.     get_INET_addr(&generic->mask, "Subnet mask for the interface");
  241.     printf("Flag Meanings (if set)\n");
  242.     printf("    Bit 0 (1h)  - Don't send routing updates out this interface\n");
  243.     printf("    Bit 1 (2h)  - Don't listen to routing updates from this interface\n");
  244.     printf("    Bit 2 (4h)  - Proxy Arp for all subnets\n");
  245.     printf("    Bit 3 (8h)  - Turn off directed broadcasts\n");
  246.     printf("    Bit 4 (10h) - Turn off the issuing of ICMP redirects\n");
  247.     printf("    Bit 5 (20h) - Broadcast using old (0's) format\n");
  248.     get_hex(&generic->flags, "Flags (HEX) for the interface");
  249.     if (generic->metric == 0)
  250.         generic->metric = 1;
  251.     for(;;)  {
  252.         get_hex(&generic->metric, "Routing Metric (HEX) for the interface");
  253.         if (generic->metric >= 0 && generic->metric < 16)
  254.             break;
  255.         generic->metric = 1;
  256.         }
  257.  
  258.     return(sizeof(CONFIG_GENERIC));
  259. }
  260.  
  261.  
  262. /**************************************************************************/
  263. /* config_localtalk prompts for the localtalk configuration data
  264.    It puts it in the buffer 'localt' of length 'len'.   The buffer is
  265.    loaded with version 'oldver' and should be inititialized for version
  266.    'newver' */
  267.  
  268. int config_localtalk(oldver, newver, localt, len)
  269.     int oldver, newver;
  270.     CONFIG_LOCALTALK *localt;
  271.     int len;
  272. {
  273.     int flags;
  274.     unsigned char *ptr;
  275.     char buff[256];
  276.     char changed;
  277.  
  278.     if (len < sizeof(CONFIG_LOCALTALK) || newver != 2) {
  279.         fprintf(stderr,"Can't configure this version of PCroute's localtalk\n");
  280.         return(-1);
  281.         }
  282.     if (oldver == 1)
  283.         memset(&localt->metric, 0, 66);
  284.     if (oldver > 2)
  285.         memset(localt, 0, len);
  286.  
  287.     printf("\nConfiguring an interface\n");
  288.     get_INET_addr(&localt->address, "Address for LOCALTALK interface");
  289.     get_INET_addr(&localt->mask, "Subnet mask for LOCALTALK interface");
  290.     printf("Flag Meanings (if set)\n");
  291.     printf("    Bit 0 (1h)  - Don't send routing updates out this interface\n");
  292.     printf("    Bit 1 (2h)  - Don't listen to routing updates from this interface\n");
  293.     printf("    Bit 2 (4h)  - Proxy Arp for all subnets\n");
  294.     printf("    Bit 3 (8h)  - Turn off directed broadcasts\n");
  295.     printf("    Bit 4 (10h) - Turn off the issuing of ICMP redirects\n");
  296.     get_hex(&localt->flags, "Flags (HEX) for the interface");
  297.     if (localt->metric == 0)
  298.         localt->metric = 1;
  299.     for(;;)  {
  300.         get_hex(&localt->metric, "Routing Metric (HEX) for the interface");
  301.         if (localt->metric > 0 && localt->metric < 16)
  302.             break;
  303.         localt->metric = 1;
  304.         }
  305.  
  306.     printf("\nPlease list all LOCALTALK zones that have gatways that this\n");
  307.     printf("router talks to.  (don't forget '*' (the current zone)\n");
  308.     printf("End with a '.'\n");
  309.  
  310.     ptr = localt->zones;
  311.     changed = 0;
  312.     for(;;) {
  313.         if (changed)    
  314.             *ptr = 0;
  315.         strncpy(buff, &ptr[1], ptr[0]);     /* copy the default */
  316.         buff[ptr[0]] = '\0';                /* make sure the string is ended */
  317.             
  318.         printf("Zone [%s]: ", buff);
  319.         gets(buff);
  320.         if (*buff == '.')
  321.             break;
  322.         if (*buff != '\0') {                    /* not the default */
  323.             changed = 1;
  324.             ptr[0] = strlen(buff);
  325.             if (ptr + ptr[0] < &localt->zones[64 - 2]) {    /* will it fit? */
  326.                 strcpy(&ptr[1], buff);
  327.                 }
  328.             else {
  329.                 printf("Sorry, zone buffer full\n");
  330.                 break;
  331.                 }
  332.             }
  333.         ptr += ptr[0]+1;
  334.         }
  335.     *ptr = 0;
  336.  
  337.     return(sizeof(CONFIG_LOCALTALK));
  338. }
  339.  
  340.  
  341. /**************************************************************************/
  342. /* config_slip prompts for the slip configuration data
  343.    It puts it in the buffer 'slip' of length 'len'.   The buffer is
  344.    loaded with version 'oldver' and should be inititialized for version
  345.    'newver' */
  346.  
  347. int config_slip(oldver, newver, slip, len)
  348.     int oldver;
  349.     CONFIG_SLIP *slip;
  350.     int len;
  351. {
  352.     unsigned int speed;
  353.     unsigned char *ptr;
  354.     char buff[256];
  355.     char changed;
  356.  
  357.     if (len < sizeof(CONFIG_SLIP) || newver != 1) {
  358.         fprintf(stderr,"Can't configure this version of PCroute's slip\n");
  359.         return(-1);
  360.         }
  361.     if (oldver != 1)
  362.         memset(slip, 0, len);
  363.  
  364.     printf("\nConfiguring a SLIP interface\n");
  365.     get_INET_addr(&slip->address, "Address for SLIP interface");
  366.     get_INET_addr(&slip->mask, "Subnet mask for SLIP interface");
  367.     printf("Flag Meanings (if set)\n");
  368.     printf("    Bit 0 (1h)  - Don't send routing updates out this interface\n");
  369.     printf("    Bit 1 (2h)  - Don't listen to routing updates from this interface\n");
  370.     printf("    Bit 2 (4h)  - Proxy Arp for all subnets\n");
  371.     printf("    Bit 3 (8h)  - Turn off directed broadcasts\n");
  372.     printf("    Bit 4 (10h) - Turn off the issuing of ICMP redirects\n");
  373.     get_hex(&slip->flags, "Flags (HEX) for the interface");
  374.  
  375.     if( slip->speed == 0 )
  376.         slip->speed = 12;         /* default of 9600 baud */
  377.  
  378.     for(;;) {
  379.         printf( "\nEnter speed for this interface (ex. 9600, 19200, ...) [%ld] ", 115200L / slip->speed  );
  380.         gets(buff);
  381.         if( *buff == 0 ) {
  382.             speed = slip->speed;
  383.             break;
  384.         }
  385.         speed = 115200L / (unsigned) atol( buff );
  386.         if( (long)speed * (unsigned) atol( buff ) == 115200L )
  387.             break;
  388.         printf( "Bad speed\n" );
  389.     }
  390.     slip->speed = speed;
  391.  
  392.     if (slip->metric == 0)
  393.         slip->metric = 1;
  394.     for(;;)  {
  395.         get_hex(&slip->metric, "Routing Metric (HEX) for the interface");
  396.         if (slip->metric > 0 && slip->metric < 16)
  397.             break;
  398.         slip->metric = 1;
  399.         }
  400.  
  401.     return(sizeof(CONFIG_SLIP));
  402. }
  403.  
  404.  
  405. /**************************************************************************/
  406. /* config_bootp prompts for the bootp configuration data.
  407.    It puts it in the buffer 'bootp' of length 'len'.   The buffer is
  408.    loaded with version 'oldver' and should be inititialized for version
  409.    'newver' */
  410.  
  411. int config_bootp(oldver, newver, bootp, len)
  412.     int oldver, newver;
  413.     CONFIG_BOOTP *bootp;
  414.     int len;
  415. {
  416.     if (len < sizeof(CONFIG_BOOTP) || newver != 1) {
  417.         fprintf(stderr, "Can't configure this version of PCroute's bootp\n");
  418.         return(-1);
  419.         }
  420.     if (oldver != 1)
  421.         memset(bootp, 0, sizeof(CONFIG_BOOTP));
  422.  
  423.     printf("\nIf you wish to forward bootp packets please enter the address\n");
  424.     printf("  of the address to forward it to.  This address can be a\n");
  425.     printf("  directed broadcast.  0.0.0.0  means don't forward\n\n");
  426.     get_INET_addr(&bootp->forward_addr, "Address to forward bootp packets");
  427.  
  428.     return(sizeof(CONFIG_BOOTP));
  429. }
  430.  
  431.  
  432. /**************************************************************************/
  433. /* config_syslog prompts for the logging configuration data. 
  434.    It puts it in the buffer 'localt' of length 'len'.   The buffer is
  435.    loaded with version 'oldver' and should be inititialized for version
  436.    'newver' */
  437.  
  438. int config_syslog(oldver, newver, log, len)
  439.     int oldver, newver;
  440.     CONFIG_SYSLOG *log;
  441.     int len;
  442. {
  443.     if (len < sizeof(CONFIG_SYSLOG) || newver != 1) {
  444.         fprintf(stderr, "Can't configure this version of PCroute's syslog\n");
  445.         return(-1);
  446.         }
  447.     if (oldver != 1)
  448.         memset(log, 0, sizeof(CONFIG_SYSLOG));
  449.  
  450.     printf("\nOnce PCroute boots up, it sends all log messages to a network\n");
  451.     printf("  host running a BSD UNIX syslogd daemon.  To disable\n");
  452.     printf("  logging enter 0.0.0.0\n\n");
  453.     get_INET_addr(&log->log_host, "Host to send loging info to");
  454.  
  455.     printf("Mask Meanings (0 = Log, 1 = Don't log)\n");
  456.     printf("    Bit 0 (1h)  - System\n");
  457.     printf("    Bit 1 (2h)  - Routing\n");
  458.     printf("    Bit 2 (4h)  - Monitor\n");
  459.     printf("    Bit 3 (8h)  - Localtalk\n");
  460.     get_hex(&log->log_mask, "Logging mask for this router");
  461.  
  462.     printf("There are 8 routing 'levels' supported\n");
  463.     printf("    0 - Emergency    1 - Alert    2 - Critical    3 - Error\n");
  464.     printf("    4 - Warning      5 - Notice   6 - info        7 - Debug\n");
  465.     printf("Only messages with a level less than the logging level are sent\n");
  466.     get_hex(&log->log_priority, "Logging level");
  467.  
  468.     return(sizeof(CONFIG_SYSLOG));
  469. }
  470.  
  471.  
  472. /**************************************************************************/
  473. /* config_routes prompts for the static routes data.
  474.    It puts it in the buffer 'localt' of length 'len'.   The buffer is
  475.    loaded with version 'oldver' and should be inititialized for version
  476.    'newver' */
  477.  
  478. int config_routes(oldver, newver, route, len)
  479.     int oldver, newver;
  480.     CONFIG_ROUTE *route;
  481.     int len;
  482. {
  483.     CONFIG_ROUTE_ENTRY *ptr;
  484.     int count;
  485.     short holder;
  486.  
  487.     if (len < sizeof(CONFIG_ROUTE_ENTRY)+2 || newver != 1) {
  488.         fprintf(stderr, "Can't configure this version of PCroute's RIP\n");
  489.         return(-1);
  490.         }
  491.     if (oldver != 1)
  492.         memset(route, 0, len);
  493.  
  494.     printf("\nIf you wish to configure static routes do so here.  ");
  495.     printf("To stop type a '.'\n\n");
  496.     printf("  Flag Meanings (if set)\n");
  497.     printf("      Bit 0 (1h)  - Local route, do not propagate it\n");
  498.     printf("      Bit 1 (2h)  - Transient route, subject to RIP protocol\n");
  499.     count = 0;
  500.     ptr = route->routes;
  501.     while (count < (len-2)/sizeof(CONFIG_ROUTE_ENTRY)) {
  502.         printf("\n");
  503.         if (get_INET_addr(&ptr->net, "Network") < 0)
  504.             break;
  505.         if (get_INET_addr(&ptr->gateway, "Gateway") < 0)
  506.             break;
  507.         holder = ptr->metric; 
  508.         if (holder == 0) 
  509.             holder = 9;
  510.         if (get_hex(&holder, "Metric (HEX) ") < 0)
  511.             break;
  512.         ptr->metric = holder;
  513.         holder = ptr->flags;
  514.         if (get_hex(&holder, "Flags (HEX)") < 0)
  515.             break;
  516.         ptr->flags = holder;
  517.         count++;
  518.         ptr++;
  519.         }
  520.  
  521.     route->len = count;
  522.     return(count*sizeof(CONFIG_ROUTE_ENTRY)+2);
  523. }
  524.  
  525.  
  526. /**************************************************************************/
  527. /* get_config reads in the binary file 'pcroute.exe' and extracts the 
  528.    configuration information from it and put it in the string 'str' of
  529.    length 'len' It returns 0 on SUCCESS */
  530.  
  531. int get_config(str, len)
  532.     char *str;
  533.     int len;
  534. {
  535.     FILE *pcroute;
  536.     static char look_for[] = "CONFIG ->";
  537.     char *ptr;
  538.     int c;
  539.  
  540.     pcroute = fopen("pcroute.exe", "rb");
  541.     if (pcroute == NULL) {
  542.         return(-1);
  543.         }
  544.  
  545.     ptr = look_for;
  546.     while(*ptr != '\0') {
  547.         c = getc(pcroute);
  548.         if (c < 0) {
  549.         fclose(pcroute);
  550.             return(-1);
  551.         }
  552.         else if (c == *ptr)
  553.             ptr++;
  554.         else
  555.             ptr = look_for;
  556.         }
  557.  
  558.     --len;
  559.     --len;
  560.     for(;;) {
  561.         if (len <= 0)
  562.             break;
  563.         *str = getc(pcroute);
  564.         if (*str <= 0)              /*  either EOF or null character */
  565.             break;
  566.  
  567.         str++;
  568.         --len;
  569.         }
  570.  
  571.     *str++ = '\0';
  572.     *str = '\0';                    /* need a word of null, just in case */
  573.     fclose(pcroute);
  574.     return(0);
  575. }
  576.  
  577.  
  578. /**************************************************************************/
  579. /* get_hex prompts the user with 'prompt' and retrieves a two byte
  580.    hex number and returns it in in addr.  It returns
  581.    0 if successful.  If the user inputs an invalid address, get_hex
  582.    will loop.  If the user inputs a '.' it returns -1 if the user inputs
  583.    a '^', get_INET_addr returns -2 */
  584.  
  585. get_hex(addr, prompt)
  586.     short *addr;
  587.     char *prompt;
  588. {
  589.     char buffer[256];
  590.     int flags;
  591.  
  592.     for(;;) {
  593.         printf("%s [%xH] ? ", prompt, *addr);
  594.         gets(buffer);
  595.         if (*buffer == 0)           /* carrage return = default */
  596.             return(0);
  597.         if (*buffer == '.')         /* wish to return */
  598.             return(-1);
  599.         if (*buffer == '^')         /* wish to return */
  600.             return(-2);
  601.         if (sscanf(buffer, "%x", &flags) == 1) {
  602.             *addr = flags;
  603.             return(0);
  604.             }
  605.         } 
  606. }
  607.  
  608.  
  609. /**************************************************************************/
  610. /* get_INET_addr prompts the user with 'prompt' and retrieves an internet
  611.    address (in dot notation) from the user and places it in addr.  It returns
  612.    0 if successful.  If the user inputs an invalid address, get_INET_addr
  613.    will loop.  If the user inputs a '.' it returns -1 if the user inputs
  614.    a '^', get_INET_addr returns -2 */
  615.  
  616. get_INET_addr(addr, prompt)
  617.     INET_ADDR *addr;
  618.     char *prompt;
  619. {
  620.     char buffer[256];
  621.  
  622.     for(;;) {
  623.         INET_to_dot(*addr, buffer);
  624.         printf("%s [%s] ? ", prompt, buffer);
  625.         gets(buffer);
  626.         if (*buffer == 0)           /* carrage return = default */
  627.             return(0);
  628.         if (*buffer == '.')         /* wish to return */
  629.             return(-1);
  630.         if (*buffer == '^')         /* wish to return */
  631.             return(-2);
  632.         if (dot_to_INET(buffer, addr))
  633.             return(0);
  634.         } 
  635. }
  636.  
  637.  
  638.  
  639. /*****************************************************************************/
  640. /* routines for converting to and from dot notation and INET_ADDR structures */
  641.  
  642. INET_to_dot(inet, dot)
  643.     INET_ADDR inet;
  644.     char *dot;
  645. {
  646.     sprintf(dot, "%d.%d.%d.%d", inet.addr[0], inet.addr[1], 
  647.         inet.addr[2], inet.addr[3]);
  648. }
  649.  
  650. dot_to_INET(dot, inet)
  651.     char *dot;
  652.     INET_ADDR *inet;
  653. {
  654.     int bytes[4];
  655.     int ret;
  656.  
  657.     ret = sscanf(dot,"%d.%d.%d.%d", &bytes[0], &bytes[1], &bytes[2], &bytes[3]);
  658.     if (ret != 4)
  659.     return(0);
  660.  
  661.     inet->addr[0] = bytes[0];
  662.     inet->addr[1] = bytes[1];
  663.     inet->addr[2] = bytes[2];
  664.     inet->addr[3] = bytes[3];
  665.     return(1);
  666. }
  667.  
  668.