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