home *** CD-ROM | disk | FTP | other *** search
/ Oracle Video Server 3.0.3.1 / OVS_3031_NT.iso / win32 / sqlnet / net23 / client / tnsapifd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-30  |  7.8 KB  |  370 lines

  1. /*
  2.    $Header: /netrcs/RCS/oracle/network/tns/tnsapi/RCS/tnsapifd.c,v 1.2 1995/09/11 21:49:37 mhill Exp $
  3. */
  4.  
  5. /* Copyright (c) 1995 by Oracle Corporation.  All rights reserved. */
  6.  
  7. /*
  8. NAME
  9.   tnsapifd - SQL*Net Open - finger server ("daemon") demo
  10. */
  11.  
  12. /* This demo implements a simple "finger" server to work with the finger
  13.    client program in tnsapifc.c, using the SQL*Net Open API.
  14.  
  15.    This server is implemented for Unix and was tested on Solaris - it 
  16.    simply invokes the finger program.   If you're not on Unix, you may want
  17.    to implement something analogous to this using this program as a
  18.    template. */
  19.  
  20. #ifdef WIN32
  21. #include <windows.h>
  22. #endif
  23.  
  24. #include <tnsapi.h>
  25.  
  26. /* For non-Solaris operating systems you may need to change this pathname */
  27. #define TNSAPIFD_FINGER_PROGRAM "finger.exe"
  28.  
  29. static short get_string_length();
  30. char **build_arg_array();
  31. static void free_arg_array();
  32.  
  33. #ifdef WIN32
  34. int main(argc, argv)
  35. int argc;
  36. char **argv;
  37. {
  38.     void *handle = 0;        /* connection handle I get from tnslsnr */
  39.     char reply[256];        /* work buffer */
  40.     char *work;            /* pointer into work buffer */
  41.     int rc = 0;
  42.     int length, rcvd, sent = 0;
  43.     HANDLE hPipeRead, hPipeWrite ; /* read/write handle for pipe */
  44.  
  45.     SECURITY_ATTRIBUTES stSecAttrib ;
  46.  
  47.     /* pick up connection from tnslsnr (service name is null because we're
  48.        on server side */
  49.     rc = tnsopen(&handle, (const char *)0);
  50.     if (rc) goto error;
  51.  
  52.     /* set security attributes for pipe */
  53.     stSecAttrib.nLength = sizeof(SECURITY_ATTRIBUTES) ;
  54.     stSecAttrib.bInheritHandle = TRUE ;
  55.     stSecAttrib.lpSecurityDescriptor = NULL ;
  56.     
  57.  
  58.     /* read and process the argument string.
  59.  
  60.        we get this in two pieces.  first read four bytes, which gives
  61.        us enough information to get the length of the argument list - then
  62.        read the argument list */
  63.     length = 4;
  64.     work = reply;
  65.     
  66.     while(length)
  67.     {
  68.     rcvd = length;
  69.     rc = tnsrecv(handle, work, &rcvd);
  70.     if (rc) goto error;
  71.     length -= rcvd;
  72.     work += rcvd;
  73.     }
  74.  
  75.     length = (int)get_string_length(reply);
  76.  
  77.     memset(reply, 0, sizeof(reply)) ;
  78.     work = reply;
  79.     
  80.     /* now read the argument string into the reply buffer */
  81.     while(length)
  82.     {
  83.     rcvd = length;
  84.     rc = tnsrecv(handle, work, &rcvd);
  85.     if (rc) goto error;
  86.     length -= rcvd;
  87.     work += rcvd;
  88.     }
  89.  
  90.  
  91.     /* create a pipe to communicate with child process */
  92.     if(! CreatePipe(&hPipeRead, &hPipeWrite, &stSecAttrib, 0) )
  93.     goto error ;
  94.  
  95.     /* start the child process - finger.exe */
  96.     if(! SpawnChild(reply, hPipeWrite))
  97.     goto error ;
  98.  
  99.     Sleep(1000) ;
  100.  
  101.     /* close write handle */
  102.     if(! CloseHandle(hPipeWrite))
  103.     goto error ;
  104.  
  105.     /* read from child through pipe */
  106.     memset(reply, 0, sizeof(reply)) ;
  107.     while (TRUE)
  108.     {
  109.     if(! ReadFile(hPipeRead, reply, sizeof(reply), &rcvd, NULL))
  110.     {
  111.         rc = GetLastError() ;
  112.         break ;
  113.     }
  114.  
  115.     if(!rcvd)
  116.         break ;
  117.  
  118.     while (rcvd)
  119.     {
  120.         sent = rcvd;
  121.         rc = tnssend(handle, reply, &sent);
  122.         if (rc) goto error;
  123.         rcvd -= sent;
  124.     }
  125.     }
  126.  
  127.  
  128.  
  129.     rc = tnsclose(&handle);
  130.     if (rc) goto error;
  131.  
  132.     /* done */
  133.     return(0) ;
  134.  
  135.  
  136.  
  137.   error:
  138.     if (rc)
  139.     {
  140.     if (rc != RECVFAIL_TNSAPIE) (void) printf("error code %d\n", rc);
  141.     }
  142.     else
  143.     {
  144.     perror("sfingerd");
  145.     }
  146.     exit(1);
  147. }
  148.  
  149. BOOL SpawnChild(char *args, HANDLE hPipeWrite)
  150. {
  151.   PROCESS_INFORMATION    stProcInfo ;
  152.   STARTUPINFO        stStartInfo ;
  153.   char            szCmd[256] ;
  154.  
  155.   stStartInfo.cb        = sizeof(STARTUPINFO) ;
  156.   stStartInfo.lpReserved    = NULL ;
  157.   stStartInfo.lpReserved2    = NULL ;
  158.   stStartInfo.cbReserved2    = 0 ;
  159.   stStartInfo.lpDesktop        = NULL ;
  160.   stStartInfo.dwFlags        = STARTF_USESTDHANDLES ;
  161.   stStartInfo.hStdOutput    = hPipeWrite ;
  162.   stStartInfo.hStdError        = hPipeWrite ;
  163.  
  164.  
  165.   memset(szCmd, 0, sizeof(szCmd)) ;
  166.   sprintf(szCmd, "%s %s", TNSAPIFD_FINGER_PROGRAM, args) ;
  167.   return CreateProcess( NULL,
  168.             szCmd,                  /* command line */
  169.             NULL,               /* security */
  170.             NULL,               /* main thread security */
  171.             TRUE,               /* inherit handles */
  172.             0,               /* creation flags */
  173.             NULL,               /* use parent env */
  174.             NULL,               /* use parent current dir */
  175.             &stStartInfo,
  176.             &stProcInfo
  177.             ) ;
  178. }
  179.  
  180. #else  /* WIN32 */
  181.  
  182. int main(argc, argv)
  183. int argc;
  184. char **argv;
  185. {
  186.     void *handle;        /* connection handle I get from tnslsnr */
  187.     char reply[256];        /* work buffer */
  188.     char *work;            /* pointer into work buffer */
  189.     int rc = 0;
  190.     int p[2];
  191.     int length, rcvd, sent = 0;
  192.     char **args;
  193.     
  194.     /* pick up connection from tnslsnr (service name is null because we're
  195.        on server side */
  196.     rc = tnsopen(&handle, (const char *)0);
  197.     if (rc) goto error;
  198.  
  199.     if (pipe(p)) goto error;
  200.     
  201.     /* read and process the argument string.
  202.  
  203.        we get this in two pieces.  first read four bytes, which gives
  204.        us enough information to get the length of the argument list - then
  205.        read the argument list */
  206.     length = 4;
  207.     work = reply;
  208.     
  209.     while(length)
  210.     {
  211.     rcvd = length;
  212.     rc = tnsrecv(handle, work, &rcvd);
  213.     if (rc) goto error;
  214.     length -= rcvd;
  215.     work += rcvd;
  216.     }
  217.  
  218.     length = (int)get_string_length(reply);
  219.  
  220.     *reply = '\0';
  221.     work = reply;
  222.     
  223.     /* now read the argument string into the reply buffer */
  224.     while(length)
  225.     {
  226.     rcvd = length;
  227.     rc = tnsrecv(handle, work, &rcvd);
  228.     if (rc) goto error;
  229.     length -= rcvd;
  230.     work += rcvd;
  231.     }
  232.  
  233.     switch(fork())
  234.     {
  235.       case 0:
  236.     /* this is the forked off process (actual finger program) */
  237.     
  238.     /* dup my stdout onto the pipe so that the parent process can 
  239.        read it */
  240.     (void) close(p[0]);
  241.     (void) dup2(p[1], 1);
  242.     (void) close(p[1]);
  243.     
  244.     /* build an array of arguments out of the string we read */
  245.     args = build_arg_array(reply);
  246.  
  247.     args[0] = TNSAPIFD_FINGER_PROGRAM;
  248.  
  249.     if (execv(TNSAPIFD_FINGER_PROGRAM, args) < 0) perror("execv");
  250.     
  251.     free_arg_array(args);
  252.     
  253.     exit(0);
  254.  
  255.       case -1:
  256.     goto error;
  257.  
  258.       default:
  259.     /* this is the parent process, read output from finger and send it */
  260.     (void) close(p[1]);
  261.  
  262.     while ((rcvd = read(p[0], reply, sizeof(reply)) ) > 0 && rcvd)
  263.     {
  264.         while (rcvd)
  265.         {
  266.         sent = rcvd;
  267.         rc = tnssend(handle, reply, &sent);
  268.          if (rc) goto error;
  269.         rcvd -= sent;
  270.         }
  271.     }
  272.  
  273.      rc = tnsclose(&handle);
  274.     if (rc) goto error;
  275.  
  276.     exit(0);
  277.     }
  278.  
  279.   error:
  280.     if (rc)
  281.     {
  282.     if (rc != RECVFAIL_TNSAPIE) (void) printf("error code %d\n", rc);
  283.     }
  284.     else
  285.     {
  286.     perror("sfingerd");
  287.     }
  288.     exit(1);
  289. }
  290.  
  291.  
  292. #endif /* WIN32 */
  293.  
  294. /* get length of the argument list to be read from first four bytes of 
  295.    the data that was read.  This is the counterpart to build_arg_string in 
  296.    tnsapifc.c */
  297. static short get_string_length(buf)
  298. char *buf;
  299. {
  300.     char *work = buf;
  301.     short one;
  302.     short result;
  303.     char *resultb = (char *)&result;
  304.     
  305.     
  306.     memcpy(&one, buf, 2);
  307.     if (one == 1) 
  308.     {
  309.     /* same data representation */
  310.     memcpy(&result, buf + 2, 2);
  311.     return(result);
  312.     }
  313.     else
  314.     {
  315.     /* swap bytes */
  316.     *(resultb) = *(buf + 3);
  317.     *(resultb + 1) = *(buf + 2);
  318.     return(result);
  319.     }
  320. }
  321.  
  322. char **build_arg_array(buf)
  323. char *buf;
  324. {
  325.     char **array;
  326.     char *work = buf;
  327.     int entry = 0;
  328.     
  329.     /* allocate "enough" space, not actually sure how many entries we have */
  330. #define max_arguments 10    
  331.     array = (char **)malloc(4 * max_arguments);
  332.  
  333.     entry++;            /* reserve first slot for program name */
  334.     if (*work)
  335.     {
  336.     array[entry++] = work++;    /* set up first pointer */
  337.     }
  338.     else
  339.     {
  340.     array[entry] = (char *)0;
  341.     return(array);
  342.     }
  343.     
  344.     for (; *work; )
  345.     {
  346.     if (*work == ' ')
  347.     {
  348.         *work++ = '\0';
  349.         array[entry++] = work;
  350.     }
  351.     else
  352.     {
  353.         work++;
  354.     }
  355.     }
  356.  
  357.     array[entry] = (char *)0;
  358.     return(array);
  359. }
  360.  
  361. void free_arg_array(args)
  362. char **args;
  363. {
  364.     free(args);
  365.     return;
  366. }
  367.  
  368.  
  369.  
  370.