Make grouping in if statement more explicit.
[ira/wip.git] / source3 / utils / net_status.c
1 /* 
2    Samba Unix/Linux SMB client library 
3    net status command -- possible replacement for smbstatus
4    Copyright (C) 2003 Volker Lendecke (vl@samba.org)
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18
19 #include "includes.h"
20 #include "utils/net.h"
21
22 static int show_session(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
23                         void *state)
24 {
25         bool *parseable = (bool *)state;
26         struct sessionid sessionid;
27
28         if (dbuf.dsize != sizeof(sessionid))
29                 return 0;
30
31         memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
32
33         if (!process_exists(sessionid.pid)) {
34                 return 0;
35         }
36
37         if (*parseable) {
38                 d_printf("%s\\%s\\%s\\%s\\%s\n",
39                          procid_str_static(&sessionid.pid), uidtoname(sessionid.uid),
40                          gidtoname(sessionid.gid), 
41                          sessionid.remote_machine, sessionid.hostname);
42         } else {
43                 d_printf("%7s   %-12s  %-12s  %-12s (%s)\n",
44                          procid_str_static(&sessionid.pid), uidtoname(sessionid.uid),
45                          gidtoname(sessionid.gid), 
46                          sessionid.remote_machine, sessionid.hostname);
47         }
48
49         return 0;
50 }
51
52 static int net_status_sessions(int argc, const char **argv)
53 {
54         TDB_CONTEXT *tdb;
55         bool parseable;
56
57         if (argc == 0) {
58                 parseable = False;
59         } else if ((argc == 1) && strequal(argv[0], "parseable")) {
60                 parseable = True;
61         } else {
62                 return net_help_status(argc, argv);
63         }
64
65         if (!parseable) {
66                 d_printf("PID     Username      Group         Machine"
67                          "                        \n");
68                 d_printf("-------------------------------------------"
69                          "------------------------\n");
70         }
71
72         tdb = tdb_open_log(lock_path("sessionid.tdb"), 0,
73                            TDB_DEFAULT, O_RDONLY, 0);
74
75         if (tdb == NULL) {
76                 d_fprintf(stderr, "%s not initialised\n", lock_path("sessionid.tdb"));
77                 return -1;
78         }
79
80         tdb_traverse(tdb, show_session, &parseable);
81         tdb_close(tdb);
82
83         return 0;
84 }
85
86 static int show_share(struct db_record *rec,
87                       const struct connections_key *key,
88                       const struct connections_data *crec,
89                       void *state)
90 {
91         if (crec->cnum == -1)
92                 return 0;
93
94         if (!process_exists(crec->pid)) {
95                 return 0;
96         }
97
98         d_printf("%-10.10s   %s   %-12s  %s",
99                crec->servicename, procid_str_static(&crec->pid),
100                crec->machine,
101                time_to_asc(crec->start));
102
103         return 0;
104 }
105
106 struct sessionids {
107         int num_entries;
108         struct sessionid *entries;
109 };
110
111 static int collect_pid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
112                        void *state)
113 {
114         struct sessionids *ids = (struct sessionids *)state;
115         struct sessionid sessionid;
116
117         if (dbuf.dsize != sizeof(sessionid))
118                 return 0;
119
120         memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
121
122         if (!process_exists(sessionid.pid)) 
123                 return 0;
124
125         ids->num_entries += 1;
126         ids->entries = SMB_REALLOC_ARRAY(ids->entries, struct sessionid, ids->num_entries);
127         if (!ids->entries) {
128                 ids->num_entries = 0;
129                 return 0;
130         }
131         ids->entries[ids->num_entries-1] = sessionid;
132
133         return 0;
134 }
135
136 static int show_share_parseable(struct db_record *rec,
137                                 const struct connections_key *key,
138                                 const struct connections_data *crec,
139                                 void *state)
140 {
141         struct sessionids *ids = (struct sessionids *)state;
142         int i;
143         bool guest = True;
144
145         if (crec->cnum == -1)
146                 return 0;
147
148         if (!process_exists(crec->pid)) {
149                 return 0;
150         }
151
152         for (i=0; i<ids->num_entries; i++) {
153                 struct server_id id = ids->entries[i].pid;
154                 if (procid_equal(&id, &crec->pid)) {
155                         guest = False;
156                         break;
157                 }
158         }
159
160         d_printf("%s\\%s\\%s\\%s\\%s\\%s\\%s",
161                  crec->servicename,procid_str_static(&crec->pid),
162                  guest ? "" : uidtoname(ids->entries[i].uid),
163                  guest ? "" : gidtoname(ids->entries[i].gid),
164                  crec->machine, 
165                  guest ? "" : ids->entries[i].hostname,
166                  time_to_asc(crec->start));
167
168         return 0;
169 }
170
171 static int net_status_shares_parseable(int argc, const char **argv)
172 {
173         struct sessionids ids;
174         TDB_CONTEXT *tdb;
175
176         ids.num_entries = 0;
177         ids.entries = NULL;
178
179         tdb = tdb_open_log(lock_path("sessionid.tdb"), 0,
180                            TDB_DEFAULT, O_RDONLY, 0);
181
182         if (tdb == NULL) {
183                 d_fprintf(stderr, "%s not initialised\n", lock_path("sessionid.tdb"));
184                 return -1;
185         }
186
187         tdb_traverse(tdb, collect_pid, &ids);
188         tdb_close(tdb);
189
190         connections_forall(show_share_parseable, &ids);
191
192         SAFE_FREE(ids.entries);
193
194         return 0;
195 }
196
197 static int net_status_shares(int argc, const char **argv)
198 {
199         if (argc == 0) {
200
201                 d_printf("\nService      pid     machine       "
202                          "Connected at\n");
203                 d_printf("-------------------------------------"
204                          "------------------\n");
205
206                 connections_forall(show_share, NULL);
207
208                 return 0;
209         }
210
211         if ((argc != 1) || !strequal(argv[0], "parseable")) {
212                 return net_help_status(argc, argv);
213         }
214
215         return net_status_shares_parseable(argc, argv);
216 }
217
218 int net_status(int argc, const char **argv)
219 {
220         struct functable func[] = {
221                 {"sessions", net_status_sessions},
222                 {"shares", net_status_shares},
223                 {NULL, NULL}
224         };
225         return net_run_function(argc, argv, func, net_help_status);
226 }