ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/ihost/ihost.c
(Generate patch)

Comparing projects/cms/source/ihost/ihost.c (file contents):
Revision 1.51 by tdb, Mon May 31 13:35:23 2004 UTC vs.
Revision 1.53 by tdb, Sat Sep 24 13:30:40 2005 UTC

# Line 1 | Line 1
1   /*
2   * i-scream central monitoring system
3   * http://www.i-scream.org
4 < * Copyright (C) 2000-2002 i-scream
4 > * Copyright (C) 2000-2004 i-scream
5   *
6   * This program is free software; you can redistribute it and/or
7   * modify it under the terms of the GNU General Public License
# Line 27 | Line 27
27   #include <unistd.h>
28   #include <string.h>
29   #include <sys/types.h>
30 #include <sys/socket.h>
30   #include <stdarg.h>
31   #include <errno.h>
32 + #ifndef WIN32
33 + #include <sys/socket.h>
34   #include <netdb.h>
35   #include <netinet/in.h>
36 + #else
37 + #include <winsock2.h>
38 + #include <getopt.h>
39 + #endif
40   #include <time.h>
41  
42   #include <ukcprog.h>
# Line 42 | Line 47
47   #define LOG_INFO 2
48   #define LOG_DEBUG 3
49  
50 + #define SERVICENAME "ihost"
51 +
52 + /* Windows printf does not understand %lld, so we have to use %I64d */
53 + #ifdef WIN32
54 + #define LLD "%I64d"
55 + #define OPTSTRING "vVn:i:s:p:w:h"
56 + #define SLEEP 10000
57 + #else
58 + #define LLD "%lld"
59 + #define OPTSTRING "vfVn:i:s:p:h"
60 + #define SLEEP 10
61 + #endif
62 +
63 + /* The "socket" */
64 + #ifdef WIN32
65 + #define IHOST_SOCKET SOCKET
66 + #define CLOSESOCKET(socket) closesocket(socket)
67 + #else
68 + #define IHOST_SOCKET FILE *
69 + #define CLOSESOCKET(socket) fclose(socket)
70 + #endif
71 +
72   typedef struct{
73          int filtermanager_port;
74          char *filtermanager_host;
# Line 77 | Line 104 | typedef struct{
104   }udp_sockinfo_t;
105  
106   ihost_config_t ihost_config;
107 + ihost_state_t ihost_state;
108  
109   extern int errno;
110  
111 + #ifdef WIN32
112 + int run_server = 1;
113 + int run_as_service = 0;
114 + SERVICE_STATUS service_status;
115 + SERVICE_STATUS_HANDLE hstatus;
116 + #endif
117 +
118   /* Taken from the OpenSSH code. Its licence included in function.*/
119   #ifndef HAVE_STRLCAT
120  
# Line 194 | Line 229 | int create_udp_sockinfo(udp_sockinfo_t *udp_sockinfo,
229          return 0;
230   }
231  
232 < FILE *create_tcp_connection(char *hostname, int port){
232 > IHOST_SOCKET create_tcp_connection(char *hostname, int port){
233 > #ifdef WIN32
234 >        SOCKET sock;
235 > #else
236          int sock;
237 + #endif
238          struct sockaddr_in addr;
239          struct in_addr haddr;
240          FILE *f;
# Line 203 | Line 242 | FILE *create_tcp_connection(char *hostname, int port){
242          log_msg(LOG_DEBUG, "Creating tcp socket");
243          if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))<0){
244                  log_msg(LOG_CRIT, "Failed to make TCP Socket");
245 <                return NULL;
245 >                goto out;
246          }
247  
248          if((get_host_addr(hostname, &haddr))!=0){
249                  log_msg(LOG_CRIT, "Failed to lookup name for %s", hostname);
250                  close(sock);
251 <                return NULL;
251 >                goto out;
252          }
253  
254          memset(&addr, 0, sizeof(addr));
# Line 221 | Line 260 | FILE *create_tcp_connection(char *hostname, int port){
260          if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) !=0){
261                  log_msg(LOG_CRIT, "Failed to connect to hostname %s on port %d", hostname, port);
262                  close(sock);
263 <                return NULL;
263 >                goto out;
264          }
265  
266 + #ifndef WIN32
267 + /* Windows does not treat sockets like this :( */
268          if((f=fdopen(sock, "r+"))==NULL){
269                  log_msg(LOG_CRIT, "Failed to connect to open filedescriptor on tcp connection");
270                  close(sock);
# Line 231 | Line 272 | FILE *create_tcp_connection(char *hostname, int port){
272          }
273  
274          return f;
275 + #else
276 +        return sock;
277 + #endif
278 +
279 + out:
280 + #ifdef WIN32
281 +        return 0;
282 + #else
283 +        return NULL;
284 + #endif
285   }
286  
287 + #ifndef WIN32
288   int tcp_comm(FILE *f, char *send, char **response, char *expected){
289  
290          log_msg(LOG_DEBUG, "Sending %s", send);
# Line 252 | Line 304 | int tcp_comm(FILE *f, char *send, char **response, cha
304          log_msg(LOG_DEBUG, "Did not get expected response");
305          return -1;
306   }
307 + #else
308 + int tcp_comm(SOCKET soc, char *sendstr, char **response, char *expected) {
309 +        static char *rec = NULL;
310 +        char sendbuf[128];
311 +        char recbuf[128];
312 +        int bytesRecv;
313 +        char *tmp;
314 +        
315 +        sprintf(sendbuf, "%s\n", sendstr);
316  
317 < int tcp_comm_strdup(FILE *f, char *send, char **response, char *expected){
317 >        log_msg(LOG_DEBUG, "Sending %s", sendstr);
318 >        send(soc, sendbuf, strlen(sendbuf), 0);
319 >        bytesRecv = recv(soc, recbuf, 128, 0);
320 >
321 >        if(bytesRecv != 0 && bytesRecv != SOCKET_ERROR) {
322 >                /* remove \n and copy to a string */
323 >                recbuf[bytesRecv-1] = '\0';
324 >                tmp = realloc(rec, bytesRecv);
325 >                if(tmp == NULL) {
326 >                        free(rec);
327 >                        rec = NULL;
328 >                        log_msg(LOG_CRIT, "out of memory");
329 >                        return -1;
330 >                }
331 >                rec = tmp;
332 >                rec = strcpy(rec, recbuf);
333 >                *response = rec;
334 >                log_msg(LOG_DEBUG, "Received %s", *response);
335 >        } else {
336 >                return -1;
337 >        }
338 >        if(strcmp(*response, "ERROR")==0) return -1;
339 >
340 >        if(expected==NULL) return 0;
341 >
342 >        if((strcmp(expected, *response))==0) return 0;
343 >
344 >        log_msg(LOG_DEBUG, "Did not get expected response");
345 >        return -1;
346 > }
347 > #endif /* WIN32 */
348 >
349 > int tcp_comm_strdup(IHOST_SOCKET f, char *send, char **response, char *expected)
350 > {
351          if((tcp_comm(f, send, response, expected))!=0){
352                  return -1;
353          }
# Line 265 | Line 359 | int tcp_comm_strdup(FILE *f, char *send, char **respon
359   }
360  
361   int ihost_getconfig(ihost_state_t *ihost_state){
362 <
269 <        FILE *tcp_con;
362 >        IHOST_SOCKET tcp_con;
363          char *response;
364          char *response_ptr;
365  
# Line 280 | Line 373 | int ihost_getconfig(ihost_state_t *ihost_state){
373          int server_udp_port=0;
374          time_t config_ttl=0;
375  
376 <        if((tcp_con=create_tcp_connection(ihost_state->filtermanager_host, ihost_state->filtermanager_port))==NULL){
376 >        if((tcp_con=create_tcp_connection(ihost_state->filtermanager_host, ihost_state->filtermanager_port))
377 > #ifndef WIN32
378 >                        ==NULL
379 > #else
380 >                        ==0
381 > #endif
382 >                        ) {
383                  return -1;
384          }
385  
386          if(ihost_state->file_list!=NULL || ihost_state->last_modified!=NULL){
387 <                if(tcp_con==NULL){
387 > #ifndef WIN32
388 >                if(tcp_con==NULL)
389 > #else
390 >                if(tcp_con==0)
391 > #endif
392 >                {
393                          goto error;
394                  }
395  
# Line 301 | Line 405 | int ihost_getconfig(ihost_state_t *ihost_state){
405                          if((tcp_comm(tcp_con, "END", &response, "OK"))!=0){
406                                  goto error;
407                          }
408 <                        fclose(tcp_con);
408 >                        CLOSESOCKET(tcp_con);
409                          return 0;
410                  }else{
411                          if((strcmp(response, "EXPIRED"))!=0){
# Line 381 | Line 485 | int ihost_getconfig(ihost_state_t *ihost_state){
485                  goto error;
486          }
487  
488 <        fclose(tcp_con);
488 >        CLOSESOCKET(tcp_con);
489  
490          /* We have the data we need, and its all been read correctly */
491  
# Line 425 | Line 529 | error:
529          if(host_fqdn!=NULL) free(host_fqdn);
530          if(server_fqdn!=NULL) free(server_fqdn);
531          if(host_ip!=NULL) free(host_ip);
532 <        fclose(tcp_con);
532 >        CLOSESOCKET(tcp_con);
533  
534          return -1;
535   }
# Line 473 | Line 577 | int get_system_stats(int seq_no, ihost_state_t *ihost_
577  
578  
579          /*Get mem stats, and fill in xml */
580 +
581          if((mem_stats=sg_get_mem_stats())==NULL){
582                  log_msg(LOG_CRIT, "Failed to get memory statistics: %s (%s)",
583                          sg_str_error(sg_get_error()), sg_get_error_arg());
584          }else{
585                  snprintf(tmp, size, \
586 <                        "<memory><total>%lld</total><free>%lld</free><used>%lld</used><cache>%lld</cache></memory>", \
586 >                        "<memory><total>"LLD"</total><free>"LLD"</free><used>"LLD"</used><cache>"LLD"</cache></memory>", \
587                          mem_stats->total, \
588                          mem_stats->free, \
589                          mem_stats->used, \
# Line 489 | Line 594 | int get_system_stats(int seq_no, ihost_state_t *ihost_
594  
595  
596          /* Get load stats */
597 +
598          if((load_stats=sg_get_load_stats())==NULL){
599                  log_msg(LOG_CRIT, "Failed to get load statistics: %s (%s)",
600                          sg_str_error(sg_get_error()), sg_get_error_arg());
# Line 519 | Line 625 | int get_system_stats(int seq_no, ihost_state_t *ihost_
625  
626  
627          /* swap stats */
628 +
629          if((swap_stats=sg_get_swap_stats())==NULL){
630                  log_msg(LOG_CRIT, "Failed to get swap statistics: %s (%s)",
631                          sg_str_error(sg_get_error()), sg_get_error_arg());
632          }else{
633                  snprintf(tmp, size, \
634 <                        "<swap><total>%lld</total><used>%lld</used><free>%lld</free></swap>",\
634 >                        "<swap><total>"LLD"</total><used>"LLD"</used><free>"LLD"</free></swap>",\
635                          swap_stats->total, \
636                          swap_stats->used, \
637                          swap_stats->free);
# Line 554 | Line 661 | int get_system_stats(int seq_no, ihost_state_t *ihost_
661  
662  
663          /* process stats */
664 +
665          if((process_stats=sg_get_process_count())==NULL){
666                  log_msg(LOG_CRIT, "Failed to get process statistics: %s (%s)",
667                          sg_str_error(sg_get_error()), sg_get_error_arg());
# Line 572 | Line 680 | int get_system_stats(int seq_no, ihost_state_t *ihost_
680  
681  
682          /* Get paging stats */
683 +
684          if((page_stats=sg_get_page_stats_diff())==NULL){
685                  log_msg(LOG_CRIT, "Failed to get paging statistics: %s (%s)",
686                          sg_str_error(sg_get_error()), sg_get_error_arg());
# Line 584 | Line 693 | int get_system_stats(int seq_no, ihost_state_t *ihost_
693                          y=page_stats->pages_pageout;
694                  }
695                  snprintf(tmp, size, \
696 <                        "<pages><pageins>%lld</pageins><pageouts>%lld</pageouts></pages>", \
696 >                        "<pages><pageins>"LLD"</pageins><pageouts>"LLD"</pageouts></pages>", \
697                          x, \
698                          y);
699  
# Line 610 | Line 719 | int get_system_stats(int seq_no, ihost_state_t *ihost_
719                          }
720  
721                          snprintf(tmp, size, \
722 <                                "<p%d name=\"%s\" rbytes=\"%lld\" wbytes=\"%lld\"></p%d>", \
722 >                                "<p%d name=\"%s\" rbytes=\""LLD"\" wbytes=\""LLD"\"></p%d>", \
723                                  counter, \
724                                  diskio_stats->disk_name, \
725                                  x, \
# Line 643 | Line 752 | int get_system_stats(int seq_no, ihost_state_t *ihost_
752                          }
753  
754                          snprintf(tmp, size, \
755 <                                "<p%d name=\"%s\" rx=\"%lld\" tx=\"%lld\"></p%d>", \
755 >                                "<p%d name=\"%s\" rx=\""LLD"\" tx=\""LLD"\"></p%d>", \
756                                  counter, \
757                                  network_stats->interface_name, \
758                                  x, \
# Line 668 | Line 777 | int get_system_stats(int seq_no, ihost_state_t *ihost_
777                  strlcat(xml, "<disk>", size);
778                  for(counter=0;counter<disk_entries;counter++){
779                          snprintf(tmp, size, \
780 <                                "<p%d name=\"%s\" mount=\"%s\" fstype=\"%s\" total=\"%lld\" used=\"%lld\" avail=\"%lld\" totalinodes=\"%lld\" usedinodes=\"%lld\" freeinodes=\"%lld\"></p%d>", \
780 >                                "<p%d name=\"%s\" mount=\"%s\" fstype=\"%s\" total=\""LLD"\" used=\""LLD"\" avail=\""LLD"\" totalinodes=\""LLD"\" usedinodes=\""LLD"\" freeinodes=\""LLD"\"></p%d>", \
781                                  counter, \
782                                  disk_stats->device_name, \
783                                  disk_stats->mnt_point, \
# Line 703 | Line 812 | too_big_error:
812  
813  
814  
815 + /* WIN32 NT service stuff */
816 + #ifdef WIN32
817 + void service_stopped() {
818 +        if(run_as_service) {
819 +                service_status.dwCurrentState = SERVICE_STOPPED;
820 +                service_status.dwWin32ExitCode = errno;
821 +                service_status.dwServiceSpecificExitCode = 0;
822 +
823 +                SetServiceStatus(hstatus, &service_status);
824 +        }
825 + }
826 +
827 + void control_handler(DWORD request) {
828 +        switch(request) {
829 +                case SERVICE_CONTROL_STOP:
830 +                case SERVICE_CONTROL_SHUTDOWN:
831 +                        service_status.dwWin32ExitCode = 0;
832 +                        service_status.dwCurrentState = SERVICE_STOP_PENDING;
833 +                        break;
834 +                default:
835 +                        break;
836 +        }
837 +
838 +        SetServiceStatus (hstatus, &service_status);
839 + }
840 +
841 + /* attempt to tell service manager to start our service.
842 + * return 0 on error, 1 on ok
843 + */
844 + int start_service() {
845 +        SC_HANDLE scm;
846 +        SC_HANDLE service;
847 +
848 +        // Open SCM
849 +        if((scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT)) == NULL) {
850 +                log_msg(LOG_CRIT, "Failed to open Service Control Manager");
851 +                return 0;
852 +        }
853 +        // Locate the service
854 +        if((service = OpenService(scm, SERVICENAME, SERVICE_START)) == NULL) {
855 +                log_msg(LOG_CRIT, "Unable to open the service");
856 +                return 0;
857 +        }
858 +        // Start the service
859 +        if(StartService(service, 0, NULL) == 0) {
860 +                log_msg(LOG_CRIT, "Unable to start the service");
861 +                return 0;
862 +        }
863 +        return 1;
864 + }
865 +
866 + int stop_service() {
867 +        SC_HANDLE scm;
868 +        SC_HANDLE service;
869 +        SERVICE_STATUS status;
870 +
871 +        // Open SCM
872 +        if((scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT)) == NULL) {
873 +                log_msg(LOG_CRIT, "Failed to open Service Control Manager");
874 +                return 0;
875 +        }
876 +        // Locate service
877 +        if((service = OpenService(scm, SERVICENAME, SERVICE_STOP)) == NULL) {
878 +                log_msg(LOG_CRIT, "Unable to open the service");
879 +                return 0;
880 +        }
881 +        // Stop the service
882 +        if(!ControlService(service, SERVICE_CONTROL_STOP, &status)) {
883 +                log_msg(LOG_CRIT, "Unable to stop the service");
884 +                return 0;
885 +        }
886 +        return 1;
887 + }
888 +
889 + int register_service(int argc, char **argv) {
890 +        char path[MAX_PATH];
891 +        int cmdline_len;
892 +        int i;
893 +        char *cmdline;
894 +        char *tmp;
895 +        SC_HANDLE scm;
896 +
897 +        if(!GetModuleFileName(NULL, path, MAX_PATH)) {
898 +                log_msg(LOG_CRIT, "GetModuleFileName failed");
899 +                return 0;
900 +        }
901 +
902 +        // Calculate command line length
903 +        // 14 = 10 for " -w service", 2x quote around path and ending \0
904 +        cmdline_len = strlen(path) + 14;
905 +        for (i=0; i<argc; i++) {
906 +                // +1 for space prefix
907 +                cmdline_len += strlen(argv[i]) +1;
908 +        }
909 +
910 +        cmdline = malloc(cmdline_len);
911 +        if(cmdline == NULL) {
912 +                log_msg(LOG_CRIT, "out of memory");
913 +                return 0;
914 +        }
915 +        tmp = malloc(cmdline_len);
916 +        if(tmp == NULL) {
917 +                log_msg(LOG_CRIT, "out of memory");
918 +                free(cmdline);
919 +                return 0;
920 +        }
921 +
922 +        // Compile up the final command line call
923 +        snprintf(cmdline, cmdline_len, "\"%s\" -w service", path);
924 +        for (i=0; i<argc; i++) {
925 +                snprintf(tmp, cmdline_len, " %s", argv[i]);
926 +                strcat(cmdline, tmp);
927 +        }
928 +        free(tmp);
929 +
930 +        // Open SCM
931 +        if((scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE)) == NULL) {
932 +                log_msg(LOG_CRIT, "Unable to open Service Control Manager");
933 +                return 0;
934 +        }
935 +
936 +        // Add the service
937 +        if (CreateService(scm, SERVICENAME, SERVICENAME,
938 +                        SC_MANAGER_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
939 +                        SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, cmdline, NULL,
940 +                        NULL, NULL, NULL, NULL) == NULL) {
941 +                log_msg(LOG_CRIT, "Unable to create service");
942 +                return 0;
943 +        }
944 +
945 +        return 1;
946 + }
947 +
948 + int unregister_service() {
949 +        SC_HANDLE scm;
950 +        SC_HANDLE service;
951 +
952 +        // Open the SCM
953 +        if((scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE)) ==NULL) {
954 +                log_msg(LOG_CRIT, "Unable to open Service Control Manager");
955 +                return 0;
956 +        }
957 +        // Get the service
958 +        if((service = OpenService(scm, SERVICENAME, SC_MANAGER_ALL_ACCESS)) == NULL) {
959 +                log_msg(LOG_CRIT, "Unable to locate the service");
960 +                return 0;
961 +        }
962 +        // Delete service
963 +        if(DeleteService(service) == 0) {
964 +                log_msg(LOG_CRIT, "Unable to remove the service");
965 +                return 0;
966 +        }
967 +        return 1;
968 + }
969 + #endif
970 +
971 +
972 +
973   void usage(char *progname){
974 <        fprintf(stderr, "Usage %s [-v[v]] [-f] [-n name] [-i ip] [-s server] [-p port] [-V] [-h]\n\n", progname);
974 >        const char *usage;
975 > #ifdef WIN32
976 >        usage = "Usage %s [-w option] [-v[v]] [-n name] [-i ip] [-s server] [-p port] [-V] [-h]\n\n";
977 > #else
978 >        usage = "Usage %s [-v[v]] [-f] [-n name] [-i ip] [-s server] [-p port] [-V] [-h]\n\n";
979 > #endif
980 >        fprintf(stderr, usage, progname);
981          fprintf(stderr, "  -v    Verbose mode, -vv would make even more verbose\n");
982 + #ifndef WIN32
983          fprintf(stderr, "  -f    Foreground mode, print errors to stderr\n");
984 + #else
985 +        fprintf(stderr, "  -w    Windows Service options:\n");
986 +        fprintf(stderr, "     start      - start the service\n");
987 +        fprintf(stderr, "     stop       - stop the service\n");
988 +        fprintf(stderr, "     register   - register the service\n");
989 +        fprintf(stderr, "     unregister - unregister the service\n");
990 +        /* service - run as a service, only called by windows service */
991 + #endif
992          fprintf(stderr, "  -n    Set the machine name to be reported as\n");
993          fprintf(stderr, "  -i    Set the IP to be reported as\n");
994          fprintf(stderr, "  -s    Specifies the i-scream server to connect to\n");
# Line 719 | Line 1001 | void usage(char *progname){
1001          exit(1);
1002   }
1003  
1004 < int main(int argc, char **argv){
1004 > int run_ihost(){
1005  
724        ihost_state_t ihost_state;
1006          udp_sockinfo_t udp_sockinfo;
1007  
727        int cmdopt;
728        extern int optind;
1008          pid_t pid;
1009          FILE *f;
1010          int packet_num=0;
# Line 734 | Line 1013 | int main(int argc, char **argv){
1013          char packet[MAX_UDP_PACKET_SIZE];
1014  
1015          time_t cur_time, sleep_delay, udp_time=0, config_time=0;
1016 + #ifdef WIN32
1017 +        int tries=0;
1018 +        WSADATA wsaData;
1019  
1020 <        /* Set default settings */
1021 <        ihost_config.verbose=1;
1022 <        ihost_config.daemon=1;
1023 <        /* Set all errors to go down stderr until told otherwise */
742 <        ihost_config.log=stderr;
743 <
744 <        /* Blank ihost_state to default settings */
745 <        ihost_state.filtermanager_host=DEF_SERVER_NAME;
746 <        ihost_state.filtermanager_port=DEF_SERVER_PORT;
747 <        ihost_state.host_fqdn=NULL;
748 <        ihost_state.host_ip=NULL;
749 <        ihost_state.preset_fqdn = 0;
750 <        ihost_state.preset_ip = 0;
751 <        ihost_state.server_fqdn=NULL;
752 <        ihost_state.file_list=NULL;
753 <        ihost_state.last_modified=NULL;
754 <
755 <        while((cmdopt=getopt(argc, argv, "vfVn:i:s:p:h")) != -1){
756 <                switch(cmdopt){
757 <                        case 'v':
758 <                                ihost_config.verbose++;
759 <                                break;
760 <
761 <                        case 'f':
762 <                                /* Force syslog logging since stderr will be closed in this case */
763 <                                ihost_config.daemon=0;
764 <                                break;
765 <
766 <                        case 'V':
767 <                                fprintf(stderr, "%s version %s\n", argv[0], VERSION);
768 <                                break;
769 <                        case 'n':
770 <                                ihost_state.preset_fqdn = 1;
771 <                                ihost_state.host_fqdn = strdup(optarg);
772 <                                if(ihost_state.host_fqdn == NULL){
773 <                                        fprintf(stderr, "Missing hostname\n");
774 <                                        usage(argv[0]);
775 <                                }
776 <                                break;
777 <                        case 'i':
778 <                                /* Hmm.. Someone could set any string to be the IP, and it will let it */
779 <                                ihost_state.preset_ip = 1;
780 <                                ihost_state.host_ip = strdup(optarg);
781 <                                if(ihost_state.host_ip == NULL){
782 <                                        fprintf(stderr, "Missing ip\n");
783 <                                        usage(argv[0]);
784 <                                }
785 <                                break;
786 <
787 <                        case 's':
788 <                                ihost_state.filtermanager_host=strdup(optarg);
789 <                                break;
790 <
791 <                        case 'p':
792 <                                ihost_state.filtermanager_port=atoi(optarg);
793 <                                break;
794 <
795 <                        case 'h':
796 <                        default:
797 <                                usage(argv[0]);
798 <                                exit(1);
799 <                }
1020 >        if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) {
1021 >                log_msg(LOG_CRIT, "Failed to init a winsock");
1022 >                service_stopped();
1023 >                exit(1);
1024          }
1025 + #endif
1026  
1027          if(gethostbyname(ihost_state.filtermanager_host)==NULL){
1028 +                printf("%s\n", ihost_state.filtermanager_host);
1029                  log_msg(LOG_CRIT, "Failed to lookup hostname. Please check settings");
1030 <                exit(1);
1030 >                goto out;
1031          }
1032          if(ihost_state.filtermanager_port==0){
1033                  log_msg(LOG_ERR, "Invalid port number");
1034 <                exit(1);
1034 >                goto out;
1035          }
1036  
1037 + #ifndef WIN32
1038          if(ihost_config.daemon){
1039                  pid=fork();
1040                  if(pid==-1){
# Line 834 | Line 1061 | int main(int argc, char **argv){
1061                  fclose(stderr);
1062  
1063          }
1064 + #endif
1065  
1066          log_msg(LOG_INFO, "Starting ihost...");
1067  
# Line 841 | Line 1069 | int main(int argc, char **argv){
1069          if(sg_init()){
1070                  log_msg(LOG_CRIT, "sg_init failed: %s (%s)",
1071                          sg_str_error(sg_get_error()), sg_get_error_arg());
1072 <                exit(1);
1072 >                goto out;
1073          }
1074 +        if(sg_snapshot()) {
1075 +                log_msg(LOG_ERR, "sg_snapshot failed: %s (%s)",
1076 +                        sg_str_error(sg_get_error()), sg_get_error_arg());
1077 +        }
1078  
1079 + #ifndef WIN32
1080          log_msg(LOG_DEBUG,"Writing PID FILE");
1081  
1082          pid=getpid();
# Line 858 | Line 1091 | int main(int argc, char **argv){
1091                          log_msg(LOG_CRIT, "failed to close PID file");
1092                  }
1093          }
1094 + #endif
1095  
1096          /* Get the initial config from the filter manager. Should this fail,
1097           * wait, and then try again. */
1098 +        /* Win32 - for a max of one minute */
1099  
1100          sg_get_disk_io_stats_diff(&packet_num);
1101          packet_num=0;
1102  
1103 <        while(ihost_getconfig(&ihost_state)!=0){
1103 >        while(ihost_getconfig(&ihost_state)!=0
1104 > #ifdef WIN32
1105 >                        && (tries<6)
1106 > #endif
1107 >                        ){
1108                  log_msg(LOG_ERR, "Failed to get ihost config");
1109 <                sleep(10);
1109 >                sleep(SLEEP);
1110 > #ifdef WIN32
1111 >                tries++;
1112 > #endif
1113          }
1114  
1115 <        while((create_udp_sockinfo(&udp_sockinfo, ihost_state.server_fqdn, ihost_state.server_udp_port))!=0){
1115 > #ifdef WIN32
1116 >        if (tries == 6) {
1117 >                log_msg(LOG_ERR, "Giving up");
1118 >                goto out;
1119 >        }
1120 >        tries = 0;
1121 > #endif
1122 >
1123 >        while((create_udp_sockinfo(&udp_sockinfo, ihost_state.server_fqdn, ihost_state.server_udp_port))!=0
1124 > #ifdef WIN32
1125 >                        && (tries<6)
1126 > #endif
1127 >                        ){
1128                  log_msg(LOG_ERR, "Failed to create udp socket");
1129 <                sleep(10);
1129 >                sleep(SLEEP);
1130 > #ifdef WIN32
1131 >                tries++;
1132 > #endif
1133          }
1134  
1135 + #ifdef WIN32
1136 +        if (tries == 6) {
1137 +                log_msg(LOG_ERR, "Giving up");
1138 +                goto out;
1139 +        }
1140 + #endif
1141 +
1142          config_time=time(NULL)+ihost_state.config_ttl;
1143  
1144 + #ifdef WIN32
1145 +        /* Finally, we have started successfully!
1146 +         * We set state to running even for non-service calls so the while
1147 +         * loop works. Bit of a hack ;)
1148 +         */
1149 +        service_status.dwCurrentState = SERVICE_RUNNING;
1150 +        if(run_as_service) {
1151 +                SetServiceStatus(hstatus, &service_status);
1152 +        }
1153 +        printf("started\n");
1154 + #endif
1155 +
1156          /* Now have config.. collect data and send as often as required */
1157 <        for(;;){
1157 > #ifdef WIN32
1158 >        while(service_status.dwCurrentState == SERVICE_RUNNING)
1159 > #else
1160 >        for(;;)
1161 > #endif
1162 >        {
1163                  cur_time=time(NULL);
1164  
1165                  if(cur_time>=udp_time){
1166 +                        if(sg_snapshot()) {
1167 +                                log_msg(LOG_ERR, "sg_snapshot failed: %s (%s)",
1168 +                                        sg_str_error(sg_get_error()), sg_get_error_arg());
1169 +                                continue; /* Could this get ugly? */
1170 +                        }
1171                          if((get_system_stats(packet_num++, &ihost_state, packet, MAX_UDP_PACKET_SIZE))!=0){
1172                                  log_msg(LOG_ERR, "Failed to get system stats");
1173                          }
# Line 906 | Line 1192 | int main(int argc, char **argv){
1192  
1193                                  while((create_udp_sockinfo(&udp_sockinfo, ihost_state.server_fqdn, ihost_state.server_udp_port))!=0){
1194                                          log_msg(LOG_CRIT, "Failed to create udp socket");
1195 <                                        sleep(10);
1195 >                                        sleep(SLEEP);
1196                                  }
1197  
1198                                  config_time=time(NULL)+ihost_state.config_ttl;
# Line 917 | Line 1203 | int main(int argc, char **argv){
1203  
1204                  sleep_delay=udp_time-time(NULL);
1205                  log_msg(LOG_DEBUG, "Sleeping for %d", sleep_delay);
1206 + #ifdef WIN32
1207 +                /* convert to millisecs */
1208 +                sleep_delay *= 1000;
1209 + #endif
1210                  if(sleep_delay>0) sleep(sleep_delay);
1211          }
1212  
1213 +        if(sg_shutdown()) {
1214 +                log_msg(LOG_ERR, "sg_shutdown failed: %s (%s)",
1215 +                        sg_str_error(sg_get_error()), sg_get_error_arg());
1216 +        }
1217 +
1218 + #ifdef WIN32
1219 +        WSACleanup();
1220 +        if(run_as_service) {
1221 +                service_status.dwWin32ExitCode = 0;
1222 +                service_status.dwCurrentState = SERVICE_STOPPED;
1223 +                SetServiceStatus(hstatus, &service_status);
1224 +        }
1225 + #endif
1226 +        log_msg(LOG_ERR, "ihost shutdown successfully");
1227 +        fclose(ihost_config.log);
1228 +
1229          return(0);
1230 +
1231 + out:
1232 + #ifdef WIN32
1233 +        WSACleanup();
1234 +        service_stopped();
1235 + #endif
1236 +        exit(1);
1237 + }
1238 +
1239 + #ifdef WIN32
1240 + int service_main(int argc, char **argv) {
1241 +        int error;
1242 +
1243 +        service_status.dwServiceType = SERVICE_WIN32;
1244 +        service_status.dwCurrentState = SERVICE_START_PENDING;
1245 +        service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
1246 +                SERVICE_ACCEPT_SHUTDOWN;
1247 +        service_status.dwWin32ExitCode = 0;
1248 +        service_status.dwServiceSpecificExitCode = 0;
1249 +        service_status.dwCheckPoint = 0;
1250 +        service_status.dwWaitHint = 0;
1251 +
1252 +        hstatus = RegisterServiceCtrlHandler(SERVICENAME,
1253 +                        (LPHANDLER_FUNCTION)control_handler);
1254 +        if(hstatus == (SERVICE_STATUS_HANDLE)0) {
1255 +                log_msg(LOG_CRIT, "RegisterServiceCtrlHandle failed");
1256 +                return -1;
1257 +        }
1258 +
1259 +        return run_ihost();
1260 + }
1261 +
1262 +
1263 + void parse_w(int argc, char **argv) {
1264 +        if (strcasecmp(optarg, "start") == 0) {
1265 +                log_msg(LOG_ERR, "Attempting to start service...");
1266 +                run_server = 0;
1267 +                if(start_service())
1268 +                        log_msg(LOG_ERR, "Service started");
1269 +        } else if (strcasecmp(optarg, "stop") == 0) {
1270 +                log_msg(LOG_ERR, "Attempting to stop service...");
1271 +                run_server = 0;
1272 +                if(stop_service())
1273 +                        log_msg(LOG_ERR, "Service stopped");
1274 +        } else if (strcasecmp(optarg, "service") == 0) {
1275 +                run_as_service = 1;
1276 +        } else if (strcasecmp(optarg, "register") == 0) {
1277 +                log_msg(LOG_ERR, "Attempting to register service...");
1278 +                run_server = 0;
1279 +                int i = optind;
1280 +                optind = argc;
1281 +                /* Grab the remaining arguments and use each time the service
1282 +                 * is started */
1283 +                if (register_service(argc-i, &argv[i]))
1284 +                        log_msg(LOG_ERR, "Registered service successfully");
1285 +        } else if (strcasecmp(optarg, "unregister") == 0) {
1286 +                log_msg(LOG_ERR, "Attempting to unregister service...");
1287 +                run_server = 0;
1288 +                if(unregister_service())
1289 +                        log_msg(LOG_ERR, "Unregistered service successfully");
1290 +        } else {
1291 +                fprintf(stderr, "Unknown -w option\n");
1292 +                usage(argv[0]);
1293 +                exit(1);
1294 +        }
1295 + }
1296 + #endif
1297 +
1298 +
1299 + int main(int argc, char **argv){
1300 +        int cmdopt;
1301 +        extern int optind;
1302 +
1303 +        /* Set default settings */
1304 +        ihost_config.verbose=1;
1305 +        ihost_config.daemon=1;
1306 +        /* Set all errors to go down stderr until told otherwise */
1307 +        ihost_config.log=stderr;
1308 +
1309 +        /* Blank ihost_state to default settings */
1310 +        ihost_state.filtermanager_host=DEF_SERVER_NAME;
1311 +        ihost_state.filtermanager_port=DEF_SERVER_PORT;
1312 +        ihost_state.host_fqdn=NULL;
1313 +        ihost_state.host_ip=NULL;
1314 +        ihost_state.preset_fqdn = 0;
1315 +        ihost_state.preset_ip = 0;
1316 +        ihost_state.server_fqdn=NULL;
1317 +        ihost_state.file_list=NULL;
1318 +        ihost_state.last_modified=NULL;
1319 +
1320 +        while((cmdopt=getopt(argc, argv, OPTSTRING)) != -1){
1321 +                switch(cmdopt){
1322 +                        case 'v':
1323 +                                ihost_config.verbose++;
1324 +                                break;
1325 +
1326 + #ifndef WIN32
1327 +                        case 'f':
1328 +                                /* Force syslog logging since stderr will be closed in this case */
1329 +                                ihost_config.daemon=0;
1330 +                                break;
1331 + #endif
1332 +
1333 +                        case 'V':
1334 +                                fprintf(stderr, "%s version %s\n", argv[0], VERSION);
1335 +                                break;
1336 +                        case 'n':
1337 +                                ihost_state.preset_fqdn = 1;
1338 +                                ihost_state.host_fqdn = strdup(optarg);
1339 +                                if(ihost_state.host_fqdn == NULL){
1340 +                                        fprintf(stderr, "Missing hostname\n");
1341 +                                        usage(argv[0]);
1342 +                                }
1343 +                                break;
1344 +                        case 'i':
1345 +                                /* Hmm.. Someone could set any string to be the IP, and it will let it */
1346 +                                ihost_state.preset_ip = 1;
1347 +                                ihost_state.host_ip = strdup(optarg);
1348 +                                if(ihost_state.host_ip == NULL){
1349 +                                        fprintf(stderr, "Missing ip\n");
1350 +                                        usage(argv[0]);
1351 +                                }
1352 +                                break;
1353 +
1354 +                        case 's':
1355 +                                ihost_state.filtermanager_host=strdup(optarg);
1356 +                                break;
1357 +
1358 +                        case 'p':
1359 +                                ihost_state.filtermanager_port=atoi(optarg);
1360 +                                break;
1361 +
1362 + #ifdef WIN32
1363 +                        case 'w':
1364 +                                parse_w(argc, argv);
1365 +                                break;
1366 + #endif
1367 +
1368 +                        case 'h':
1369 +                        default:
1370 +                                usage(argv[0]);
1371 +                                exit(1);
1372 +                }
1373 +        }
1374 +
1375 + #ifdef WIN32
1376 +        if (run_server) {
1377 +                if(run_as_service) {
1378 +                        if((ihost_config.log=fopen(LOG_FILE, "a"))==NULL){
1379 +                                ihost_config.log=stderr;
1380 +                                log_msg(LOG_CRIT, "Failed to open Logfiles %s for writing", LOG_FILE);
1381 +                                exit(1);
1382 +                        }
1383 +                        log_msg(LOG_ERR, "Starting Service-Mode i-host");
1384 +                        SERVICE_TABLE_ENTRY service_table[2];
1385 +                        service_table[0].lpServiceName = SERVICENAME;
1386 +                        service_table[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)service_main;
1387 +                        service_table[1].lpServiceName = NULL;
1388 +                        service_table[1].lpServiceProc = NULL;
1389 +                        return StartServiceCtrlDispatcher(service_table);
1390 +                } else {
1391 +                        log_msg(LOG_ERR, "Starting User-Mode i-host");
1392 +                        return run_ihost();
1393 +                }
1394 +        }
1395 + #else
1396 +        return run_ihost();
1397 + #endif
1398   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines