Last bit of code clean up, and bug fixes. Release?
[umurmur.git] / shm_utils / mon-umurmurd / mon-umurmurd.c
1 #include <fcntl.h> /* For O_* constants */\r
2 #include <stdio.h>\r
3 #include <ctype.h>\r
4 #include <stdlib.h>\r
5 #include <string.h>\r
6 #include <unistd.h>\r
7 #include <sys/stat.h>\r
8 #include <sys/mman.h>\r
9 #include <sys/types.h>\r
10 #include "../../src/sharedmemory.h"\r
11 #include "../../src/sharedmemory_global.h"\r
12 \r
13 enum{ NOP_SHM, WAIT_ATTACH_SHM, TRY_ATTACH_SHM, MAT_SHM, CLEAN_UP_SHM, RUN_SHM };\r
14 \r
15 int wait = 0, opt;\r
16 uint8_t last, shm_statem = TRY_ATTACH_SHM;\r
17 \r
18 void run_shm(void);\r
19 \r
20 int main(int argc, char **argv) \r
21 {\r
22   struct stat buf;\r
23   int bindport = 0;\r
24   \r
25     while ( (opt = getopt(argc, argv, "wb:")) != -1 ) \r
26     {\r
27         switch(opt) \r
28         {\r
29            case 'w':\r
30               wait = 1;\r
31               break;\r
32            case 'b':\r
33               bindport = atoi(optarg);\r
34               break;              \r
35            default:                                                      \r
36               fprintf(stderr, "Usage: %s [-w] [-b <port>]\n", argv[0]);\r
37               fprintf(stderr, "\t-w         - Wait for umurmurd to create shm area. useful if you need to start from init.d script\n" );\r
38               fprintf(stderr, "\t-b <port>  - Change this to the port used when starting umurmurd. Defaults to \"/umurmurd:64738\" \n");\r
39               exit(EXIT_FAILURE);\r
40         }\r
41     }\r
42 \r
43       shmptr = NULL;\r
44       \r
45       if( !bindport )\r
46       {\r
47         bindport = 64738;\r
48       }\r
49       \r
50       sprintf( shm_file_name, "/umurmurd:%i", bindport );\r
51             \r
52       if( wait )\r
53           shm_statem = WAIT_ATTACH_SHM;\r
54           \r
55         while( shm_statem )\r
56         {\r
57           switch( shm_statem )\r
58           {\r
59               case RUN_SHM:\r
60                     run_shm();\r
61                     break;          \r
62               case WAIT_ATTACH_SHM:\r
63                     printf( "Waiting for umurmurd to be run\n\r"); fflush(stdout);\r
64                     while( ( shm_fd = shm_open( shm_file_name, O_RDONLY, 0666 ) ) == -1 )\r
65                        sleep( 1 );\r
66                     shm_statem = MAT_SHM;\r
67                     break;\r
68               case TRY_ATTACH_SHM:\r
69                     if( ( shm_fd = shm_open( shm_file_name, O_RDONLY, 0666 ) ) == -1 )\r
70                     {\r
71                         printf( "umurmurd doesn't seem to be running\n\r" );                        \r
72                         exit(EXIT_FAILURE);\r
73                     }\r
74                     shm_statem = MAT_SHM;\r
75                     break;\r
76              case MAT_SHM:                  \r
77                     fstat( shm_fd, &buf);                                       \r
78                     if( ( shmptr = mmap(0, buf.st_size, PROT_READ, MAP_SHARED, shm_fd, 0) ) == (void *) (-1) )   //MJP BUG? \r
79                     {\r
80                         exit(EXIT_FAILURE);\r
81                     }                    \r
82                     printf( "umumurd PID: %u\n\r", shmptr->umurmurd_pid );\r
83                     shm_statem = RUN_SHM;                    \r
84                     break;\r
85              case CLEAN_UP_SHM:                   \r
86                               \r
87                     break;\r
88                     \r
89          }\r
90        }\r
91         fflush(stdout);\r
92         return 0;\r
93 }\r
94 \r
95 uint8_t check_serverTick(void)\r
96 {\r
97   last = shmptr->alive;\r
98   sleep( 1 );  // Sleep for 1 sec\r
99   return(shmptr->alive - last); \r
100 }\r
101 \r
102 void run_shm(void)\r
103 {\r
104 \r
105 int cc;\r
106 \r
107     printf( "\033[2J\033[H" ); fflush(stdout); //clear screen VT100\r
108     printf( "%s  Clients(CONECTED/MAX)  %i/%i\n\n", shm_file_name, shmptr->clientcount, shmptr->server_max_clients );      \r
109           \r
110         for( cc = 0 ; cc < shmptr->server_max_clients ; cc++ )\r
111         {\r
112           \r
113           if( !shmptr->client[cc].authenticated )\r
114             continue; \r
115             \r
116           printf( "%s@%s:%i in channel: %s\n\\r
117                     \tclient_OS: %s %s\n\\r
118                     \tclient_info: %s\n\\r
119                     \tavailableBandwidth: %i\n\\r
120                     \tOnline(secs): %lu Idle(secs): %lu\n\\r
121                     \tusingUDP=%i\n\\r
122                     \tdeaf=%i, mute=%i\n\\r
123                     \tself_deaf=%i, self_mute=%i\n\\r
124                     \trecording=%i\n\\r
125                     \tbOpus=%i\n\\r
126                     \tisAdmin=%i\n\\r
127                     \tisSuppressed=%i\n\\r
128                     \tUDP_Avg/Var: %3.2f/%3.2f\n\\r
129                     \tTCP_Avg/Var: %3.2f/%3.2f\n\\r
130                     \tUDP_C/TCP_C: %lu/%lu\n", \r
131                                               shmptr->client[cc].username,\r
132                                               shmptr->client[cc].ipaddress,\r
133                                               shmptr->client[cc].udp_port,\r
134                                               shmptr->client[cc].channel,\r
135                                               shmptr->client[cc].os,\r
136                                               shmptr->client[cc].os_version,\r
137                                               shmptr->client[cc].release,\r
138                                               shmptr->client[cc].availableBandwidth,\r
139                                               shmptr->client[cc].online_secs,\r
140                                               shmptr->client[cc].idle_secs,\r
141                                                              \r
142                                               shmptr->client[cc].bUDP,\r
143                                               shmptr->client[cc].deaf,\r
144                                               shmptr->client[cc].mute,\r
145                                               shmptr->client[cc].self_deaf,\r
146                                               shmptr->client[cc].self_mute,\r
147                                               shmptr->client[cc].recording,\r
148                                               shmptr->client[cc].bOpus,\r
149                                               \r
150                                               shmptr->client[cc].isAdmin,\r
151                                               shmptr->client[cc].isSuppressed,\r
152                                                                               \r
153                                               shmptr->client[cc].UDPPingAvg,\r
154                                               shmptr->client[cc].UDPPingVar,\r
155                                               shmptr->client[cc].TCPPingAvg,\r
156                                               shmptr->client[cc].TCPPingVar,\r
157                                               shmptr->client[cc].UDPPackets,\r
158                                               shmptr->client[cc].TCPPackets ); fflush(stdout);  // fflush need because of sleep() call\r
159         }\r
160         if( !check_serverTick() )\r
161         {\r
162             exit(EXIT_FAILURE); //You dont have to exit you could just report the fact that the data is not valid \r
163         }\r
164 }