]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/ncplist/ncplist.c
Use NO_WCAST_ALIGN for usr.bin/ncplist, as there are many potential
[FreeBSD/FreeBSD.git] / usr.bin / ncplist / ncplist.c
1 /*
2  * Copyright (c) 1999, Boris Popov
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *    This product includes software developed by Boris Popov.
16  * 4. Neither the name of the author nor the names of any co-contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32
33 #include <sys/cdefs.h>
34
35 __FBSDID("$FreeBSD$");
36
37 #include <sys/param.h>
38 #include <sys/time.h>
39
40 #include <grp.h>
41 #include <pwd.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <unistd.h>
46
47 #include <netncp/ncp_lib.h>
48
49 extern char *__progname;
50
51 static struct ncp_conn_stat conndesc;
52
53 static void help(void);
54 static void show_connlist(void);
55 static void show_serverlist(char *server);
56 static void show_userlist(char *server);
57 static void list_volumes(char *server);
58 static void str_trim_right(char *s, char c);
59
60
61 static int
62 ncp_get_connid(char *server, int justattach)
63 {
64         int connid, error;
65         struct ncp_conn_loginfo li;
66
67         connid = ncp_conn_find(server, NULL);
68         if (connid > 0) {
69                 ncp_conn_getinfo(connid, &conndesc);
70                 return connid;
71         }
72         if (!justattach) {
73                 if (connid == -1) {
74                         printf("You are not attached to server %s\n",server);
75                         return -1;
76                 }
77                 printf("You are not attached to any server\n");
78                 return -1;
79         }
80         ncp_li_init(&li, 0, NULL);
81         if (server) {
82                 ncp_li_setserver(&li, server);
83                 error = ncp_find_fileserver(&li, AF_IPX, NULL);
84                 if (error) {
85                         printf("Could not find server %s\n", li.server);
86                         return -1;
87                 }
88         } else {
89                 error = ncp_find_fileserver(&li, AF_IPX, NULL);
90                 if (error) {
91                         printf("Can't find any file server\n");
92                         return -1;
93                 }
94         }
95         error = ncp_connect(&li, &connid);
96         if (error) {
97                 printf("Can't attach to a nearest server\n");
98                 return -1;
99         }
100         ncp_conn_getinfo(connid, &conndesc);
101         return connid;
102 }
103
104 static struct ncp_bitname conn_statenames [] = {
105         {NCPFL_INVALID, "invalid"},
106         {NCPFL_LOGGED,  "active"},
107         {NCPFL_PERMANENT, "permanent"},
108         {NCPFL_PRIMARY, "primary"},
109         {0, NULL}
110 };
111
112 static void
113 str_trim_right(char *s, char c)
114 {
115         int len;
116
117         for (len = strlen(s) - 1; len > 0 && s[len] == c; len--)
118                 s[len] = '\0';
119 }
120
121 void
122 show_connlist(void)
123 {
124         void *p;
125         int cnt;
126         char buf[200];
127         struct ncp_conn_stat *ncsp;
128
129         printf("Active NCP connections:\n");
130         p = ncp_conn_list();
131         if (p == NULL) {
132                 printf("None\n");
133                 return;
134         }
135         printf(" refid server:user(connid), owner:group(mode), refs, <state>\n");
136         cnt = *(int*)p;
137         ncsp = (struct ncp_conn_stat*)(((int*)p)+1);
138         while (cnt--) {
139                 printf("%6d %s:%s(%d), %s:%s(%o), %d, %s",
140                     ncsp->connRef, ncsp->li.server,ncsp->user,ncsp->connid,
141                     user_from_uid(ncsp->owner, 0), 
142                     group_from_gid(ncsp->group, 0), 
143                     ncsp->li.access_mode,
144                     ncsp->ref_cnt,
145                     ncp_printb(buf, ncsp->flags, conn_statenames));
146                 printf("\n");
147                 ncsp++;
148         }
149         free(p);
150         printf("\n");
151 }
152
153 void
154 show_serverlist(char *server)
155 {
156         int found = 0, connid;
157         struct ncp_bindery_object obj;
158         const char *pattern = "*";
159
160         connid = ncp_get_connid(server, 1);
161         if (connid < 0)
162                 return;
163         printf("Visible servers (from %s):\n", conndesc.li.server);
164         printf("Name                                            Network    Node       Port\n");
165         printf("----------------------------------------------- -------- ------------ ----\n");
166         obj.object_id = 0xffffffff;
167
168         while (ncp_scan_bindery_object(connid, obj.object_id, NCP_BINDERY_FSERVER, 
169             pattern, &obj) == 0) {
170                 struct nw_property prop;
171                 struct ipx_addr *naddr = (struct ipx_addr *) &prop;
172
173                 found = 1;
174                 printf("%-48s", obj.object_name);
175
176                 if (ncp_read_property_value(connid, NCP_BINDERY_FSERVER,
177                                             obj.object_name, 1, "NET_ADDRESS",
178                                             &prop) == 0) {
179                         ipx_print_addr(naddr);
180                 }
181                 printf("\n");
182         }
183
184         if (!found) {
185                 printf("No servers found\n");
186         }
187         printf("\n");
188 }
189
190
191 void
192 show_userlist(char *server)
193 {
194         int connid, error, i;
195         struct ncp_file_server_info info;
196         struct ncp_bindery_object user;
197         time_t login_time;
198         struct ipx_addr addr;
199         u_int8_t conn_type;
200
201         connid = ncp_get_connid(server, 0);
202         if (connid < 0) return;
203         if (ncp_get_file_server_information(connid, &info) != 0) {
204                 perror("Could not get server information");
205                 return;
206         }
207         printf("User information for server %s\n",info.ServerName);
208         printf("\n%-6s%-21s%-27s%-12s\n"
209                "---------------------------------------------"
210                "---------------------------------\n",
211                "Conn",
212                "User name",
213                "Station Address",
214                "Login time");
215         for (i = 1; i <= info.MaximumServiceConnections; i++) {
216                 char name[49];
217                 name[48] = '\0';
218                 error = ncp_get_stations_logged_info(connid, i, &user, &login_time);
219                 if (error) continue;
220                 memset(&addr, 0, sizeof(addr));
221                 error = ncp_get_internet_address(connid, i, &addr, &conn_type);
222                 if (error) continue;
223                 memcpy(name, user.object_name, 48);
224                 str_trim_right(name, ' ');
225                 printf("%4d: %-20s ", i, name);
226                 ipx_print_addr(&addr);
227                 printf(" ");
228                 printf("%s", ctime(&login_time));
229         }
230
231         return;
232 }
233
234 static void
235 show_queuelist(char *server, char *patt)
236 {
237         struct ncp_bindery_object q;
238         int found = 0, connid;
239         char default_pattern[] = "*";
240         char *pattern = default_pattern;
241
242         connid = ncp_get_connid(server, 1);
243         if (connid < 0) return;
244         if (patt != NULL)
245                 pattern = patt;
246         ncp_str_upper(pattern);
247
248         printf("\nServer: %s\n", server);
249         printf("%-52s%-10s\n"
250                "-----------------------------------------------"
251                "-------------\n",
252                "Print queue name",
253                "Queue ID");
254         q.object_id = 0xffffffff;
255
256         while (ncp_scan_bindery_object(connid, q.object_id,
257                                        NCP_BINDERY_PQUEUE, pattern, &q) == 0)
258         {
259                 found = 1;
260                 printf("%-52s", q.object_name);
261                 printf("%08X\n", (unsigned int) q.object_id);
262         }
263
264         if (!found) {
265                 printf("No queues found\n");
266         }
267         return;
268 }
269
270 void
271 list_volumes(char *server)
272 {
273         int found = 0, connid, i, error;
274         struct ncp_file_server_info si;
275         char volname[NCP_VOLNAME_LEN+1];
276
277         connid = ncp_get_connid(server, 1);
278         if (connid < 0) return;
279         
280         error = ncp_get_file_server_information(connid, &si);
281         if (error) {
282                 ncp_error("Can't get information for server %s", error, server);
283                 return;
284         }
285
286         printf("\nMounted volumes on server %s:\n", server);
287         printf("Number Name\n");
288         printf("------ -----------------------------------------------\n");
289
290         for(i = 0; i < si.NumberMountedVolumes; i++) {
291                 if (NWGetVolumeName(connid, i, volname))
292                         continue;
293                 found = 1;
294                 printf("%6d %s\n", i, volname);
295         }
296
297         if (!found)
298                 printf("No volumes found ?\n");
299         return;
300 }
301
302 struct ncp_bind_type {
303         u_long          type;
304         const char      *name;
305 };
306
307 static struct ncp_bind_type btypes[] = {
308         {NCP_BINDERY_USER,      "USER"},
309         {NCP_BINDERY_UGROUP,    "GROUP"},
310         {NCP_BINDERY_PSERVER,   "PSERVER"},
311         {0x278,                 "TREE"},
312         {0, NULL}
313 };
314
315 static void
316 list_bindery(char *server, char *type, char *patt)
317 {
318         struct ncp_bindery_object q;
319         int i, found = 0, connid;
320         char default_pattern[] = "*";
321         char *pattern = default_pattern;
322         u_long objtype;
323
324         ncp_str_upper(type);
325         objtype = 0;
326
327         for(i = 0; btypes[i].type; i++) {
328                 if (strcmp(btypes[i].name, type) == 0) {
329                         objtype = btypes[i].type;
330                         break;
331                 }
332         }
333         if (!objtype) {
334                 printf("Bindery object of type %s is unknown\n", type);
335                 return;
336         }
337         if (patt != NULL)
338                 pattern = patt;
339         ncp_str_upper(pattern);
340         connid = ncp_get_connid(server, 1);
341         if (connid < 0) return;
342
343         connid = ncp_get_connid(server, 1);
344         if (connid < 0) return;
345
346
347         printf("\nServer: %s\n", server);
348         printf("%-52s%-10s\n"
349                "-----------------------------------------------"
350                "-------------\n",
351                "Object name",
352                "Object ID");
353
354         q.object_id = 0xffffffff;
355         while (ncp_scan_bindery_object(connid, q.object_id,
356                                        objtype, pattern, &q) == 0)
357         {
358                 found = 1;
359                 printf("%-52s", q.object_name);
360                 printf("%08X\n", (unsigned int) q.object_id);
361         }
362
363         if (!found) {
364                 printf("No bindery objects found\n");
365         }
366         return;
367 }
368
369 enum listop {
370         LO_NONE, LO_SERVERS, LO_QUEUES, LO_BINDERY, LO_USERS, LO_VOLUMES
371 };
372
373 #define MAX_ARGS        10
374
375 int
376 main(int argc, char *argv[])
377 {
378         int opt, wdone = 0, nargs = 0, i;
379         enum listop what;
380         char *args[MAX_ARGS];
381
382         bzero(args, sizeof(args));
383
384         what = LO_NONE;
385         while ((opt = getopt(argc, argv, "h")) != -1) {
386                 switch (opt) {
387                     case 'h': case '?':
388                         help();
389                         /*NOTREACHED */
390                     default:
391                         help();
392                         return 1;
393                 }
394         }
395         if (optind >= argc)
396                 help();
397
398         if(ncp_initlib())
399                 exit(1);
400
401         switch(argv[optind++][0]) {
402             case 'b':
403                 what = LO_BINDERY;
404                 nargs = 2;
405                 break;
406             case 'c':
407                 show_connlist();
408                 return 0;
409             case 's':
410                 what = LO_SERVERS;
411                 break;
412             case 'u':
413                 what = LO_USERS;
414                 nargs = 1;
415                 break;
416             case 'q':
417                 what = LO_QUEUES;
418                 nargs = 1;
419                 break;
420             case 'v':
421                 what = LO_VOLUMES;
422                 nargs = 1;
423                 break;
424             default:
425                 printf("Unknown command %s\n", argv[optind-1]);
426                 help();
427         }
428         for (i = 0; i < MAX_ARGS; i++) {
429                 if (optind < argc) {
430                         args[i] = argv[optind++];
431                 } else if (i < nargs) {
432                         printf("Not enough arguments\n");
433                         help();
434                         return 1;
435                 } else
436                         break;
437         }
438         switch(what) {
439             case LO_SERVERS:
440                 show_serverlist(args[0]);
441                 wdone = 1;
442                 break;
443             case LO_USERS:
444                 show_userlist(args[0]);
445                 wdone = 1;
446                 break;
447             case LO_QUEUES:
448                 show_queuelist(args[0], args[1]);
449                 wdone = 1;
450                 break;
451             case LO_VOLUMES:
452                 list_volumes(args[0]);
453                 wdone = 1;
454                 break;
455             case LO_BINDERY:
456                 list_bindery(args[0], args[1], args[2]);
457                 wdone = 1;
458                 break;
459             default:
460                 help();
461         }
462         return 0;
463 }
464
465 static void
466 help(void)
467 {
468         printf("\n");
469         printf("usage: %s command [args]\n", __progname);
470         printf("where commands are:\n"
471         " b server user|group [pattern] list bindery objects on server\n"
472         " c                             display opened connections\n"
473         " s [server]                    display known servers\n"
474         " u server                      list logged-in users on server\n"
475         " q server [pattern]            list print queues on server\n"
476         " v server                      list mounted volumes on a specified server\n"
477         "\n");
478         exit(1);
479 }