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.54 by tdb, Tue May 2 06:49:53 2006 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 667 | Line 776 | int get_system_stats(int seq_no, ihost_state_t *ihost_
776          }else{
777                  strlcat(xml, "<disk>", size);
778                  for(counter=0;counter<disk_entries;counter++){
779 +                        if(strcmp(disk_stats->fs_type, "nfs") == 0) continue;
780                          snprintf(tmp, size, \
781 <                                "<p%d name=\"%s\" mount=\"%s\" fstype=\"%s\" total=\"%lld\" used=\"%lld\" avail=\"%lld\" totalinodes=\"%lld\" usedinodes=\"%lld\" freeinodes=\"%lld\"></p%d>", \
781 >                                "<p%d name=\"%s\" mount=\"%s\" fstype=\"%s\" total=\""LLD"\" used=\""LLD"\" avail=\""LLD"\" totalinodes=\""LLD"\" usedinodes=\""LLD"\" freeinodes=\""LLD"\"></p%d>", \
782                                  counter, \
783                                  disk_stats->device_name, \
784                                  disk_stats->mnt_point, \
# Line 703 | Line 813 | too_big_error:
813  
814  
815  
816 + /* WIN32 NT service stuff */
817 + #ifdef WIN32
818 + void service_stopped() {
819 +        if(run_as_service) {
820 +                service_status.dwCurrentState = SERVICE_STOPPED;
821 +                service_status.dwWin32ExitCode = errno;
822 +                service_status.dwServiceSpecificExitCode = 0;
823 +
824 +                SetServiceStatus(hstatus, &service_status);
825 +        }
826 + }
827 +
828 + void control_handler(DWORD request) {
829 +        switch(request) {
830 +                case SERVICE_CONTROL_STOP:
831 +                case SERVICE_CONTROL_SHUTDOWN:
832 +                        service_status.dwWin32ExitCode = 0;
833 +                        service_status.dwCurrentState = SERVICE_STOP_PENDING;
834 +                        break;
835 +                default:
836 +                        break;
837 +        }
838 +
839 +        SetServiceStatus (hstatus, &service_status);
840 + }
841 +
842 + /* attempt to tell service manager to start our service.
843 + * return 0 on error, 1 on ok
844 + */
845 + int start_service() {
846 +        SC_HANDLE scm;
847 +        SC_HANDLE service;
848 +
849 +        // Open SCM
850 +        if((scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT)) == NULL) {
851 +                log_msg(LOG_CRIT, "Failed to open Service Control Manager");
852 +                return 0;
853 +        }
854 +        // Locate the service
855 +        if((service = OpenService(scm, SERVICENAME, SERVICE_START)) == NULL) {
856 +                log_msg(LOG_CRIT, "Unable to open the service");
857 +                return 0;
858 +        }
859 +        // Start the service
860 +        if(StartService(service, 0, NULL) == 0) {
861 +                log_msg(LOG_CRIT, "Unable to start the service");
862 +                return 0;
863 +        }
864 +        return 1;
865 + }
866 +
867 + int stop_service() {
868 +        SC_HANDLE scm;
869 +        SC_HANDLE service;
870 +        SERVICE_STATUS status;
871 +
872 +        // Open SCM
873 +        if((scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT)) == NULL) {
874 +                log_msg(LOG_CRIT, "Failed to open Service Control Manager");
875 +                return 0;
876 +        }
877 +        // Locate service
878 +        if((service = OpenService(scm, SERVICENAME, SERVICE_STOP)) == NULL) {
879 +                log_msg(LOG_CRIT, "Unable to open the service");
880 +                return 0;
881 +        }
882 +        // Stop the service
883 +        if(!ControlService(service, SERVICE_CONTROL_STOP, &status)) {
884 +                log_msg(LOG_CRIT, "Unable to stop the service");
885 +                return 0;
886 +        }
887 +        return 1;
888 + }
889 +
890 + int register_service(int argc, char **argv) {
891 +        char path[MAX_PATH];
892 +        int cmdline_len;
893 +        int i;
894 +        char *cmdline;
895 +        char *tmp;
896 +        SC_HANDLE scm;
897 +
898 +        if(!GetModuleFileName(NULL, path, MAX_PATH)) {
899 +                log_msg(LOG_CRIT, "GetModuleFileName failed");
900 +                return 0;
901 +        }
902 +
903 +        // Calculate command line length
904 +        // 14 = 10 for " -w service", 2x quote around path and ending \0
905 +        cmdline_len = strlen(path) + 14;
906 +        for (i=0; i<argc; i++) {
907 +                // +1 for space prefix
908 +                cmdline_len += strlen(argv[i]) +1;
909 +        }
910 +
911 +        cmdline = malloc(cmdline_len);
912 +        if(cmdline == NULL) {
913 +                log_msg(LOG_CRIT, "out of memory");
914 +                return 0;
915 +        }
916 +        tmp = malloc(cmdline_len);
917 +        if(tmp == NULL) {
918 +                log_msg(LOG_CRIT, "out of memory");
919 +                free(cmdline);
920 +                return 0;
921 +        }
922 +
923 +        // Compile up the final command line call
924 +        snprintf(cmdline, cmdline_len, "\"%s\" -w service", path);
925 +        for (i=0; i<argc; i++) {
926 +                snprintf(tmp, cmdline_len, " %s", argv[i]);
927 +                strcat(cmdline, tmp);
928 +        }
929 +        free(tmp);
930 +
931 +        // Open SCM
932 +        if((scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE)) == NULL) {
933 +                log_msg(LOG_CRIT, "Unable to open Service Control Manager");
934 +                return 0;
935 +        }
936 +
937 +        // Add the service
938 +        if (CreateService(scm, SERVICENAME, SERVICENAME,
939 +                        SC_MANAGER_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
940 +                        SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, cmdline, NULL,
941 +                        NULL, NULL, NULL, NULL) == NULL) {
942 +                log_msg(LOG_CRIT, "Unable to create service");
943 +                return 0;
944 +        }
945 +
946 +        return 1;
947 + }
948 +
949 + int unregister_service() {
950 +        SC_HANDLE scm;
951 +        SC_HANDLE service;
952 +
953 +        // Open the SCM
954 +        if((scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE)) ==NULL) {
955 +                log_msg(LOG_CRIT, "Unable to open Service Control Manager");
956 +                return 0;
957 +        }
958 +        // Get the service
959 +        if((service = OpenService(scm, SERVICENAME, SC_MANAGER_ALL_ACCESS)) == NULL) {
960 +                log_msg(LOG_CRIT, "Unable to locate the service");
961 +                return 0;
962 +        }
963 +        // Delete service
964 +        if(DeleteService(service) == 0) {
965 +                log_msg(LOG_CRIT, "Unable to remove the service");
966 +                return 0;
967 +        }
968 +        return 1;
969 + }
970 + #endif
971 +
972 +
973 +
974   void usage(char *progname){
975 <        fprintf(stderr, "Usage %s [-v[v]] [-f] [-n name] [-i ip] [-s server] [-p port] [-V] [-h]\n\n", progname);
975 >        const char *usage;
976 > #ifdef WIN32
977 >        usage = "Usage %s [-w option] [-v[v]] [-n name] [-i ip] [-s server] [-p port] [-V] [-h]\n\n";
978 > #else
979 >        usage = "Usage %s [-v[v]] [-f] [-n name] [-i ip] [-s server] [-p port] [-V] [-h]\n\n";
980 > #endif
981 >        fprintf(stderr, usage, progname);
982          fprintf(stderr, "  -v    Verbose mode, -vv would make even more verbose\n");
983 + #ifndef WIN32
984          fprintf(stderr, "  -f    Foreground mode, print errors to stderr\n");
985 + #else
986 +        fprintf(stderr, "  -w    Windows Service options:\n");
987 +        fprintf(stderr, "     start      - start the service\n");
988 +        fprintf(stderr, "     stop       - stop the service\n");
989 +        fprintf(stderr, "     register   - register the service\n");
990 +        fprintf(stderr, "     unregister - unregister the service\n");
991 +        /* service - run as a service, only called by windows service */
992 + #endif
993          fprintf(stderr, "  -n    Set the machine name to be reported as\n");
994          fprintf(stderr, "  -i    Set the IP to be reported as\n");
995          fprintf(stderr, "  -s    Specifies the i-scream server to connect to\n");
# Line 719 | Line 1002 | void usage(char *progname){
1002          exit(1);
1003   }
1004  
1005 < int main(int argc, char **argv){
1005 > int run_ihost(){
1006  
724        ihost_state_t ihost_state;
1007          udp_sockinfo_t udp_sockinfo;
1008  
727        int cmdopt;
728        extern int optind;
1009          pid_t pid;
1010          FILE *f;
1011          int packet_num=0;
# Line 734 | Line 1014 | int main(int argc, char **argv){
1014          char packet[MAX_UDP_PACKET_SIZE];
1015  
1016          time_t cur_time, sleep_delay, udp_time=0, config_time=0;
1017 + #ifdef WIN32
1018 +        int tries=0;
1019 +        WSADATA wsaData;
1020  
1021 <        /* Set default settings */
1022 <        ihost_config.verbose=1;
1023 <        ihost_config.daemon=1;
1024 <        /* 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 <                }
1021 >        if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) {
1022 >                log_msg(LOG_CRIT, "Failed to init a winsock");
1023 >                service_stopped();
1024 >                exit(1);
1025          }
1026 + #endif
1027  
1028          if(gethostbyname(ihost_state.filtermanager_host)==NULL){
1029 +                printf("%s\n", ihost_state.filtermanager_host);
1030                  log_msg(LOG_CRIT, "Failed to lookup hostname. Please check settings");
1031 <                exit(1);
1031 >                goto out;
1032          }
1033          if(ihost_state.filtermanager_port==0){
1034                  log_msg(LOG_ERR, "Invalid port number");
1035 <                exit(1);
1035 >                goto out;
1036          }
1037  
1038 + #ifndef WIN32
1039          if(ihost_config.daemon){
1040                  pid=fork();
1041                  if(pid==-1){
# Line 834 | Line 1062 | int main(int argc, char **argv){
1062                  fclose(stderr);
1063  
1064          }
1065 + #endif
1066  
1067          log_msg(LOG_INFO, "Starting ihost...");
1068  
# Line 841 | Line 1070 | int main(int argc, char **argv){
1070          if(sg_init()){
1071                  log_msg(LOG_CRIT, "sg_init failed: %s (%s)",
1072                          sg_str_error(sg_get_error()), sg_get_error_arg());
1073 <                exit(1);
1073 >                goto out;
1074          }
1075 +        if(sg_snapshot()) {
1076 +                log_msg(LOG_ERR, "sg_snapshot failed: %s (%s)",
1077 +                        sg_str_error(sg_get_error()), sg_get_error_arg());
1078 +        }
1079  
1080 + #ifndef WIN32
1081          log_msg(LOG_DEBUG,"Writing PID FILE");
1082  
1083          pid=getpid();
# Line 858 | Line 1092 | int main(int argc, char **argv){
1092                          log_msg(LOG_CRIT, "failed to close PID file");
1093                  }
1094          }
1095 + #endif
1096  
1097          /* Get the initial config from the filter manager. Should this fail,
1098           * wait, and then try again. */
1099 +        /* Win32 - for a max of one minute */
1100  
1101          sg_get_disk_io_stats_diff(&packet_num);
1102          packet_num=0;
1103  
1104 <        while(ihost_getconfig(&ihost_state)!=0){
1104 >        while(ihost_getconfig(&ihost_state)!=0
1105 > #ifdef WIN32
1106 >                        && (tries<6)
1107 > #endif
1108 >                        ){
1109                  log_msg(LOG_ERR, "Failed to get ihost config");
1110 <                sleep(10);
1110 >                sleep(SLEEP);
1111 > #ifdef WIN32
1112 >                tries++;
1113 > #endif
1114          }
1115  
1116 <        while((create_udp_sockinfo(&udp_sockinfo, ihost_state.server_fqdn, ihost_state.server_udp_port))!=0){
1116 > #ifdef WIN32
1117 >        if (tries == 6) {
1118 >                log_msg(LOG_ERR, "Giving up");
1119 >                goto out;
1120 >        }
1121 >        tries = 0;
1122 > #endif
1123 >
1124 >        while((create_udp_sockinfo(&udp_sockinfo, ihost_state.server_fqdn, ihost_state.server_udp_port))!=0
1125 > #ifdef WIN32
1126 >                        && (tries<6)
1127 > #endif
1128 >                        ){
1129                  log_msg(LOG_ERR, "Failed to create udp socket");
1130 <                sleep(10);
1130 >                sleep(SLEEP);
1131 > #ifdef WIN32
1132 >                tries++;
1133 > #endif
1134          }
1135  
1136 + #ifdef WIN32
1137 +        if (tries == 6) {
1138 +                log_msg(LOG_ERR, "Giving up");
1139 +                goto out;
1140 +        }
1141 + #endif
1142 +
1143          config_time=time(NULL)+ihost_state.config_ttl;
1144  
1145 + #ifdef WIN32
1146 +        /* Finally, we have started successfully!
1147 +         * We set state to running even for non-service calls so the while
1148 +         * loop works. Bit of a hack ;)
1149 +         */
1150 +        service_status.dwCurrentState = SERVICE_RUNNING;
1151 +        if(run_as_service) {
1152 +                SetServiceStatus(hstatus, &service_status);
1153 +        }
1154 +        printf("started\n");
1155 + #endif
1156 +
1157          /* Now have config.. collect data and send as often as required */
1158 <        for(;;){
1158 > #ifdef WIN32
1159 >        while(service_status.dwCurrentState == SERVICE_RUNNING)
1160 > #else
1161 >        for(;;)
1162 > #endif
1163 >        {
1164                  cur_time=time(NULL);
1165  
1166                  if(cur_time>=udp_time){
1167 +                        if(sg_snapshot()) {
1168 +                                log_msg(LOG_ERR, "sg_snapshot failed: %s (%s)",
1169 +                                        sg_str_error(sg_get_error()), sg_get_error_arg());
1170 +                                continue; /* Could this get ugly? */
1171 +                        }
1172                          if((get_system_stats(packet_num++, &ihost_state, packet, MAX_UDP_PACKET_SIZE))!=0){
1173                                  log_msg(LOG_ERR, "Failed to get system stats");
1174                          }
# Line 906 | Line 1193 | int main(int argc, char **argv){
1193  
1194                                  while((create_udp_sockinfo(&udp_sockinfo, ihost_state.server_fqdn, ihost_state.server_udp_port))!=0){
1195                                          log_msg(LOG_CRIT, "Failed to create udp socket");
1196 <                                        sleep(10);
1196 >                                        sleep(SLEEP);
1197                                  }
1198  
1199                                  config_time=time(NULL)+ihost_state.config_ttl;
# Line 917 | Line 1204 | int main(int argc, char **argv){
1204  
1205                  sleep_delay=udp_time-time(NULL);
1206                  log_msg(LOG_DEBUG, "Sleeping for %d", sleep_delay);
1207 + #ifdef WIN32
1208 +                /* convert to millisecs */
1209 +                sleep_delay *= 1000;
1210 + #endif
1211                  if(sleep_delay>0) sleep(sleep_delay);
1212          }
1213  
1214 +        if(sg_shutdown()) {
1215 +                log_msg(LOG_ERR, "sg_shutdown failed: %s (%s)",
1216 +                        sg_str_error(sg_get_error()), sg_get_error_arg());
1217 +        }
1218 +
1219 + #ifdef WIN32
1220 +        WSACleanup();
1221 +        if(run_as_service) {
1222 +                service_status.dwWin32ExitCode = 0;
1223 +                service_status.dwCurrentState = SERVICE_STOPPED;
1224 +                SetServiceStatus(hstatus, &service_status);
1225 +        }
1226 + #endif
1227 +        log_msg(LOG_ERR, "ihost shutdown successfully");
1228 +        fclose(ihost_config.log);
1229 +
1230          return(0);
1231 +
1232 + out:
1233 + #ifdef WIN32
1234 +        WSACleanup();
1235 +        service_stopped();
1236 + #endif
1237 +        exit(1);
1238 + }
1239 +
1240 + #ifdef WIN32
1241 + int service_main(int argc, char **argv) {
1242 +        int error;
1243 +
1244 +        service_status.dwServiceType = SERVICE_WIN32;
1245 +        service_status.dwCurrentState = SERVICE_START_PENDING;
1246 +        service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
1247 +                SERVICE_ACCEPT_SHUTDOWN;
1248 +        service_status.dwWin32ExitCode = 0;
1249 +        service_status.dwServiceSpecificExitCode = 0;
1250 +        service_status.dwCheckPoint = 0;
1251 +        service_status.dwWaitHint = 0;
1252 +
1253 +        hstatus = RegisterServiceCtrlHandler(SERVICENAME,
1254 +                        (LPHANDLER_FUNCTION)control_handler);
1255 +        if(hstatus == (SERVICE_STATUS_HANDLE)0) {
1256 +                log_msg(LOG_CRIT, "RegisterServiceCtrlHandle failed");
1257 +                return -1;
1258 +        }
1259 +
1260 +        return run_ihost();
1261 + }
1262 +
1263 +
1264 + void parse_w(int argc, char **argv) {
1265 +        if (strcasecmp(optarg, "start") == 0) {
1266 +                log_msg(LOG_ERR, "Attempting to start service...");
1267 +                run_server = 0;
1268 +                if(start_service())
1269 +                        log_msg(LOG_ERR, "Service started");
1270 +        } else if (strcasecmp(optarg, "stop") == 0) {
1271 +                log_msg(LOG_ERR, "Attempting to stop service...");
1272 +                run_server = 0;
1273 +                if(stop_service())
1274 +                        log_msg(LOG_ERR, "Service stopped");
1275 +        } else if (strcasecmp(optarg, "service") == 0) {
1276 +                run_as_service = 1;
1277 +        } else if (strcasecmp(optarg, "register") == 0) {
1278 +                log_msg(LOG_ERR, "Attempting to register service...");
1279 +                run_server = 0;
1280 +                int i = optind;
1281 +                optind = argc;
1282 +                /* Grab the remaining arguments and use each time the service
1283 +                 * is started */
1284 +                if (register_service(argc-i, &argv[i]))
1285 +                        log_msg(LOG_ERR, "Registered service successfully");
1286 +        } else if (strcasecmp(optarg, "unregister") == 0) {
1287 +                log_msg(LOG_ERR, "Attempting to unregister service...");
1288 +                run_server = 0;
1289 +                if(unregister_service())
1290 +                        log_msg(LOG_ERR, "Unregistered service successfully");
1291 +        } else {
1292 +                fprintf(stderr, "Unknown -w option\n");
1293 +                usage(argv[0]);
1294 +                exit(1);
1295 +        }
1296 + }
1297 + #endif
1298 +
1299 +
1300 + int main(int argc, char **argv){
1301 +        int cmdopt;
1302 +        extern int optind;
1303 +
1304 +        /* Set default settings */
1305 +        ihost_config.verbose=1;
1306 +        ihost_config.daemon=1;
1307 +        /* Set all errors to go down stderr until told otherwise */
1308 +        ihost_config.log=stderr;
1309 +
1310 +        /* Blank ihost_state to default settings */
1311 +        ihost_state.filtermanager_host=DEF_SERVER_NAME;
1312 +        ihost_state.filtermanager_port=DEF_SERVER_PORT;
1313 +        ihost_state.host_fqdn=NULL;
1314 +        ihost_state.host_ip=NULL;
1315 +        ihost_state.preset_fqdn = 0;
1316 +        ihost_state.preset_ip = 0;
1317 +        ihost_state.server_fqdn=NULL;
1318 +        ihost_state.file_list=NULL;
1319 +        ihost_state.last_modified=NULL;
1320 +
1321 +        while((cmdopt=getopt(argc, argv, OPTSTRING)) != -1){
1322 +                switch(cmdopt){
1323 +                        case 'v':
1324 +                                ihost_config.verbose++;
1325 +                                break;
1326 +
1327 + #ifndef WIN32
1328 +                        case 'f':
1329 +                                /* Force syslog logging since stderr will be closed in this case */
1330 +                                ihost_config.daemon=0;
1331 +                                break;
1332 + #endif
1333 +
1334 +                        case 'V':
1335 +                                fprintf(stderr, "%s version %s\n", argv[0], VERSION);
1336 +                                break;
1337 +                        case 'n':
1338 +                                ihost_state.preset_fqdn = 1;
1339 +                                ihost_state.host_fqdn = strdup(optarg);
1340 +                                if(ihost_state.host_fqdn == NULL){
1341 +                                        fprintf(stderr, "Missing hostname\n");
1342 +                                        usage(argv[0]);
1343 +                                }
1344 +                                break;
1345 +                        case 'i':
1346 +                                /* Hmm.. Someone could set any string to be the IP, and it will let it */
1347 +                                ihost_state.preset_ip = 1;
1348 +                                ihost_state.host_ip = strdup(optarg);
1349 +                                if(ihost_state.host_ip == NULL){
1350 +                                        fprintf(stderr, "Missing ip\n");
1351 +                                        usage(argv[0]);
1352 +                                }
1353 +                                break;
1354 +
1355 +                        case 's':
1356 +                                ihost_state.filtermanager_host=strdup(optarg);
1357 +                                break;
1358 +
1359 +                        case 'p':
1360 +                                ihost_state.filtermanager_port=atoi(optarg);
1361 +                                break;
1362 +
1363 + #ifdef WIN32
1364 +                        case 'w':
1365 +                                parse_w(argc, argv);
1366 +                                break;
1367 + #endif
1368 +
1369 +                        case 'h':
1370 +                        default:
1371 +                                usage(argv[0]);
1372 +                                exit(1);
1373 +                }
1374 +        }
1375 +
1376 + #ifdef WIN32
1377 +        if (run_server) {
1378 +                if(run_as_service) {
1379 +                        if((ihost_config.log=fopen(LOG_FILE, "a"))==NULL){
1380 +                                ihost_config.log=stderr;
1381 +                                log_msg(LOG_CRIT, "Failed to open Logfiles %s for writing", LOG_FILE);
1382 +                                exit(1);
1383 +                        }
1384 +                        log_msg(LOG_ERR, "Starting Service-Mode i-host");
1385 +                        SERVICE_TABLE_ENTRY service_table[2];
1386 +                        service_table[0].lpServiceName = SERVICENAME;
1387 +                        service_table[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)service_main;
1388 +                        service_table[1].lpServiceName = NULL;
1389 +                        service_table[1].lpServiceProc = NULL;
1390 +                        return StartServiceCtrlDispatcher(service_table);
1391 +                } else {
1392 +                        log_msg(LOG_ERR, "Starting User-Mode i-host");
1393 +                        return run_ihost();
1394 +                }
1395 +        }
1396 + #else
1397 +        return run_ihost();
1398 + #endif
1399   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines