home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / k95source.tar.gz / k95source.tar / iksd.c < prev    next >
C/C++ Source or Header  |  2001-11-20  |  13KB  |  421 lines

  1. #include <stdio.h>
  2.  
  3. #ifdef NT
  4. #include <windows.h>
  5. #include <winsock.h>
  6. #define strdup _strdup
  7. #define ltoa   _ltoa
  8. #endif
  9. #define CONFIG_FILE "iksd.cfg"
  10.  
  11. #define bzero(x,y) memset(x,0,y)
  12. #define BSDSELECT
  13.  
  14. #define MAXPORTS 32
  15. struct PORT 
  16. {
  17.     short id ;
  18.     int   lsocket ;
  19.     int   asocket ;
  20.     char  * k95cmd ;
  21.     int   showcmd;
  22. } ports[MAXPORTS] ;
  23. int portcount = 0 ;
  24.  
  25. int
  26. ParseCmdLine( int argc, char * argv[] )
  27. {
  28.     int len = 0, i ;
  29.     char * p = NULL ;
  30.     static struct servent *service, servrec;
  31.     int arg = 1;
  32.  
  33.     /* Set up some defaults */
  34.     ports[portcount].showcmd = SW_SHOWNORMAL;
  35.     service = getservbyname("kermit", "tcp");
  36.  
  37.     /* Allocate the max needed memory */
  38.     for ( i = 1 ; i < argc ; i++ )
  39.         len += strlen( argv[i] ) + 1 ;
  40.    
  41.     ports[portcount].k95cmd = (char *) malloc( len+1 ) ;
  42.     if ( !ports[portcount].k95cmd )
  43.     {
  44.         fprintf( stderr, "memory allocation error\n" ) ;
  45.         exit(1) ;
  46.     }
  47.     ports[portcount].k95cmd[0] = '\0' ;
  48.  
  49.     /* Process each command line option */
  50.     for ( i=1 ; i<argc ; i++ )
  51.     {
  52.         if ( argv[arg][0] == '-' && argv[arg][1] == '-' ) {
  53.             if ( !_stricmp("--maximized",argv[arg]) ) {
  54.                 ports[portcount].showcmd = SW_SHOWMAXIMIZED;
  55.                 continue;
  56.             }
  57.             else if ( !_stricmp("--minimized",argv[arg]) ) {
  58.                 ports[portcount].showcmd = SW_SHOWMINIMIZED;
  59.                 continue;
  60.             }
  61.             else if ( !_stricmp("--normal",argv[arg]) ) {
  62.                 ports[portcount].showcmd = SW_NORMAL;
  63.                 continue;
  64.             }
  65.             else if ( !_stricmp("--minnoactive",argv[arg]) ) {
  66.                 ports[portcount].showcmd = SW_SHOWMINNOACTIVE;
  67.                 continue;
  68.             }
  69.             else if ( !_strnicmp("--port:",argv[arg],7) ) {
  70.                 p = &argv[arg][7];
  71.                 if (isdigit(*p)) {            /* Use socket number without lookup */
  72.                     service = &servrec;
  73.                     service->s_port = htons((unsigned short)atoi(p));
  74.                 } else {                /* Otherwise lookup the service name */
  75.                     service = getservbyname(p, "tcp");
  76.                 }
  77.                 continue;
  78.             }
  79.         }
  80.  
  81.         if ( ports[portcount].k95cmd[0] )
  82.             strcat( ports[portcount].k95cmd, " ");
  83.         strcat( ports[portcount].k95cmd, argv[i] );
  84.     }
  85.  
  86.     if ( service )
  87.         ports[portcount].id = service->s_port;
  88.     else
  89.         ports[portcount].id = htons( 1649 );
  90.  
  91.     portcount++ ;
  92.     return portcount ;
  93. }
  94.  
  95. HANDLE
  96. StartKermit( int socket, char * cmdline, int ShowCmd ) 
  97. {
  98. #ifdef NT
  99.    PROCESS_INFORMATION StartKermitProcessInfo ;
  100.    OSVERSIONINFO osverinfo ;
  101.    STARTUPINFO si ;
  102.    HANDLE sockdup = INVALID_HANDLE_VALUE ;
  103.    static char buf[512] ;
  104.  
  105.    osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO) ;
  106.    GetVersionEx( &osverinfo ) ;
  107.     
  108.    memset( &si, 0, sizeof(STARTUPINFO) ) ;
  109.    si.cb = sizeof(STARTUPINFO);
  110.    si.dwFlags = STARTF_USESHOWWINDOW;
  111.    si.wShowWindow = ShowCmd;
  112.  
  113.    if (!DuplicateHandle( GetCurrentProcess(), (HANDLE) socket, 
  114.                     GetCurrentProcess(), &sockdup,
  115.                     DUPLICATE_SAME_ACCESS, TRUE, 
  116.                     DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS ))
  117.    {
  118.       closesocket( (int) socket ) ;
  119.       fprintf( stderr, "\nINTERNET KERMIT SERVICE DAEMON FATAL ERROR:\n" );
  120.       fprintf( stderr, " You are using a WinSOCK which does not allow socket handles\n");
  121.       fprintf( stderr, " to be duplicated or shared with child processes.\n\n");
  122.       fprintf( stderr, " If you are attempting to start Kermit 95 Host Mode,\n");
  123.       fprintf( stderr, " please change SESSIONS to 1 in your configuration.\n");
  124.       fprintf( stderr, "\n Press ENTER to exit...\n");
  125.       fscanf( stdin, "" ) ; 
  126.       exit( 2 ) ;
  127.    }
  128.  
  129.  
  130. #ifdef DEBUG
  131.     strcpy( buf, "msdev.exe cknker.exe -# 132 -A " ) ;
  132.     ltoa( (LONG) sockdup, buf+strlen(buf), 10 ) ;
  133.     strcat( buf, " " );
  134.     strcat( buf, cmdline ) ;
  135.  
  136.    printf("Executing: %s\n",buf ) ;
  137.    if (CreateProcess(
  138.                        (LPSTR)NULL,          /* start K-95  */
  139.                        (LPSTR)buf, /* give it the file */
  140.                        (LPSECURITY_ATTRIBUTES)NULL, 
  141.                        (LPSECURITY_ATTRIBUTES)NULL, 
  142.                         TRUE,                      /* fix if necessary */
  143.                        (DWORD) CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP,    
  144.                        (LPVOID)NULL,                /* fix if necessary */
  145.                        (LPSTR)NULL,               /* Current directory */
  146.                        &si,                     /* Startup info, fix */
  147.                        &StartKermitProcessInfo  /* Process info */
  148.                       )) 
  149.     {
  150.         closesocket( (int) sockdup ) ;
  151.         return (StartKermitProcessInfo.hProcess);
  152.     } 
  153. #endif /* DEBUG */
  154.  
  155. #ifdef DEBUG
  156.     strcpy( buf, "msdev.exe iksdnt.exe -# 132 -A " ) ;
  157. #else
  158.     strcpy( buf, "iksdnt.exe -# 132 -A " ) ;
  159. #endif /* DEBUG */
  160.     ltoa( (LONG) sockdup, buf+strlen(buf), 10 ) ;
  161.     strcat( buf, " " );
  162.     strcat( buf, cmdline ) ;
  163.  
  164.    printf("Executing: %s\n",buf ) ;
  165.    if (CreateProcess(
  166.                        (LPSTR)NULL,          /* start K-95  */
  167.                        (LPSTR)buf, /* give it the file */
  168.                        (LPSECURITY_ATTRIBUTES)NULL, 
  169.                        (LPSECURITY_ATTRIBUTES)NULL, 
  170.                         TRUE,                      /* fix if necessary */
  171.                        (DWORD) CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP,    
  172.                        (LPVOID)NULL,                /* fix if necessary */
  173.                        (LPSTR)NULL,               /* Current directory */
  174.                        &si,                     /* Startup info, fix */
  175.                        &StartKermitProcessInfo  /* Process info */
  176.                       )) 
  177.     {
  178.         closesocket( (int) sockdup ) ;
  179.         return (StartKermitProcessInfo.hProcess);
  180.     } 
  181.  
  182. #ifdef DEBUG
  183.     strcpy( buf, "msdev.exe k95.exe -# 132 -A " ) ;
  184. #else
  185.     strcpy( buf, "k95.exe -# 132 -A " ) ;
  186. #endif /* DEBUG */
  187.     ltoa( (LONG) sockdup, buf+strlen(buf), 10 ) ;
  188.     strcat( buf, " " );
  189.     strcat( buf, cmdline ) ;
  190.  
  191.    printf("Executing: %s\n",buf ) ;
  192.    if (CreateProcess(
  193.                        (LPSTR)NULL,          /* start K-95  */
  194.                        (LPSTR)buf, /* give it the file */
  195.                        (LPSECURITY_ATTRIBUTES)NULL, 
  196.                        (LPSECURITY_ATTRIBUTES)NULL, 
  197.                         TRUE,                      /* fix if necessary */
  198.                        (DWORD) CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP,    
  199.                        (LPVOID)NULL,                /* fix if necessary */
  200.                        (LPSTR)NULL,               /* Current directory */
  201.                        &si,                     /* Startup info, fix */
  202.                        &StartKermitProcessInfo  /* Process info */
  203.                       )) 
  204.     {
  205.         closesocket( (int) sockdup ) ;
  206.         return (StartKermitProcessInfo.hProcess);
  207.     } 
  208.  
  209.     printf("CreateProcess() failed gle=%ul\n",GetLastError());
  210.     closesocket( (int) sockdup ) ;
  211.     return(FALSE);
  212. #else /* NT */
  213.     Not built for OS/2 yet.
  214. #endif /* NT */
  215. }
  216.  
  217. int
  218. main( int argc, char * argv[] ) {
  219.     char *p=NULL, * dbdir=NULL, dbfile[256];
  220.     int i, x;
  221.     int on = 1, rc = 0;
  222.     int ready_to_accept = 0 ;
  223.     static struct servent *service, servrec;
  224.     static struct hostent *host;
  225.     static struct sockaddr_in saddr;
  226.     static int saddrlen ;
  227. #ifdef BSDSELECT
  228.     fd_set rfds;
  229.     struct timeval tv;
  230. #endif /* BSDSELECT */
  231.     int tcpsrv_fd = -1, ttyfd = -1 ;
  232. #ifdef NT
  233.     WSADATA data ;
  234.     OSVERSIONINFO osverinfo ;
  235.     HANDLE hProcess;
  236.  
  237.     printf("Internet Kermit Service Daemon\n");
  238.     rc = WSAStartup( MAKEWORD( 2, 0 ), &data ) ;
  239.     if ( rc == WSAVERNOTSUPPORTED )
  240.     {
  241.       WSACleanup() ;
  242.       rc = WSAStartup( MAKEWORD( 1, 1 ), &data ) ;
  243.    }
  244. #else /* NT */
  245.  
  246. #endif /* NT */
  247.  
  248.     ParseCmdLine( argc, argv );
  249.     if ( !portcount )
  250.     {
  251. #ifdef DEBUG
  252.         ports[portcount].showcmd = SW_NORMAL;
  253. #else
  254.         ports[portcount].showcmd = SW_SHOWMINNOACTIVE;
  255. #endif
  256.         ports[portcount].k95cmd = (char *) malloc( 1 ) ;
  257.         ports[portcount].k95cmd[0] = '\0' ;
  258.         ports[portcount].id = htons( 1649 ) ;
  259.         portcount++;
  260.     }
  261.  
  262. #ifdef NT
  263.     osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO) ;
  264.     GetVersionEx( &osverinfo ) ;
  265.  
  266.     if (osverinfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) {
  267.         dbdir = getenv("SystemRoot");
  268.     } else {
  269.         dbdir = getenv("winbootdir");
  270.         if (!dbdir)  
  271.             dbdir = getenv("windir");
  272.     }
  273.     if (!dbdir) 
  274.         dbdir = "C:/";
  275. #else /* NT */
  276.     dbdir = "C:/";
  277. #endif /* NT */
  278.     sprintf(dbfile,"%s\\iksd.lck",dbdir);
  279.     unlink(dbfile);
  280.     sprintf(dbfile,"%s\\iksd.db",dbdir);
  281.     unlink(dbfile);
  282.  
  283.    for ( i=0; i<portcount; i++)
  284.    {
  285.       /* Set up socket structure and get host address */
  286.  
  287.       bzero((char *)&saddr, sizeof(saddr));
  288.       saddr.sin_family = AF_INET ;
  289.       saddr.sin_addr.s_addr = INADDR_ANY ;
  290.  
  291.       /* Get a file descriptor for the connection. */
  292.  
  293.       saddr.sin_port = ports[i].id;
  294.  
  295.       if ((ports[i].lsocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  296.       {
  297.          perror("TCP socket error");
  298.          exit (3);
  299.       }
  300.       errno = 0;
  301.  
  302.       /* Specify the Port may be reused */
  303.       setsockopt(ports[i].lsocket, SOL_SOCKET, SO_REUSEADDR,(char *) &on, sizeof on);
  304.  
  305.       /* Now bind to the socket */
  306. #ifdef DEBUG
  307.       printf("Binding socket to port %d ... ",
  308.               ntohs((unsigned short)ports[i].id)) ;
  309. #endif
  310.       if (bind(ports[i].lsocket, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) 
  311.       {
  312.          i = errno;            /* save error code */
  313.          closesocket(ports[i].lsocket) ;
  314.          ports[i].lsocket = -1 ;
  315.          ports[i].asocket = -1;
  316.          errno = i;            /* and report this error */
  317.          fprintf(stderr,"tcpsrv_open bind errno","",errno);
  318.          exit(4);
  319.       }
  320. #ifdef DEBUG
  321.       printf("Listening ...\n");
  322. #endif
  323.       if (listen(ports[i].lsocket, 15) < 0)
  324.       {
  325.          i = errno;            /* save error code */
  326.          closesocket(ports[i].lsocket) ;
  327.          ports[i].lsocket = -1 ;
  328.          ports[i].asocket = -1;
  329.          errno = i;            /* and report this error */
  330.          fprintf(stderr,"tcpsrv_open listen errno","",errno);
  331.          exit(5);
  332.       }
  333.    }
  334.               
  335.    printf("Servicing ports:\n");
  336.    for ( i=0;i<portcount ;i++ )
  337.    {
  338.       printf("  %d\n", ntohs((unsigned short)ports[i].id) ) ;
  339.    }
  340.  
  341.    saddrlen = sizeof(saddr) ;
  342.  
  343. #ifdef BSDSELECT
  344.    tv.tv_sec  = 1L;
  345.    tv.tv_usec = 0L;
  346. #endif /* BSDSELECT */
  347.  
  348.    for ( ;; )
  349.    {
  350.       while ( !ready_to_accept )
  351.       {
  352. #ifdef BSDSELECT
  353.          FD_ZERO(&rfds);
  354.          for ( i=0; i<portcount;i++ )
  355.             FD_SET(ports[i].lsocket, &rfds);
  356.          if (select(FD_SETSIZE, &rfds, NULL, NULL, &tv ) > 0)
  357.          {
  358.             for ( i=0; i<portcount ; i++ )
  359.             {
  360.                if ( ready_to_accept = FD_ISSET(ports[i].lsocket, &rfds) )
  361.                   break;
  362.             }
  363.          }
  364. #else /* BSDSELECT */
  365. #ifdef IBMSELECT
  366. ???      /* in order to make this work, we need to create an array of socket values */
  367.          ready_to_accept = (( select(&tcpsrv_fd, 1, 0, 0,1 )) == 1) ;
  368. #endif /* IBMSELECT */
  369. #endif /* BSDSELECT */
  370.       }
  371.      
  372.       if ( ready_to_accept )
  373.       {
  374.          if ((ports[i].asocket = accept(ports[i].lsocket, (struct sockaddr *)&saddr,&saddrlen)) < 0)
  375.          {
  376.             i = errno;            /* save error code */
  377.             closesocket(ports[i].lsocket) ;
  378.             ports[i].asocket = -1;
  379.             ports[i].lsocket = -1 ;
  380.             errno = i;            /* and report this error */
  381.             fprintf(stderr,"tcpsrv_open accept errno","",errno);
  382.             exit(6);
  383.          }
  384.  
  385.          setsockopt(ports[i].asocket, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);
  386.  
  387.          if ((host = gethostbyaddr((char *)&saddr.sin_addr,4,PF_INET)) != NULL) 
  388.          {
  389.             printf("%s connected on port %d\n",host->h_name,ntohs(ports[i].id)) ;
  390.          }
  391.  
  392.          /* Now start subprocess */
  393.           if ( ports[i].asocket,ports[i].k95cmd )
  394.               printf("Starting IKSD with socket %d and command %s\n",ports[i].asocket,ports[i].k95cmd);
  395.           else 
  396.               printf("Starting IKSD with socket %d\n");
  397.          hProcess = StartKermit(ports[i].asocket,ports[i].k95cmd, ports[i].showcmd) ;
  398.      if ( hProcess != INVALID_HANDLE_VALUE )
  399.          CloseHandle(hProcess);
  400.          closesocket(ports[i].asocket);
  401.          continue;                /* Go get the next one */
  402.       }
  403.       else
  404.       {
  405.          i = errno;            /* save error code */
  406.          closesocket(ports[i].lsocket) ;
  407.          ports[i].lsocket = -1;
  408.          ports[i].asocket = -1;
  409.          errno = i;            /* and report this error */
  410.          fprintf(stderr,"tcpsrv_open accept errno","",errno);
  411.          exit(7);
  412.       }
  413.    }
  414.  
  415. #ifdef NT
  416.    WSACleanup() ;
  417. #else
  418.  
  419. #endif /* NT */
  420. }
  421.