"Fossies" - the Fresh Open Source Software Archive

Member "tlswrap-1.04/misc.c" (25 Nov 2006, 19325 Bytes) of package /linux/privat/old/tlswrap-1.04.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "misc.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (c) 2002-2006 Tomas Svensson <ts@codepix.com>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. The name of the author may not be used to endorse or promote products
   14  *    derived from this software without specific prior written permission.
   15  *
   16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
   17  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
   18  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
   19  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   26  */
   27 
   28 #include "conf.h"
   29 
   30 #include <errno.h>
   31 #include <memory.h>
   32 #include <stdio.h>
   33 #include <string.h>
   34 #ifdef WIN32
   35 extern const char *srv_name;
   36 extern const char *srv_name2;
   37 extern char *srv_desc;
   38 #include <conio.h>
   39 #include <process.h>
   40 #define snprintf _snprintf
   41 #define close closesocket
   42 #else
   43 #include <unistd.h>
   44 #endif
   45 
   46 #include "tlswrap.h"
   47 #include "misc.h"
   48 
   49 extern int debug;
   50 #ifdef WIN32
   51 extern struct parm serv_param;
   52 #endif
   53 
   54 void sys_err(const char *err){
   55     perror(err);
   56     exit(1);
   57 }
   58 
   59 void user_close(struct user_data *ud)
   60 {
   61     if (ud->connected == CONN_YES || ud->connected == CONN_IN_PROG)
   62         close(ud->serv_fd);
   63     close(ud->user_fd);
   64 
   65     if (ud->ssl_ctrl)
   66         SSL_free(ud->ssl_ctrl);
   67 
   68     if (debug)
   69         printf("user_close\n");
   70     if (ud->data_connected != CONN_NO)
   71         data_close(ud);
   72     if (ud->ssl_sess)
   73         SSL_SESSION_free(ud->ssl_sess);
   74     if (ud->ssl_ctx)
   75         SSL_CTX_free(ud->ssl_ctx);
   76     /* memset(ud, 0, sizeof(struct user_data)); */
   77     ud->user_fd = -1;
   78     ud->serv_fd = -1;
   79     ud->connected = CONN_NO;
   80     ud->ssl_data_fd_mode = TLS_NONE;
   81 
   82     ud->s2u_i = ud->s2u_o = ud->s2u_buf;
   83     ud->u2s_i = ud->u2s_o = ud->u2s_buf;
   84 
   85 }
   86 
   87 void data_close(struct user_data *ud)
   88 {
   89     if (ud->ssl_data) {
   90         if (1) {
   91         //if (SSL_get_shutdown(ud->ssl_data) & SSL_RECEIVED_SHUTDOWN) {
   92             /* SSL connection was shutdown cleanly */
   93             ud->ssl_sess = SSL_get1_session(ud->ssl_data);
   94             SSL_shutdown(ud->ssl_data);
   95         } else 
   96             SSL_clear(ud->ssl_data);
   97         SSL_free(ud->ssl_data);
   98         ud->ssl_data = NULL;
   99     }
  100 
  101     if (ud->data_connected == CONN_DATA_OK ||
  102         ud->data_connected == CONN_DATA_LISTEN) 
  103         close(ud->user_data_fd);
  104     if (ud->data_connected == CONN_IN_PROG ||
  105         ud->data_connected == CONN_DATA_TLS ||
  106         ud->data_connected == CONN_DATA_OK) 
  107         close(ud->serv_data_fd);
  108 
  109     ud->user_data_fd = -1;
  110     ud->serv_data_fd = -1;
  111 
  112     ud->data_connected = CONN_NO;
  113     ud->ssl_data_fd_mode = TLS_NONE;
  114     ud->dc2s_i = ud->dc2s_o = ud->dc2s_buf;
  115     ud->ds2c_i = ud->ds2c_o = ud->ds2c_buf;
  116 
  117     ud->serv_data_close = CLOSE_NONE;
  118     ud->user_data_close = CLOSE_NONE;
  119     ud->user_read_cnt = 0;
  120     ud->serv_read_cnt = 0;
  121     ud->tls_status &= ~TLS_DATA;
  122     ud->retry_data = 0;
  123     ud->active = 0;
  124     if (debug)
  125         printf("data_close\n");
  126 
  127 }
  128 
  129 size_t
  130 extr_str(const char *src, size_t src_len, char *dst, size_t dst_len) {
  131 
  132     /* Extract a \r\n (or just \n) terminated string from a binary
  133         buffer. The copied string will always be null-terminated and
  134         without \r\n. The function will return a pointer to the next
  135         byte after the extracted string or NULL if no string could be
  136         found */
  137 
  138     char *ptr;
  139     int ext_size,size;
  140 
  141     if ((ptr = memchr(src,'\n',src_len)) == NULL)
  142         return 0;
  143 
  144     ext_size = size = ptr - src;
  145 
  146     if (src[ext_size-1] == '\r')
  147             ext_size--;
  148 
  149     if ( (ext_size + 1) <= dst_len) {
  150             memcpy(dst, src, ext_size);
  151             dst[ext_size] = 0;
  152     } else {
  153             printf("ext_str: dst buffer too small for extracted string\n");
  154             return 0;
  155     }
  156 
  157     return size + 1;
  158 }
  159 int print_to_ud(struct user_data *ud, const char *s) {
  160 
  161     /* all pointers must be setup correctly prior to calling this
  162         function, or it will segfault */
  163 
  164     size_t slen;
  165     char str[1024];
  166   
  167     snprintf(str, sizeof(str), s);
  168 
  169     slen = strlen(str); /* NOT including null char */
  170   
  171     if ( (&ud->s2u_buf[S2U_SIZE] - ud->s2u_i) < slen) {
  172             printf("print_to_ud: can't fit string to buffer\n");
  173             return 1;
  174     } else {
  175             memcpy(ud->s2u_i,str,slen);
  176             ud->s2u_i+=slen;
  177     }
  178 
  179     return 0;
  180 }
  181 
  182 int print_to_serv(struct user_data *ud, const char *s) {
  183 
  184     size_t slen;
  185     char str[130];
  186 
  187     snprintf(str, sizeof(str), s);
  188     slen = strlen(str); /* NOT including null char */
  189     if ( (&ud->u2s_buf[U2S_SIZE]-ud->u2s_i)<slen) {
  190         printf("print_to_ud: can't fit string to buffer\n");
  191         return 1; 
  192     } else {
  193         memcpy(ud->u2s_i,str,slen);
  194         ud->u2s_i+=slen;
  195     }
  196     
  197     return 0;
  198 }
  199 #if 1 
  200 int find_max_fd(int listen, struct user_data *ud, int max_users) {
  201     int i, max_fd = listen;
  202  
  203     for(i = 0; i < max_users; i++) {
  204             if (ud[i].user_fd != -1) {
  205                 if (ud[i].user_fd > max_fd)
  206                 max_fd = ud[i].user_fd;
  207                 if ((ud[i].serv_fd > max_fd) &&
  208                 ((ud[i].connected == CONN_YES)||
  209                 (ud[i].connected == CONN_IN_PROG )))
  210                 max_fd = ud[i].serv_fd;
  211                 if ( (ud[i].serv_data_fd > max_fd) &&
  212                 ((ud[i].data_connected == CONN_YES) ||
  213                     (ud[i].data_connected == CONN_IN_PROG )))
  214                 max_fd = ud[i].serv_data_fd; 
  215                 if (ud[i].data_connected == CONN_DATA_LISTEN)
  216                 if (ud[i].user_data_fd > max_fd)
  217                     max_fd = ud[i].user_data_fd;
  218                 if (ud[i].ssl_data_fd_mode != TLS_NONE)
  219                 if (ud[i].serv_data_fd > max_fd)
  220                     max_fd = ud[i].serv_data_fd;
  221                 if (ud[i].data_connected == CONN_DATA_OK) {
  222                 if (ud[i].user_data_fd > max_fd)
  223                     max_fd = ud[i].user_data_fd;
  224                 if (ud[i].serv_data_fd > max_fd)
  225                     max_fd = ud[i].serv_data_fd;
  226             }
  227             }
  228         }
  229   
  230     return max_fd;
  231 }
  232 #else
  233 
  234 int find_max_fd(fd_set *fd_r, fd_set *fd_w)
  235 {
  236     int i, max_fd;
  237 
  238     max_fd = 0;
  239 
  240     for (i = FD_SETSIZE - 1; i >= 0 ; i--) {
  241         if ( FD_ISSET(i,fd_r) || FD_ISSET(i,fd_w) )
  242             return i;
  243     }
  244 
  245     return 0;
  246 }
  247 #endif
  248 void init_ud(struct user_data *ud, int max_users) {
  249 
  250     /* Initializes the user_data structures */
  251 
  252     int i;
  253     memset(&ud[0], 0, max_users * sizeof(struct user_data));
  254     for (i = 0; i < max_users; i++)
  255             ud[i].user_fd = -1;
  256 }
  257 
  258 int find_free_slot(struct user_data *ud, int max_users) {
  259 
  260     /* Returns the index of the first free ud slot, otherwise
  261            it returns -1 */
  262 
  263     int i;
  264   
  265     for (i = 0; i < max_users; i++)
  266             if (ud++->user_fd == -1) return i;
  267   
  268     return -1;
  269 }
  270 
  271 
  272 #ifndef HAVE_STRLCPY
  273 
  274 /*  $Id: strlcpy.c,v 1.1 2000/07/29 13:33:34 lukem Exp $    */
  275 /*  $NetBSD: strlcpy.c,v 1.5 1999/09/20 04:39:47 lukem Exp $    */
  276 /*  from OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp   */
  277 
  278 /*
  279  * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
  280  * All rights reserved.
  281  *
  282  * Redistribution and use in source and binary forms, with or without
  283  * modification, are permitted provided that the following conditions
  284  * are met:
  285  * 1. Redistributions of source code must retain the above copyright
  286  *    notice, this list of conditions and the following disclaimer.
  287  * 2. Redistributions in binary form must reproduce the above copyright
  288  *    notice, this list of conditions and the following disclaimer in the
  289  *    documentation and/or other materials provided with the distribution.
  290  * 3. The name of the author may not be used to endorse or promote products
  291  *    derived from this software without specific prior written permission.
  292  *
  293  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  294  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  295  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
  296  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  297  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  298  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  299  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  300  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  301  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  302  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  303  */
  304 
  305 /*
  306  * Copy src to string dst of size siz.  At most siz-1 characters
  307  * will be copied.  Always NUL terminates (unless siz == 0).
  308  * Returns strlen(src); if retval >= siz, truncation occurred.
  309  */
  310 size_t
  311 strlcpy(char *dst, const char *src, size_t siz)
  312 {
  313     char *d = dst;
  314     const char *s = src;
  315     size_t n = siz;
  316 
  317     /* Copy as many bytes as will fit */
  318     if (n != 0 && --n != 0) {
  319         do {
  320             if ((*d++ = *s++) == 0)
  321                 break;
  322         } while (--n != 0);
  323     }
  324 
  325     /* Not enough room in dst, add NUL and traverse rest of src */
  326     if (n == 0) {
  327         if (siz != 0)
  328             *d = '\0';      /* NUL-terminate dst */
  329         while (*s++)
  330             ;
  331     }
  332 
  333     return(s - src - 1);    /* count does not include NUL */
  334 }
  335 #endif
  336 
  337 /*
  338  * Copyright (c) 1987, 1993, 1994
  339  *  The Regents of the University of California.  All rights reserved.
  340  *
  341  * Redistribution and use in source and binary forms, with or without
  342  * modification, are permitted provided that the following conditions
  343  * are met:
  344  * 1. Redistributions of source code must retain the above copyright
  345  *    notice, this list of conditions and the following disclaimer.
  346  * 2. Redistributions in binary form must reproduce the above copyright
  347  *    notice, this list of conditions and the following disclaimer in the
  348  *    documentation and/or other materials provided with the distribution.
  349  * 3. All advertising materials mentioning features or use of this software
  350  *    must display the following acknowledgement:
  351  *  This product includes software developed by the University of
  352  *  California, Berkeley and its contributors.
  353  * 4. Neither the name of the University nor the names of its contributors
  354  *    may be used to endorse or promote products derived from this software
  355  *    without specific prior written permission.
  356  *
  357  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  358  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  359  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  360  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  361  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  362  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  363  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  364  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  365  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  366  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  367  * SUCH DAMAGE.
  368  */
  369 
  370 #ifndef HAVE_GETOPT
  371 
  372 int opterr = 1,     /* if error message should be printed */
  373     optind = 1,     /* index into parent argv vector */
  374     optopt,         /* character checked for validity */
  375     optreset;       /* reset getopt */
  376 char    *optarg;        /* argument associated with option */
  377 
  378 #define BADCH   (int)'?'
  379 #define BADARG  (int)':'
  380 #define EMSG    ""
  381 
  382 char *_getprogname(void) {
  383     return "tlswrap";
  384 }
  385 
  386 /*
  387  * getopt --
  388  *  Parse argc/argv argument vector.
  389  */
  390 int
  391 getopt(int nargc, char * const nargv[], const char *ostr) {
  392 
  393     static char *place = EMSG;      /* option letter processing */
  394     char *oli;              /* option letter list index */
  395 
  396     if (optreset || *place == 0) {      /* update scanning pointer */
  397         optreset = 0;
  398         place = nargv[optind];
  399         if (optind >= nargc || *place++ != '-') {
  400             /* Argument is absent or is not an option */
  401             place = EMSG;
  402             return (-1);
  403         }
  404         optopt = *place++;
  405         if (optopt == '-' && *place == 0) {
  406             /* "--" => end of options */
  407             ++optind;
  408             place = EMSG;
  409             return (-1);
  410         }
  411         if (optopt == 0) {
  412             /* Solitary '-', treat as a '-' option
  413                if the program (eg su) is looking for it. */
  414             place = EMSG;
  415             if (strchr(ostr, '-') == NULL)
  416                 return (-1);
  417             optopt = '-';
  418         }
  419     } else
  420         optopt = *place++;
  421 
  422     /* See if option letter is one the caller wanted... */
  423     if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
  424         if (*place == 0)
  425             ++optind;
  426         if (opterr && *ostr != ':')
  427             (void)fprintf(stderr,
  428                 "%s: illegal option -- %c\n", _getprogname(),
  429                 optopt);
  430         return (BADCH);
  431     }
  432 
  433     /* Does this option need an argument? */
  434     if (oli[1] != ':') {
  435         /* don't need argument */
  436         optarg = NULL;
  437         if (*place == 0)
  438             ++optind;
  439     } else {
  440         /* Option-argument is either the rest of this argument or the
  441            entire next argument. */
  442         if (*place)
  443             optarg = place;
  444         else if (nargc > ++optind)
  445             optarg = nargv[optind];
  446         else {
  447             /* option-argument absent */
  448             place = EMSG;
  449             if (*ostr == ':')
  450                 return (BADARG);
  451             if (opterr)
  452                 (void)fprintf(stderr,
  453                     "%s: option requires an argument -- %c\n",
  454                     _getprogname(), optopt);
  455             return (BADCH);
  456         }
  457         place = EMSG;
  458         ++optind;
  459     }
  460     return (optopt);            /* return option letter */
  461 } 
  462 #endif /* !HAVE_GETOPT */
  463 
  464 #ifdef WIN32
  465 #ifndef WIN98
  466 void service_main(DWORD argc, LPTSTR *argv)
  467 {
  468 
  469     BOOL success;
  470 
  471     nServiceStatusHandle = RegisterServiceCtrlHandler(srv_name,
  472         (LPHANDLER_FUNCTION)service_ctrl_handler);
  473     if (!nServiceStatusHandle)
  474         return;
  475     success = update_service_status(SERVICE_START_PENDING,NO_ERROR,0,1,3000);
  476     if (!success)
  477         return;
  478     killServiceEvent = CreateEvent(0,TRUE,FALSE,0);
  479     if (killServiceEvent == NULL)
  480         return;
  481     success = update_service_status(SERVICE_START_PENDING,NO_ERROR,0,2,1000);
  482     if(!success)
  483         return;
  484     success = start_service_thread();
  485     if (!success)
  486         return;
  487     nServiceCurrentStatus = SERVICE_RUNNING;
  488     success = update_service_status(SERVICE_RUNNING,NO_ERROR,0,0,0);
  489     if (!success)
  490         return;
  491     WaitForSingleObject(killServiceEvent,INFINITE);
  492     CloseHandle(killServiceEvent);
  493     _endthread();
  494 }
  495 
  496 BOOL update_service_status(DWORD dwCurrentState, DWORD dwWin32ExitCode,
  497                      DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint,
  498                      DWORD dwWaitHint)
  499 {
  500     BOOL success;
  501     SERVICE_STATUS nServiceStatus;
  502     nServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  503     nServiceStatus.dwCurrentState = dwCurrentState;
  504     if(dwCurrentState == SERVICE_START_PENDING)
  505         nServiceStatus.dwControlsAccepted = 0;
  506     else
  507         nServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP         
  508             |SERVICE_ACCEPT_SHUTDOWN;
  509     if (dwServiceSpecificExitCode == 0)
  510         nServiceStatus.dwWin32ExitCode = dwWin32ExitCode;
  511     else
  512         nServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
  513     nServiceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
  514     nServiceStatus.dwCheckPoint = dwCheckPoint;
  515     nServiceStatus.dwWaitHint = dwWaitHint;
  516 
  517     success = SetServiceStatus(nServiceStatusHandle,&nServiceStatus);
  518 
  519     if (!success) {
  520         kill_service();
  521         return success;
  522     }
  523     else
  524         return success;
  525 }
  526 
  527 BOOL start_service_thread()
  528 {
  529     DWORD id;
  530     hServiceThread = CreateThread(0,0,
  531         (LPTHREAD_START_ROUTINE)service_execution_thread,
  532         NULL,0,&id);
  533     if (hServiceThread == 0)
  534         return false;
  535     else
  536         return true;
  537 }
  538 
  539 void kill_service()
  540 {
  541 //  closesocket(pipe1[0]);
  542     closesocket(pipe1[1]);
  543 //  closesocket(pipe2[0]);
  544 //  closesocket(pipe2[1]);
  545     SetEvent(killServiceEvent);
  546     update_service_status(SERVICE_STOPPED,NO_ERROR,0,0,0);
  547 }
  548 
  549 void service_ctrl_handler(DWORD nControlCode)
  550 {
  551 
  552     switch (nControlCode) {
  553     case SERVICE_CONTROL_SHUTDOWN:
  554     case SERVICE_CONTROL_STOP:
  555         nServiceCurrentStatus = SERVICE_STOP_PENDING;
  556         update_service_status(SERVICE_STOP_PENDING,NO_ERROR,0,1,3000);
  557         kill_service();     
  558         return;
  559     default:
  560         break;
  561     }
  562     update_service_status(nServiceCurrentStatus,NO_ERROR,0,0,0);
  563 }
  564 
  565 void install_service(char *serv, char *serv_opt, int key_wait)
  566 {
  567     SC_HANDLE tlswrap_srv, scm;
  568     SERVICE_DESCRIPTION info[] =
  569     {
  570         {srv_desc},
  571         {NULL},
  572     };
  573 
  574     scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE);
  575     
  576     if(!scm) {
  577         printf("Could not access the service control manager.\n");
  578         if (key_wait) {
  579             printf("Press any key.");
  580             _getch();
  581         }
  582         exit(0);
  583     }
  584 
  585     strcat(serv, "\\tlswrap.exe -S ");
  586     strcat(serv, serv_opt);
  587 
  588     tlswrap_srv = CreateService(scm, 
  589         srv_name, srv_name2,
  590         SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS,SERVICE_AUTO_START,
  591         SERVICE_ERROR_NORMAL,
  592         serv,
  593         0,0,0,0,0);
  594         
  595     if (!tlswrap_srv) {
  596         CloseServiceHandle(scm);
  597         printf("CreateService failed.\n");
  598         if (key_wait) {
  599             printf("Press any key.");
  600             _getch();
  601         }
  602         exit(1);
  603     }
  604     
  605     if (!ChangeServiceConfig2(tlswrap_srv, SERVICE_CONFIG_DESCRIPTION,
  606         &info))
  607         printf("Could not set service description\n");
  608 
  609     printf("TLSWrap service installed.\n");
  610     if (StartService(tlswrap_srv, 0, NULL))
  611         printf("Started TLSWrap service.\n");
  612     else
  613         printf("Could not start TLSWrap service.\n");
  614     CloseServiceHandle(tlswrap_srv);
  615     CloseServiceHandle(scm);
  616     if (key_wait) {
  617         printf("Press any key.");
  618         _getch();
  619     }
  620     exit(0);
  621 
  622 }
  623 
  624 void remove_service(int key_wait)
  625 {
  626     SC_HANDLE       tlswrap_srv, scm;
  627     SERVICE_STATUS  tlswrap_status;
  628     HANDLE          hpipe;
  629 
  630     hpipe = CreateFile( 
  631          "\\\\.\\pipe\\tlswrap_tray",   // pipe name 
  632          GENERIC_WRITE, 
  633          0,              // no sharing 
  634          NULL,           // no security attributes
  635          OPEN_EXISTING,  // opens existing pipe 
  636          0,              // default attributes 
  637          NULL);          // no template file 
  638  
  639 
  640     if (hpipe != INVALID_HANDLE_VALUE) {  
  641         CloseHandle(hpipe);
  642         printf("Killed the TLSWrap Tray Monitor.\n");
  643     } else
  644         printf("Could not find the TLSWrap Tray Monitor running.\n");
  645 
  646     scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE);
  647     
  648     if(!scm) {
  649         printf("Could not access the service control manager.\n");
  650         if (key_wait) {
  651             printf("Press any key.");
  652             _getch();
  653         }
  654         exit(0);
  655     }
  656     if (!(tlswrap_srv = OpenService(scm, srv_name, SERVICE_ALL_ACCESS))) {
  657         printf("No TLSWrap service to remove.\n");
  658         if (key_wait) {
  659             printf("Press any key.\n");
  660             getch();
  661         }
  662         exit(0);
  663     }
  664 
  665     if (ControlService(tlswrap_srv, SERVICE_CONTROL_STOP, &tlswrap_status)) {
  666         printf("Stopping TLSWrap Service");
  667         Sleep(1000);
  668         while (QueryServiceStatus(tlswrap_srv, &tlswrap_status)) {
  669             if (tlswrap_status.dwCurrentState == SERVICE_STOP_PENDING) {
  670                 printf(".");
  671                 Sleep(1000);
  672             } else
  673                 break;
  674         }
  675 
  676         if (tlswrap_status.dwCurrentState == SERVICE_STOPPED)
  677                     printf("\nTLSWrap service stopped.\n");
  678                 else
  679                     printf("\nFailed to stop TLSWrap service.\n");
  680     }
  681     
  682     if (DeleteService(tlswrap_srv))
  683             printf("Removed TLSWrap service.\n");
  684     else
  685             printf("Could not remove TLSWrap service.\n");
  686     CloseServiceHandle(tlswrap_srv);
  687     CloseServiceHandle(scm);
  688     if (key_wait) {
  689         printf("Press any key.\n");
  690         getch();
  691     }
  692     exit(0);
  693 }
  694 
  695 #endif /* !not WIN98 */
  696 
  697 /* Control handler */
  698 
  699 BOOL CtrlHandler(DWORD fdwCtrlType) {
  700 
  701     switch(fdwCtrlType)  { 
  702         // Handle all signals
  703         default:
  704             closesocket(pipe1[1]);
  705 //          closesocket(pipe1[0]);
  706 //          closesocket(pipe2[0]);
  707 //          closesocket(pipe2[1]);
  708             return TRUE;
  709     }
  710 }
  711 
  712 #endif /* !WIN32 */