Added SWAT i18n feature:
[sfrench/samba-autobuild/.git] / source3 / web / statuspage.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 2.2.
4    web status page
5    Copyright (C) Andrew Tridgell 1997-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "webintl.h"
24
25 static pid_t smbd_pid;
26
27 static char *tstring(time_t t)
28 {
29         static pstring buf;
30         pstrcpy(buf, asctime(LocalTime(&t)));
31         all_string_sub(buf," "," ",sizeof(buf));
32         return buf;
33 }
34
35 static void print_share_mode(share_mode_entry *e, char *fname)
36 {
37         printf("<tr><td>%d</td>",(int)e->pid);
38         printf("<td>");
39         switch ((e->share_mode>>4)&0xF) {
40         case DENY_NONE: printf(_("DENY_NONE")); break;
41         case DENY_ALL:  printf(_("DENY_ALL   ")); break;
42         case DENY_DOS:  printf(_("DENY_DOS   ")); break;
43         case DENY_READ: printf(_("DENY_READ  ")); break;
44         case DENY_WRITE:printf(_("DENY_WRITE ")); break;
45         }
46         printf("</td>");
47
48         printf("<td>");
49         switch (e->share_mode&0xF) {
50         case 0: printf(_("RDONLY     ")); break;
51         case 1: printf(_("WRONLY     ")); break;
52         case 2: printf(_("RDWR       ")); break;
53         }
54         printf("</td>");
55
56         printf("<td>");
57         if((e->op_type & 
58             (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) == 
59            (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
60                 printf(_("EXCLUSIVE+BATCH "));
61         else if (e->op_type & EXCLUSIVE_OPLOCK)
62                 printf(_("EXCLUSIVE       "));
63         else if (e->op_type & BATCH_OPLOCK)
64                 printf(_("BATCH           "));
65         else if (e->op_type & LEVEL_II_OPLOCK)
66                 printf(_("LEVEL_II        "));
67         else
68                 printf(_("NONE            "));
69         printf("</td>");
70
71         printf("<td>%s</td><td>%s</td></tr>\n",
72                fname,tstring(e->time.tv_sec));
73 }
74
75
76 /* kill off any connections chosen by the user */
77 static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* state)
78 {
79         struct connections_data crec;
80
81         if (dbuf.dsize != sizeof(crec))
82                 return 0;
83
84         memcpy(&crec, dbuf.dptr, sizeof(crec));
85
86         if (crec.cnum == -1 && process_exists(crec.pid)) {
87                 char buf[30];
88                 slprintf(buf,sizeof(buf)-1,"kill_%d", (int)crec.pid);
89                 if (cgi_variable(buf)) {
90                         kill_pid(crec.pid);
91                 }
92         }
93         return 0;
94 }
95
96 /* traversal fn for showing machine connections */
97 static int traverse_fn2(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* state)
98 {
99         struct connections_data crec;
100
101         if (dbuf.dsize != sizeof(crec))
102                 return 0;
103
104         memcpy(&crec, dbuf.dptr, sizeof(crec));
105         
106         if (crec.cnum != -1 || !process_exists(crec.pid) || (crec.pid == smbd_pid))
107                 return 0;
108
109         printf("<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td>\n",
110                (int)crec.pid,
111                crec.machine, crec.addr,
112                tstring(crec.start));
113         if (geteuid() == 0) {
114                 printf("<td><input type=submit value=\"X\" name=\"kill_%d\"></td>\n",
115                        (int)crec.pid);
116         }
117         printf("</tr>\n");
118
119         return 0;
120 }
121
122 /* traversal fn for showing share connections */
123 static int traverse_fn3(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* state)
124 {
125         struct connections_data crec;
126
127         if (dbuf.dsize != sizeof(crec))
128                 return 0;
129
130         memcpy(&crec, dbuf.dptr, sizeof(crec));
131
132         if (crec.cnum == -1 || !process_exists(crec.pid))
133                 return 0;
134
135         printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%s</td></tr>\n",
136                crec.name,uidtoname(crec.uid),
137                gidtoname(crec.gid),(int)crec.pid,
138                crec.machine,
139                tstring(crec.start));
140         return 0;
141 }
142
143
144 /* show the current server status */
145 void status_page(void)
146 {
147         char *v;
148         int autorefresh=0;
149         int refresh_interval=30;
150         TDB_CONTEXT *tdb;
151
152         smbd_pid = pidfile_pid("smbd");
153
154         if (cgi_variable("smbd_restart")) {
155                 stop_smbd();
156                 start_smbd();
157         }
158
159         if (cgi_variable("smbd_start")) {
160                 start_smbd();
161         }
162
163         if (cgi_variable("smbd_stop")) {
164                 stop_smbd();
165         }
166
167         if (cgi_variable("nmbd_restart")) {
168                 stop_nmbd();
169                 start_nmbd();
170         }
171         if (cgi_variable("nmbd_start")) {
172                 start_nmbd();
173         }
174
175         if (cgi_variable("nmbd_stop")) {
176                 stop_nmbd();
177         }
178
179         if (cgi_variable("autorefresh")) {
180                 autorefresh = 1;
181         } else if (cgi_variable("norefresh")) {
182                 autorefresh = 0;
183         } else if (cgi_variable("refresh")) {
184                 autorefresh = 1;
185         }
186
187         if ((v=cgi_variable("refresh_interval"))) {
188                 refresh_interval = atoi(v);
189         }
190
191         tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
192         if (tdb) tdb_traverse(tdb, traverse_fn1, NULL);
193
194         printf("<H2>%s</H2>\n", _("Server Status"));
195
196         printf("<FORM method=post>\n");
197
198         if (!autorefresh) {
199                 printf("<input type=submit value=\"%s\" name=autorefresh>\n", _("Auto Refresh"));
200                 printf("<br>%s", _("Refresh Interval: "));
201                 printf("<input type=text size=2 name=\"refresh_interval\" value=%d>\n", 
202                        refresh_interval);
203         } else {
204                 printf("<input type=submit value=\"%s\" name=norefresh>\n", _("Stop Refreshing"));
205                 printf("<br>%s%d\n", _("Refresh Interval: "), refresh_interval);
206                 printf("<input type=hidden name=refresh value=1>\n");
207         }
208
209         printf("<p>\n");
210
211         if (!tdb) {
212                 /* open failure either means no connections have been
213                    made */
214         }
215
216
217         printf("<table>\n");
218
219         printf("<tr><td>%s</td><td>%s</td></tr>", _("version:"), VERSION);
220
221         fflush(stdout);
222         printf("<tr><td>%s</td><td>%s</td>\n", _("smbd:"), smbd_running()?_("running"):_("not running"));
223         if (geteuid() == 0) {
224             if (smbd_running()) {
225                 printf("<td><input type=submit name=\"smbd_stop\" value=\"%s\"></td>\n", _("Stop smbd"));
226             } else {
227                 printf("<td><input type=submit name=\"smbd_start\" value=\"%s\"></td>\n", _("Start smbd"));
228             }
229             printf("<td><input type=submit name=\"smbd_restart\" value=\"%s\"></td>\n", _("Restart smbd"));
230         }
231         printf("</tr>\n");
232
233         fflush(stdout);
234         printf("<tr><td>%s</td><td>%s</td>\n", _("nmbd:"), nmbd_running()?_("running"):_("not running"));
235         if (geteuid() == 0) {
236             if (nmbd_running()) {
237                 printf("<td><input type=submit name=\"nmbd_stop\" value=\"%s\"></td>\n", _("Stop nmbd"));
238             } else {
239                 printf("<td><input type=submit name=\"nmbd_start\" value=\"%s\"></td>\n", _("Start nmbd"));
240             }
241             printf("<td><input type=submit name=\"nmbd_restart\" value=\"%s\"></td>\n", _("Restart nmbd"));
242         }
243         printf("</tr>\n");
244
245         printf("</table>\n");
246         fflush(stdout);
247
248         printf("<p><h3>%s</h3>\n", _("Active Connections"));
249         printf("<table border=1>\n");
250         printf("<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th>\n", _("PID"), _("Client"), _("IP address"), _("Date"));
251         if (geteuid() == 0) {
252                 printf("<th>%s</th>\n", _("Kill"));
253         }
254         printf("</tr>\n");
255
256         if (tdb) tdb_traverse(tdb, traverse_fn2, NULL);
257
258         printf("</table><p>\n");
259
260         printf("<p><h3>%s</h3>\n", _("Active Shares"));
261         printf("<table border=1>\n");
262         printf("<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n\n",
263                 _("Share"), _("User"), _("Group"), _("PID"), _("Client"), _("Date"));
264
265         if (tdb) tdb_traverse(tdb, traverse_fn3, NULL);
266
267         printf("</table><p>\n");
268
269         printf("<h3>%s</h3>\n", _("Open Files"));
270         printf("<table border=1>\n");
271         printf("<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n", _("PID"), _("Sharing"), _("R/W"), _("Oplock"), _("File"), _("Date"));
272
273         locking_init(1);
274         share_mode_forall(print_share_mode);
275         locking_end();
276         printf("</table>\n");
277
278         if (tdb) tdb_close(tdb);
279
280         printf("</FORM>\n");
281
282         if (autorefresh) {
283                 /* this little JavaScript allows for automatic refresh
284                    of the page. There are other methods but this seems
285                    to be the best alternative */
286                 printf("<script language=\"JavaScript\">\n");
287                 printf("<!--\nsetTimeout('window.location.replace(\"%s/status?refresh_interval=%d&refresh=1\")', %d)\n", 
288                        cgi_baseurl(),
289                        refresh_interval,
290                        refresh_interval*1000);
291                 printf("//-->\n</script>\n");
292         }
293 }