From e0812b5842c14a677593b53e33dab11c34f627a8 Mon Sep 17 00:00:00 2001 From: Boris Popov Date: Wed, 20 Oct 1999 11:31:02 +0000 Subject: [PATCH] Add ncplist program. That makes minimal set of ncp utilities to use NetWare volumes. Other functionality (ncpsend, ncprint) will be added later. --- usr.bin/Makefile | 1 + usr.bin/ncplist/Makefile | 10 + usr.bin/ncplist/ncplist.1 | 73 ++++++ usr.bin/ncplist/ncplist.c | 463 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 547 insertions(+) create mode 100644 usr.bin/ncplist/Makefile create mode 100644 usr.bin/ncplist/ncplist.1 create mode 100644 usr.bin/ncplist/ncplist.c diff --git a/usr.bin/Makefile b/usr.bin/Makefile index c10ef949db0c..df7d46cf43a3 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -213,6 +213,7 @@ SUBDIR+=ar \ doscmd \ gcore \ gprof4 \ + ncplist \ nm \ ranlib \ sasc \ diff --git a/usr.bin/ncplist/Makefile b/usr.bin/ncplist/Makefile new file mode 100644 index 000000000000..b08d781d09c3 --- /dev/null +++ b/usr.bin/ncplist/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +PROG= ncplist +SRCS= ncplist.c +MAN1= ncplist.1 + +DPADD+= ${LIBIPX} ${LIBNCP} +LDADD+= -lipx -lncp + +.include diff --git a/usr.bin/ncplist/ncplist.1 b/usr.bin/ncplist/ncplist.1 new file mode 100644 index 000000000000..2c869656df74 --- /dev/null +++ b/usr.bin/ncplist/ncplist.1 @@ -0,0 +1,73 @@ +.\" $FreeBSD$ +.Dd Jun 24, 1999 +.Dt NCPLIST 1 +.Os FreeBSD 3.2 +.Sh NAME +.Nm ncplist +.Nd Displays various information about ncplib and NetWare servers +.Sh SYNOPSIS +.Nm ncplist +.Ar command +.Op Ar args +.Sh DESCRIPTION +The +.Nm +command used to display state of ncplib and NetWare servers. First argument +are one letter +.Ar command +following by optional +.Ar args +.Pp +The commands are: +.Bl -tag -width indent +.It b Ar server Ar type Op Ar pattern +Lists bindery objects of +.Ar type +on a specified +.Ar server. +.Ar Type +can be one of the following: +.Bd -literal -offset indent +Type Meaning +user bindery users +group bindery groups +pserver bindery print servers +tree tree name hosted by given server. +.Ed +.Pp +Please note that if you are not logged in to the specified server list can be +incomplete or empty. +.It c +List active NCP connections on local machine. +.It s Op Ar server +Displays NetWare servers known to given +.Ar server . +If no server is specified nearest server will be used. +.It u Ar server +Displays a list of users logged-in on given +.Ar server . +If you are not logged in to the specified server list will be empty. +.It q Ar server Op Ar pattern +Displays bindery queues on given +.Ar server . +.It v Ar server +Displays mounted volumes on given +.Ar server . +.El +.Sh FILES +.Bl -tag -width /var/log/wtmp -compact +.It Pa ~/.nwfsrc +keeps description for each connection. See +.Xr nwfsrc 8 +for details. + +.Sh NOTES +This utility provided mostly for educational purposes. + +.Sh BUGS +to number a few + +.Sh AUTHOR +.An Boris Popov Aq bp@butya.kz +, +.Aq rbp@chat.ru diff --git a/usr.bin/ncplist/ncplist.c b/usr.bin/ncplist/ncplist.c new file mode 100644 index 000000000000..fa657e2cb57c --- /dev/null +++ b/usr.bin/ncplist/ncplist.c @@ -0,0 +1,463 @@ +/* + * 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. + * + * $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); + + +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")) != EOF) { + 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); +}