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