/* * Copyright (c) 1999, Boris Popov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Boris Popov. * 4. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include extern char *__progname; static struct ncp_conn_stat conndesc; static void help(void); static void show_connlist(void); static void show_serverlist(char *server); static void show_userlist(char *server); static void list_volumes(char *server); static void str_trim_right(char *s, char c); static int ncp_get_connid(char *server, int justattach) { int connid, error; struct ncp_conn_loginfo li; connid = ncp_conn_find(server, NULL); if (connid > 0) { ncp_conn_getinfo(connid, &conndesc); return connid; } if (!justattach) { if (connid == -1) { printf("You are not attached to server %s\n",server); return -1; } printf("You are not attached to any server\n"); return -1; } ncp_li_init(&li, 0, NULL); if (server) { ncp_li_setserver(&li, server); error = ncp_find_fileserver(&li, AF_IPX, NULL); if (error) { printf("Could not find server %s\n", li.server); return -1; } } else { error = ncp_find_fileserver(&li, AF_IPX, NULL); if (error) { printf("Can't find any file server\n"); return -1; } } error = ncp_connect(&li, &connid); if (error) { printf("Can't attach to a nearest server\n"); return -1; } ncp_conn_getinfo(connid, &conndesc); return connid; } static struct ncp_bitname conn_statenames [] = { {NCPFL_INVALID, "invalid"}, {NCPFL_LOGGED, "active"}, {NCPFL_PERMANENT, "permanent"}, {NCPFL_PRIMARY, "primary"}, {0, NULL} }; static void str_trim_right(char *s, char c) { int len; for (len = strlen(s) - 1; len > 0 && s[len] == c; len--) s[len] = '\0'; } void show_connlist(void) { void *p; int cnt; char buf[200]; struct ncp_conn_stat *ncsp; printf("Active NCP connections:\n"); p = ncp_conn_list(); if (p == NULL) { printf("None\n"); return; } printf(" refid server:user(connid), owner:group(mode), refs, \n"); cnt = *(int*)p; ncsp = (struct ncp_conn_stat*)(((int*)p)+1); while (cnt--) { printf("%6d %s:%s(%d), %s:%s(%o), %d, %s", ncsp->connRef, ncsp->li.server,ncsp->user,ncsp->connid, user_from_uid(ncsp->owner, 0), group_from_gid(ncsp->group, 0), ncsp->li.access_mode, ncsp->ref_cnt, ncp_printb(buf, ncsp->flags, conn_statenames)); printf("\n"); ncsp++; } free(p); printf("\n"); } void show_serverlist(char *server) { int found = 0, connid; struct ncp_bindery_object obj; char *pattern = "*"; connid = ncp_get_connid(server, 1); if (connid < 0) return; printf("Visible servers (from %s):\n", conndesc.li.server); printf("Name Network Node Port\n"); printf("----------------------------------------------- -------- ------------ ----\n"); obj.object_id = 0xffffffff; while (ncp_scan_bindery_object(connid, obj.object_id, NCP_BINDERY_FSERVER, pattern, &obj) == 0) { struct nw_property prop; struct ipx_addr *naddr = (struct ipx_addr *) ∝ found = 1; printf("%-48s", obj.object_name); if (ncp_read_property_value(connid, NCP_BINDERY_FSERVER, obj.object_name, 1, "NET_ADDRESS", &prop) == 0) { ipx_print_addr(naddr); } printf("\n"); } if (!found) { printf("No servers found\n"); } printf("\n"); } void show_userlist(char *server) { int connid, error, i; struct ncp_file_server_info info; struct ncp_bindery_object user; time_t login_time; struct ipx_addr addr; u_int8_t conn_type; connid = ncp_get_connid(server, 0); if (connid < 0) return; if (ncp_get_file_server_information(connid, &info) != 0) { perror("Could not get server information"); return; } printf("User information for server %s\n",info.ServerName); printf("\n%-6s%-21s%-27s%-12s\n" "---------------------------------------------" "---------------------------------\n", "Conn", "User name", "Station Address", "Login time"); for (i = 1; i <= info.MaximumServiceConnections; i++) { char name[49]; name[48] = '\0'; error = ncp_get_stations_logged_info(connid, i, &user, &login_time); if (error) continue; memset(&addr, 0, sizeof(addr)); error = ncp_get_internet_address(connid, i, &addr, &conn_type); if (error) continue; memcpy(name, user.object_name, 48); str_trim_right(name, ' '); printf("%4d: %-20s ", i, name); ipx_print_addr(&addr); printf(" "); printf("%s", ctime(&login_time)); } return; } void show_queuelist(char *server, char *patt) { struct ncp_bindery_object q; int found = 0, connid; char default_pattern[] = "*"; char *pattern = default_pattern; connid = ncp_get_connid(server, 1); if (connid < 0) return; if (patt != NULL) pattern = patt; ncp_str_upper(pattern); printf("\nServer: %s\n", server); printf("%-52s%-10s\n" "-----------------------------------------------" "-------------\n", "Print queue name", "Queue ID"); q.object_id = 0xffffffff; while (ncp_scan_bindery_object(connid, q.object_id, NCP_BINDERY_PQUEUE, pattern, &q) == 0) { found = 1; printf("%-52s", q.object_name); printf("%08X\n", (unsigned int) q.object_id); } if (!found) { printf("No queues found\n"); } return; } void list_volumes(char *server) { int found = 0, connid, i, error; struct ncp_file_server_info si; char volname[NCP_VOLNAME_LEN+1]; connid = ncp_get_connid(server, 1); if (connid < 0) return; error = ncp_get_file_server_information(connid, &si); if (error) { ncp_error("Can't get information for server %s", error, server); return; } printf("\nMounted volumes on server %s:\n", server); printf("Number Name\n"); printf("------ -----------------------------------------------\n"); for(i = 0; i < si.NumberMountedVolumes; i++) { if (NWGetVolumeName(connid, i, volname)) continue; found = 1; printf("%6d %s\n", i, volname); } if (!found) printf("No volumes found ?\n"); return; } struct ncp_bind_type { u_long type; char *name; }; static struct ncp_bind_type btypes[] = { {NCP_BINDERY_USER, "USER"}, {NCP_BINDERY_UGROUP, "GROUP"}, {NCP_BINDERY_PSERVER, "PSERVER"}, {0x278, "TREE"}, {0, NULL} }; void list_bindery(char *server, char *type, char *patt) { struct ncp_bindery_object q; int i, found = 0, connid; char default_pattern[] = "*"; char *pattern = default_pattern; u_long objtype; ncp_str_upper(type); objtype = 0; for(i = 0; btypes[i].type; i++) { if (strcmp(btypes[i].name, type) == 0) { objtype = btypes[i].type; break; } } if (!objtype) { printf("Bindery object of type %s is unknown\n", type); return; } if (patt != NULL) pattern = patt; ncp_str_upper(pattern); connid = ncp_get_connid(server, 1); if (connid < 0) return; connid = ncp_get_connid(server, 1); if (connid < 0) return; printf("\nServer: %s\n", server); printf("%-52s%-10s\n" "-----------------------------------------------" "-------------\n", "Object name", "Object ID"); q.object_id = 0xffffffff; while (ncp_scan_bindery_object(connid, q.object_id, objtype, pattern, &q) == 0) { found = 1; printf("%-52s", q.object_name); printf("%08X\n", (unsigned int) q.object_id); } if (!found) { printf("No bindery objects found\n"); } return; } enum listop { LO_NONE, LO_SERVERS, LO_QUEUES, LO_BINDERY, LO_USERS, LO_VOLUMES }; #define MAX_ARGS 10 int main(int argc, char *argv[]) { int opt, wdone = 0, nargs = 0, i; enum listop what; char *args[MAX_ARGS]; bzero(args, sizeof(args)); what = LO_NONE; while ((opt = getopt(argc, argv, "h")) != -1) { switch (opt) { case 'h': case '?': help(); /*NOTREACHED */ default: help(); return 1; } } if (optind >= argc) help(); if(ncp_initlib()) exit(1); switch(argv[optind++][0]) { case 'b': what = LO_BINDERY; nargs = 2; break; case 'c': show_connlist(); return 0; case 's': what = LO_SERVERS; break; case 'u': what = LO_USERS; nargs = 1; break; case 'q': what = LO_QUEUES; nargs = 1; break; case 'v': what = LO_VOLUMES; nargs = 1; break; default: printf("Unknown command %s\n", argv[optind-1]); help(); } for (i = 0; i < MAX_ARGS; i++) { if (optind < argc) { args[i] = argv[optind++]; } else if (i < nargs) { printf("Not enough arguments\n"); help(); return 1; } else break; } switch(what) { case LO_SERVERS: show_serverlist(args[0]); wdone = 1; break; case LO_USERS: show_userlist(args[0]); wdone = 1; break; case LO_QUEUES: show_queuelist(args[0], args[1]); wdone = 1; break; case LO_VOLUMES: list_volumes(args[0]); wdone = 1; break; case LO_BINDERY: list_bindery(args[0], args[1], args[2]); wdone = 1; break; default: help(); } return 0; } static void help(void) { printf("\n"); printf("usage: %s command [args]\n", __progname); printf("where commands are:\n" " b server user|group [pattern] list bindery objects on server\n" " c display opened connections\n" " s [server] display known servers\n" " u server list logged-in users on server\n" " q server [pattern] list print queues on server\n" " v server list mounted volumes on a specified server\n" "\n"); exit(1); }