]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - usr.bin/ncplist/ncplist.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.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 <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <unistd.h>
44
45 #include <netncp/ncp_lib.h>
46
47 extern char *__progname;
48
49 static struct ncp_conn_stat conndesc;
50
51 static void help(void);
52 static void show_connlist(void);
53 static void show_serverlist(char *server);
54 static void show_userlist(char *server);
55 static void list_volumes(char *server);
56 static void str_trim_right(char *s, char c);
57
58
59 static int
60 ncp_get_connid(char *server, int justattach)
61 {
62         int connid, error;
63         struct ncp_conn_loginfo li;
64
65         connid = ncp_conn_find(server, NULL);
66         if (connid > 0) {
67                 ncp_conn_getinfo(connid, &conndesc);
68                 return connid;
69         }
70         if (!justattach) {
71                 if (connid == -1) {
72                         printf("You are not attached to server %s\n",server);
73                         return -1;
74                 }
75                 printf("You are not attached to any server\n");
76                 return -1;
77         }
78         ncp_li_init(&li, 0, NULL);
79         if (server) {
80                 ncp_li_setserver(&li, server);
81                 error = ncp_find_fileserver(&li, AF_IPX, NULL);
82                 if (error) {
83                         printf("Could not find server %s\n", li.server);
84                         return -1;
85                 }
86         } else {
87                 error = ncp_find_fileserver(&li, AF_IPX, NULL);
88                 if (error) {
89                         printf("Can't find any file server\n");
90                         return -1;
91                 }
92         }
93         error = ncp_connect(&li, &connid);
94         if (error) {
95                 printf("Can't attach to a nearest server\n");
96                 return -1;
97         }
98         ncp_conn_getinfo(connid, &conndesc);
99         return connid;
100 }
101
102 static struct ncp_bitname conn_statenames [] = {
103         {NCPFL_INVALID, "invalid"},
104         {NCPFL_LOGGED,  "active"},
105         {NCPFL_PERMANENT, "permanent"},
106         {NCPFL_PRIMARY, "primary"},
107         {0, NULL}
108 };
109
110 static void
111 str_trim_right(char *s, char c)
112 {
113         int len;
114
115         for (len = strlen(s) - 1; len > 0 && s[len] == c; len--)
116                 s[len] = '\0';
117 }
118
119 void
120 show_connlist(void)
121 {
122         void *p;
123         int cnt;
124         char buf[200];
125         struct ncp_conn_stat *ncsp;
126
127         printf("Active NCP connections:\n");
128         p = ncp_conn_list();
129         if (p == NULL) {
130                 printf("None\n");
131                 return;
132         }
133         printf(" refid server:user(connid), owner:group(mode), refs, <state>\n");
134         cnt = *(int*)p;
135         ncsp = (struct ncp_conn_stat*)(((int*)p)+1);
136         while (cnt--) {
137                 printf("%6d %s:%s(%d), %s:%s(%o), %d, %s",
138                     ncsp->connRef, ncsp->li.server,ncsp->user,ncsp->connid,
139                     user_from_uid(ncsp->owner, 0), 
140                     group_from_gid(ncsp->group, 0), 
141                     ncsp->li.access_mode,
142                     ncsp->ref_cnt,
143                     ncp_printb(buf, ncsp->flags, conn_statenames));
144                 printf("\n");
145                 ncsp++;
146         }
147         free(p);
148         printf("\n");
149 }
150
151 void
152 show_serverlist(char *server)
153 {
154         int found = 0, connid;
155         struct ncp_bindery_object obj;
156         char *pattern = "*";
157
158         connid = ncp_get_connid(server, 1);
159         if (connid < 0)
160                 return;
161         printf("Visible servers (from %s):\n", conndesc.li.server);
162         printf("Name                                            Network    Node       Port\n");
163         printf("----------------------------------------------- -------- ------------ ----\n");
164         obj.object_id = 0xffffffff;
165
166         while (ncp_scan_bindery_object(connid, obj.object_id, NCP_BINDERY_FSERVER, 
167             pattern, &obj) == 0) {
168                 struct nw_property prop;
169                 struct ipx_addr *naddr = (struct ipx_addr *) &prop;
170
171                 found = 1;
172                 printf("%-48s", obj.object_name);
173
174                 if (ncp_read_property_value(connid, NCP_BINDERY_FSERVER,
175                                             obj.object_name, 1, "NET_ADDRESS",
176                                             &prop) == 0) {
177                         ipx_print_addr(naddr);
178                 }
179                 printf("\n");
180         }
181
182         if (!found) {
183                 printf("No servers found\n");
184         }
185         printf("\n");
186 }
187
188
189 void
190 show_userlist(char *server)
191 {
192         int connid, error, i;
193         struct ncp_file_server_info info;
194         struct ncp_bindery_object user;
195         time_t login_time;
196         struct ipx_addr addr;
197         u_int8_t conn_type;
198
199         connid = ncp_get_connid(server, 0);
200         if (connid < 0) return;
201         if (ncp_get_file_server_information(connid, &info) != 0) {
202                 perror("Could not get server information");
203                 return;
204         }
205         printf("User information for server %s\n",info.ServerName);
206         printf("\n%-6s%-21s%-27s%-12s\n"
207                "---------------------------------------------"
208                "---------------------------------\n",
209                "Conn",
210                "User name",
211                "Station Address",
212                "Login time");
213         for (i = 1; i <= info.MaximumServiceConnections; i++) {
214                 char name[49];
215                 name[48] = '\0';
216                 error = ncp_get_stations_logged_info(connid, i, &user, &login_time);
217                 if (error) continue;
218                 memset(&addr, 0, sizeof(addr));
219                 error = ncp_get_internet_address(connid, i, &addr, &conn_type);
220                 if (error) continue;
221                 memcpy(name, user.object_name, 48);
222                 str_trim_right(name, ' ');
223                 printf("%4d: %-20s ", i, name);
224                 ipx_print_addr(&addr);
225                 printf(" ");
226                 printf("%s", ctime(&login_time));
227         }
228
229         return;
230 }
231
232 void
233 show_queuelist(char *server, char *patt)
234 {
235         struct ncp_bindery_object q;
236         int found = 0, connid;
237         char default_pattern[] = "*";
238         char *pattern = default_pattern;
239
240         connid = ncp_get_connid(server, 1);
241         if (connid < 0) return;
242         if (patt != NULL)
243                 pattern = patt;
244         ncp_str_upper(pattern);
245
246         printf("\nServer: %s\n", server);
247         printf("%-52s%-10s\n"
248                "-----------------------------------------------"
249                "-------------\n",
250                "Print queue name",
251                "Queue ID");
252         q.object_id = 0xffffffff;
253
254         while (ncp_scan_bindery_object(connid, q.object_id,
255                                        NCP_BINDERY_PQUEUE, pattern, &q) == 0)
256         {
257                 found = 1;
258                 printf("%-52s", q.object_name);
259                 printf("%08X\n", (unsigned int) q.object_id);
260         }
261
262         if (!found) {
263                 printf("No queues found\n");
264         }
265         return;
266 }
267
268 void
269 list_volumes(char *server)
270 {
271         int found = 0, connid, i, error;
272         struct ncp_file_server_info si;
273         char volname[NCP_VOLNAME_LEN+1];
274
275         connid = ncp_get_connid(server, 1);
276         if (connid < 0) return;
277         
278         error = ncp_get_file_server_information(connid, &si);
279         if (error) {
280                 ncp_error("Can't get information for server %s", error, server);
281                 return;
282         }
283
284         printf("\nMounted volumes on server %s:\n", server);
285         printf("Number Name\n");
286         printf("------ -----------------------------------------------\n");
287
288         for(i = 0; i < si.NumberMountedVolumes; i++) {
289                 if (NWGetVolumeName(connid, i, volname))
290                         continue;
291                 found = 1;
292                 printf("%6d %s\n", i, volname);
293         }
294
295         if (!found)
296                 printf("No volumes found ?\n");
297         return;
298 }
299
300 struct ncp_bind_type {
301         u_long  type;
302         char    *name;
303 };
304
305 static struct ncp_bind_type btypes[] = {
306         {NCP_BINDERY_USER,      "USER"},
307         {NCP_BINDERY_UGROUP,    "GROUP"},
308         {NCP_BINDERY_PSERVER,   "PSERVER"},
309         {0x278,                 "TREE"},
310         {0, NULL}
311 };
312
313 void
314 list_bindery(char *server, char *type, char *patt)
315 {
316         struct ncp_bindery_object q;
317         int i, found = 0, connid;
318         char default_pattern[] = "*";
319         char *pattern = default_pattern;
320         u_long objtype;
321
322         ncp_str_upper(type);
323         objtype = 0;
324
325         for(i = 0; btypes[i].type; i++) {
326                 if (strcmp(btypes[i].name, type) == 0) {
327                         objtype = btypes[i].type;
328                         break;
329                 }
330         }
331         if (!objtype) {
332                 printf("Bindery object of type %s is unknown\n", type);
333                 return;
334         }
335         if (patt != NULL)
336                 pattern = patt;
337         ncp_str_upper(pattern);
338         connid = ncp_get_connid(server, 1);
339         if (connid < 0) return;
340
341         connid = ncp_get_connid(server, 1);
342         if (connid < 0) return;
343
344
345         printf("\nServer: %s\n", server);
346         printf("%-52s%-10s\n"
347                "-----------------------------------------------"
348                "-------------\n",
349                "Object name",
350                "Object ID");
351
352         q.object_id = 0xffffffff;
353         while (ncp_scan_bindery_object(connid, q.object_id,
354                                        objtype, pattern, &q) == 0)
355         {
356                 found = 1;
357                 printf("%-52s", q.object_name);
358                 printf("%08X\n", (unsigned int) q.object_id);
359         }
360
361         if (!found) {
362                 printf("No bindery objects found\n");
363         }
364         return;
365 }
366
367 enum listop {
368         LO_NONE, LO_SERVERS, LO_QUEUES, LO_BINDERY, LO_USERS, LO_VOLUMES
369 };
370
371 #define MAX_ARGS        10
372
373 int
374 main(int argc, char *argv[])
375 {
376         int opt, nargs = 0, i;
377         enum listop what;
378         char *args[MAX_ARGS];
379
380         bzero(args, sizeof(args));
381
382         what = LO_NONE;
383         while ((opt = getopt(argc, argv, "h")) != -1) {
384                 switch (opt) {
385                     case 'h': case '?':
386                         help();
387                         /*NOTREACHED */
388                     default:
389                         help();
390                         return 1;
391                 }
392         }
393         if (optind >= argc)
394                 help();
395
396         if(ncp_initlib())
397                 exit(1);
398
399         switch(argv[optind++][0]) {
400             case 'b':
401                 what = LO_BINDERY;
402                 nargs = 2;
403                 break;
404             case 'c':
405                 show_connlist();
406                 return 0;
407             case 's':
408                 what = LO_SERVERS;
409                 break;
410             case 'u':
411                 what = LO_USERS;
412                 nargs = 1;
413                 break;
414             case 'q':
415                 what = LO_QUEUES;
416                 nargs = 1;
417                 break;
418             case 'v':
419                 what = LO_VOLUMES;
420                 nargs = 1;
421                 break;
422             default:
423                 printf("Unknown command %s\n", argv[optind-1]);
424                 help();
425         }
426         for (i = 0; i < MAX_ARGS; i++) {
427                 if (optind < argc) {
428                         args[i] = argv[optind++];
429                 } else if (i < nargs) {
430                         printf("Not enough arguments\n");
431                         help();
432                         return 1;
433                 } else
434                         break;
435         }
436         switch(what) {
437             case LO_SERVERS:
438                 show_serverlist(args[0]);
439                 break;
440             case LO_USERS:
441                 show_userlist(args[0]);
442                 break;
443             case LO_QUEUES:
444                 show_queuelist(args[0], args[1]);
445                 break;
446             case LO_VOLUMES:
447                 list_volumes(args[0]);
448                 break;
449             case LO_BINDERY:
450                 list_bindery(args[0], args[1], args[2]);
451                 break;
452             default:
453                 help();
454         }
455         return 0;
456 }
457
458 static void
459 help(void)
460 {
461         printf("\n");
462         printf("usage: %s command [args]\n", __progname);
463         printf("where commands are:\n"
464         " b server user|group [pattern] list bindery objects on server\n"
465         " c                             display opened connections\n"
466         " s [server]                    display known servers\n"
467         " u server                      list logged-in users on server\n"
468         " q server [pattern]            list print queues on server\n"
469         " v server                      list mounted volumes on a specified server\n"
470         "\n");
471         exit(1);
472 }