home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / finger4.zip / fingerd.c < prev    next >
C/C++ Source or Header  |  1994-05-29  |  11KB  |  378 lines

  1. /*******************************************************************
  2.  * Finger Daemon for TCP/IP for OS/2
  3.  * Compiles with CSET/2
  4.  * by:
  5.  *   Aaron Williams
  6.  *   35900 Turpin Way
  7.  *   Fremont, CA. 94536-2666
  8.  *   (510) 792-0340 after June 18, 1994.
  9.  *   (408) 426-3053 before June 18, 1994.
  10.  *******************************************************************/
  11.  
  12. /*
  13.  * Include Files.
  14.  */
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include <types.h>
  18. #include <netinet\in.h>
  19. #include <sys\socket.h>
  20. #include <stdio.h>
  21. #include <netdb.h>
  22. #define INCL_DOSQUEUES
  23. #define INCL_DOSNMPIPES
  24. #define INCL_DOSPROCESS
  25.  
  26. #include <os2.h>
  27.  
  28.  
  29. #define PIPESIZE 32768        /* Size of our pipe for I/O redirecting */
  30. #define HF_STDOUT 1
  31.  
  32.  
  33. void usage(char *program)
  34. {
  35.   fprintf(stderr, "Usage: %s -f responsefile [-s port|service] [-p protocol] [-d] [-l logfile] [-b]\n", program);
  36.   fprintf(stderr, "\t-f specifies the data file to be displayed\n");
  37.   fprintf(stderr, "\t-s specifies the service to be used (default is finger)\n");
  38.   fprintf(stderr, "\t   A port number may also be specified.\n");
  39.   fprintf(stderr, "\t-p specifies the protocol used (default is tcp)\n");
  40.   fprintf(stderr, "\t-d specifies debugging info is to be displayed\n");
  41.   fprintf(stderr, "\t-l specifies the log file to be used for logging queries\n");
  42.   fprintf(stderr, "\t-b tells %s to beep whenever a finger request is made.\n");
  43.   
  44.   exit(1);
  45. }
  46.  
  47.  
  48. /*
  49.  * Server Main.
  50.  */
  51. main(argc, argv)
  52. int argc;
  53. char **argv;
  54. {
  55.     unsigned short port;       /* port server binds to                  */
  56.     char buf[512];             /* buffer for sending and receiving data */
  57.     struct sockaddr_in client; /* client address information            */
  58.     struct sockaddr_in server; /* server address information            */
  59.     struct servent *ser;
  60.     struct hostent *client_info;
  61.     int s;                     /* socket for accepting connections      */
  62.     int ns;                    /* socket connected to client            */
  63.     int namelen;               /* length of client name                 */
  64.     char *servicename;         /* name of service to be used, usually finger */
  65.     char *protocol;            /* name of protocol to be used, usually tcp */
  66.     char *filename;            /* filename of finger data file          */
  67.     char *logfilename;         /* filename where logging info is to be stored */
  68.     int i;
  69.     int bufsize;
  70.     int debugging = 0;         /* indicates whether debugging has been enabled */
  71.     int logging = 0;           /* indicates whether logging has been enabled */
  72.     FILE *finger_data;         
  73.     FILE *logfile;
  74.     char client_addr[18];      /* address string */
  75.     int beepenable = 0;
  76.  
  77.     /*
  78.      * Check arguments. Should be only one: the port number to bind to.
  79.      */
  80.  
  81.     servicename = "finger";    /* default service */
  82.     protocol = "tcp";          /* default protocol */
  83.  
  84.     if (argc < 3)
  85.       usage(argv[0]);          /* if no arguments are passed, presend info */
  86.  
  87.     i = 1;
  88.     while (i < argc) {
  89.       if (!strcmp(argv[i], "-f")) {
  90.     i++;
  91.     if (i >= argc) {
  92.       fprintf(stderr, "Error: Filename missing!\n");
  93.       usage(argv[0]);
  94.     }
  95.     filename = argv[i];
  96.     fprintf(stdout, "Finger file = %s\n", filename);
  97.     finger_data = fopen(filename, "r");
  98.     if (finger_data == NULL) {
  99.       fprintf(stderr, "Error:  Cannot open finger data file!\n");
  100.       exit(-1);
  101.     }
  102.     fclose(finger_data);
  103.     i++;
  104.     continue;
  105.       }
  106.       if (!strcmp(argv[i], "-s")) {
  107.     i++;
  108.     if (i >= argc) {
  109.       fprintf(stderr, "Error:  Missing service name!\n");
  110.       usage(argv[0]);
  111.     }
  112.     servicename = argv[i];
  113.     if (!isdigit(servicename[0]))
  114.       printf("Using %s service\n", servicename);
  115.     else
  116.       printf("Using port %s\n", servicename);
  117.     i++;
  118.     continue;
  119.       }
  120.       if (!strcmp(argv[i], "-p")) {
  121.     i++;
  122.     if (i >= argc) {
  123.       fprintf(stderr, "Error:  Missing protocol!\n");
  124.       usage(argv[0]);
  125.     }
  126.     protocol = argv[i];
  127.     if (strcmp(protocol, "tcp") && strcmp(protocol, "udp")) {
  128.       fprintf(stderr, "Error: Invalid protocol!  Must be tcp or udp!\n");
  129.       usage(argv[0]);
  130.     }
  131.     printf("Using %s protocol\n", protocol);
  132.     i++;
  133.     continue;
  134.       }
  135.       if (!strcmp(argv[i], "-d")) {
  136.     i++;
  137.     debugging = 1;
  138.     printf("Debugging info is enabled.\n");
  139.     continue;
  140.       }
  141.       if (!strcmp(argv[i], "-l")) {
  142.     i++;
  143.     if (i >= argc) {
  144.       fprintf(stderr, "Error: logfile not specified!\n");
  145.       usage(argv[0]);
  146.     }
  147.     logfilename = argv[i];
  148.     logfile = fopen(logfilename, "a");
  149.     if (logfile == NULL) {
  150.       fprintf(stderr, "Error: Cannot open logfile %s!\n", 
  151.           logfilename);
  152.       exit(-1);
  153.     }
  154.     fclose(logfile);
  155.     i++;
  156.     printf("Logging queries to file %s\n", logfilename);
  157.     logging = 1;
  158.     continue;
  159.       }
  160.       if (!strcmp(argv[i], "-b")) {
  161.         printf("Beep enabled on finger request.\n");
  162.         beepenable = 1;
  163.         i++;
  164.         continue;
  165.       }
  166.       
  167.       fprintf(stderr, "Unknown option %s\n", argv[i]);
  168.       usage(argv[0]);
  169.     }
  170.     printf("\nFinger Daemon for OS/2\n");
  171.     printf("Brought to you by Aaron Williams\n");
  172.     printf("This program is provided as-is, and no warrenties exist!\n");
  173.     printf("If you make improvements or find any bugs, let me know.\n");
  174.     printf("\nI can be reached via snail mail at:\n\n\tAaron Williams\n");
  175.     printf("\t35900 Turpin Way\n\tFremont, CA. 94536-2666\n");
  176.     printf("\nEmail: aaronw@cats.ucsc.edu (subject to change on June 18, 1994)\n\n");
  177.     /*
  178.      * Initialize with sockets.
  179.      */
  180.     sock_init();
  181.     /*
  182.      * First argument should be the port.
  183.      */
  184.     if (isdigit(servicename[0]))
  185.       port = (unsigned short) atoi(servicename);
  186.     else {
  187.       ser = getservbyname(servicename, protocol);
  188.       if (ser == NULL) {
  189.     fprintf(stderr, "Error:  Service %s is not available!\n", servicename);
  190.     exit(-1);
  191.       }
  192.       port = ser->s_port >> 8;
  193.       if (debugging)
  194.     printf("Service %s using port #%d\n", ser->s_name, port);
  195.     }
  196.  
  197.     /*
  198.      * Get a socket for accepting connections.
  199.      */
  200.     if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  201.       psock_errno("Socket()");
  202.       exit(2);
  203.     }
  204.  
  205.     /*
  206.      * Bind the socket to the server address.
  207.      */
  208.     server.sin_family = AF_INET;
  209.     server.sin_port   = htons(port);
  210.     server.sin_addr.s_addr = INADDR_ANY;
  211.     
  212.     if (bind(s, (struct sockaddr *)&server, sizeof(server)) < 0) {
  213.       psock_errno("Bind()");
  214.       soclose(s);
  215.       exit(3);
  216.     }
  217.  
  218.     while (1) {
  219.       /*
  220.        * Listen for connections. Specify the backlog as 1.
  221.        */
  222.       if (listen(s, 1) != 0) {
  223.     psock_errno("Listen()");
  224.     exit(4);
  225.       }
  226.     
  227.       /*
  228.        * Accept a connection.
  229.        */
  230.       namelen = sizeof(client);
  231.       if ((ns = accept(s, (struct sockaddr *)&client, &namelen)) == -1) {
  232.     psock_errno("Accept()");
  233.     exit(5);
  234.       }
  235.       if (beepenable) {
  236.         DosBeep(1600,50);
  237.         DosBeep(800,25);
  238.         DosBeep(1600,25);
  239.       }
  240.       if (debugging || logging) {
  241.     sprintf(client_addr, "%d.%d.%d.%d", 
  242.         (client.sin_addr.s_addr  & 255),
  243.         (client.sin_addr.s_addr >> 8) & 255,
  244.         (client.sin_addr.s_addr >> 16) & 255,
  245.         client.sin_addr.s_addr >> 24);
  246.     sethostent(1);
  247.         
  248.     client_info = gethostbyaddr((char *)(&(client.sin_addr.s_addr)), 
  249.                     sizeof(client.sin_addr.s_addr), 
  250.                     AF_INET);
  251.     if (debugging) {
  252.       if (client_info != NULL)
  253.         printf("%s (%s) port=%d.  ", client_info->h_name, 
  254.            client_addr, client.sin_port);
  255.       else
  256.         printf("Cannot get client name.  IP=%s.  ", client_addr); 
  257.     }
  258.     if (logging) {
  259.       logfile = fopen(logfilename, "a");
  260.       if (logfile == NULL)
  261.         fprintf(stderr, "Warning: Cannot write to log file!\n");
  262.       else {
  263.         if (client_info != NULL)
  264.           fprintf(logfile, "%s (%s) port=%d.  ",
  265.               client_info->h_name, 
  266.               client_addr, client.sin_port);
  267.         else
  268.           fprintf(logfile, "Cannot get client name.  IP=%s.  ", 
  269.               client_addr); 
  270.       }
  271.     }
  272.       }
  273.     
  274.       /*
  275.        * Receive the message on the newly connected socket.
  276.        */
  277.       memset(buf, 0, sizeof(buf));
  278.       
  279.       if ((bufsize=recv(ns, buf, sizeof(buf), 0)) == -1) {
  280.     psock_errno("Recv()");
  281.     exit(6);
  282.       }
  283.         
  284.       if (bufsize > 0) {
  285.     if (debugging) {
  286.       if (buf[0] == 13)
  287.         printf("Querying all users\n");
  288.       else
  289.         printf("Account=%s", buf);
  290.       fflush(stdout);
  291.     }
  292.     if (logging) {
  293.       if (buf[0] == 13)
  294.         fprintf(logfile, "Querying all users\n");
  295.       else
  296.         fprintf(logfile, "Querying account %s\n", buf);
  297.     }
  298.       }
  299.     
  300.       /*
  301.        * Send the message back to the client.
  302.        */
  303.                 /* Open finger data file for reading */
  304.       finger_data = fopen(filename, "r");
  305.       if (finger_data == NULL) {
  306.     fprintf(stderr, "Error: Cannot open finger data file!\n");
  307.     exit(7);
  308.       }
  309.  
  310.                 /* Read a line from the data file */
  311.       while (fgets(buf, sizeof(buf), finger_data)) { 
  312.     bufsize = strlen(buf);    /* Get the length of the line */
  313.     if (buf[0] == '~' && buf[1] == 'x') /* Is this a command? (~x) */
  314.       {            /* Yes, process it as such */
  315.  
  316.         ULONG cbRead, cbWritten; /* count of bytes read & written */
  317.         HFILE hfSave = -1;
  318.         HFILE hfNew = HF_STDOUT;
  319.         HPIPE hpR, hpW;
  320.         RESULTCODES rc;
  321.  
  322.         buf[strlen(buf)-1] = 0; /* Remove final cr from command line */
  323.                 
  324.         if (debugging) {    /* If debugging print out command executed */
  325.           printf("Executing %s.\n", buf+2);
  326.           fflush(stdout);
  327.         }
  328.         if (logging) {
  329.           fprintf(logfile, "Executing %s.\n", buf+2);
  330.           fflush(logfile);
  331.         }
  332.  
  333.         DosDupHandle(HF_STDOUT, &hfSave); /* Save the stdout handle */
  334.                 /* Create a pipe */
  335.         if (DosCreatePipe(&hpR, &hpW, PIPESIZE))
  336.           {
  337.         fprintf(stderr, "Error opening pipe!\n");
  338.         if (logging)
  339.           fprintf(logfile, "Error opening pipe!\n");
  340.           }
  341.         DosDupHandle(hpW, &hfNew);
  342.                 /* This will be changed in the future to */
  343.                 /* allow for asynchronous execution.  This */
  344.                 /* will also remove any limits on the size */
  345.                 /* of the pipe. */
  346.         system(buf+2);    /* Do the command */
  347.         
  348.         DosClose(hpW);
  349.         DosDupHandle(hfSave, &hfNew); /* Un redirect stdout */
  350.  
  351.         do {
  352.  
  353.           static CHAR achBuf[PIPESIZE]; /* Buffer for storing pipe */
  354.  
  355.           DosRead(hpR, achBuf, sizeof(achBuf), &cbRead); /* Read from pipe */
  356.           if (send(ns, achBuf, cbRead, 0) < 0) { /* Output to socket */
  357.         psock_errno("Send()");
  358.           }
  359.         } while (cbRead);
  360.         DosClose(hpR);
  361.       }
  362.     else            /* Not a command line */
  363.       if (send(ns, buf, bufsize, 0) < 0) { /* Send the line out the socket */
  364.         psock_errno("Send()"); /* Report send errors */
  365.       }
  366.       }
  367.       fclose (finger_data);
  368.       soclose(ns);
  369.       if (logging)
  370.     fclose(logfile);
  371.     }
  372.     soclose(s);
  373.     printf("Server ended successfully\n");
  374.     exit(0);
  375. }
  376.  
  377.  
  378.