diff --git a/.downloads/ncpfs-2.0.3.tgz b/.downloads/ncpfs-2.0.3.tgz new file mode 100644 index 0000000..9e48cbe Binary files /dev/null and b/.downloads/ncpfs-2.0.3.tgz differ diff --git a/Changes b/Changes index 682e687..2684a8a 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,22 @@ I only began this file with ncpfs-0.12. If you're interested in older versions, you can find them on ftp.gwdg.de:/pub/linux/misc/ncpfs/old. +ncpfs-2.0.2 -> ncpfs-2.0.3 +- Removed the kernel-2.0 directory. Linus took the patch into 2.0.8. + So, if you want to use long file name support, upgrade to Linux + kernel version 2.0.8. +- Applied the lfn patch to the kernel-1.2 module with some light + testing. If you experience problems, tell it to me, and use the + ncpfs-2.0.2 kernel module, or upgrade to Linux 2.0.8. +- Added unencrypted login when no crypt key is returned. +- Hopefully improved error messages a bit +- Added some values to ipxparse +- For ELF systems, moved ncplib to /lib/libncp.so.1.x. This saves + about 1MB of disk space. As ncpfs grows, the saving will + increase. Please look at the Makefile to enable this. +- Enhanced nwfsinfo a bit. (Even with a manpage!) +- Added nwuserlist. + ncpfs-2.0.1 -> ncpfs-2.0.2 - Added some values to ipxparse. - Added a patch against 2.0.7 for long file names support. I did not @@ -133,4 +149,4 @@ ncpfs-0.12 -> ncpfs-0.13 - support for automatic loading of ncpfs.o by kerneld. Thanks to Steven N. Hirsch . - A subtle problem in the read routines has been removed by Uwe Bonnes - . Thanks a lot. \ No newline at end of file + . Thanks a lot. diff --git a/FAQ b/FAQ index cdaf2a1..904c800 100644 --- a/FAQ +++ b/FAQ @@ -37,13 +37,6 @@ packet signatures on the 4.1 server, as ncpfs does not support them. ------------------------------------------------------------------------------- -Q: Does ncpfs support long file names, using the OS/2 namespace? - -Yes. But you will have to patch your kernel. Look at the file -kernel-2.0/README for more information. - -------------------------------------------------------------------------------- - Q: When I re-export ncpfs-mounted directories via nfs, I get messages like 'pwd: cannot get current directory', and other strange things happen to the nfs clients. What's wrong? diff --git a/Makefile b/Makefile index bec5406..a82502c 100644 --- a/Makefile +++ b/Makefile @@ -2,12 +2,15 @@ # Makefile for the linux ncp-filesystem routines. # -VERSION = 2.0.2 +VERSION = 2.0.3 # If you are using kerneld to autoload ncp support, # uncomment this (kerneld is in linux since about 1.3.57): #KERNELD = -DHAVE_KERNELD +# If your system is ELF, please uncomment the following line: +#HAVE_ELF=yes + TOPDIR = $(shell pwd) BINDIR = /usr/local/bin SBINDIR = /sbin @@ -21,7 +24,7 @@ SUBDIRS += kernel-1.2/src INCLUDES = -I$(TOPDIR)/kernel-1.2 endif -export INCLUDES BINDIR INTERM_BINDIR SBINDIR KERNELD VERSION +export INCLUDES BINDIR INTERM_BINDIR SBINDIR KERNELD VERSION HAVE_ELF all: for i in $(SUBDIRS); do make -C $$i all; done diff --git a/README b/README index 22aa684..4d0d3f0 100644 --- a/README +++ b/README @@ -39,6 +39,12 @@ ncpfs. If you are running kerneld, please uncomment the corresponding line in the Makefile to reflect this. +If your system is ELF, please enable the use of the shared ncp-library +in the Makefile. This will save at least 1MB of disk space. + +After you adapted your Makefile, type 'make' and, as root, 'make install'. + + HELP In the meantime my mail volume has grown considerably, so the response diff --git a/ipxdump/ipxparse.c b/ipxdump/ipxparse.c index 8e3e890..10726ce 100644 --- a/ipxdump/ipxparse.c +++ b/ipxdump/ipxparse.c @@ -351,6 +351,10 @@ void handle_ncp (struct sockaddr_ipx *source, switch(rq->function) { + case 18: + printf("fn: %-3d\n", rq->function); + printf("Get Volume Info with Number\n"); + break; case 20: printf("fn: %-3d\n", rq->function); printf("Get File Server Date and Time\n"); @@ -381,6 +385,9 @@ void handle_ncp (struct sockaddr_ipx *source, case 01: printf("Get Directory Path\n"); break; + case 02: + printf("Scan Directory Information\n"); + break; case 03: printf("Get Effective Directory Rights\n"); break; @@ -390,6 +397,9 @@ void handle_ncp (struct sockaddr_ipx *source, case 06: printf("Get Volume Name\n"); break; + case 10: + printf("Create directory\n"); + break; case 18: printf("Allocate Permanent Dir Handle\n"); break; @@ -399,6 +409,9 @@ void handle_ncp (struct sockaddr_ipx *source, case 21: printf("Get Volume Info with handle\n"); break; + case 39: + printf("Add ext. Trustee to Dir or File\n"); + break; case 48: printf("Get Name Space Directory Entry\n"); break; @@ -426,21 +439,48 @@ void handle_ncp (struct sockaddr_ipx *source, case 28: printf("Get Connection Information\n"); break; + case 50: + printf("Create Bindery Object\n"); + break; case 53: printf("Get Bindery Object ID\n"); break; + case 54: + printf("Get Bindery Object Name\n"); + break; case 55: printf("Scan Bindery Object\n"); break; + case 57: + printf("Create Property\n"); + break; + case 59: + printf("Change Property Security\n"); + break; + case 60: + printf("Scan Property\n"); + break; case 61: printf("Read Property Value\n"); break; case 62: printf("Write Property Value\n"); break; + case 65: + printf("Add Bindery Object to Set\n"); + break; + case 67: + printf("Is Bindery Object in Set\n"); + break; case 70: printf("Get Bindery Access Level\n"); break; + case 72: + printf("Get Bindery Object Access Level\n"); + break; + case 75: + printf("Keyed change password\n"); + break; } data += 3; @@ -476,6 +516,10 @@ void handle_ncp (struct sockaddr_ipx *source, printf("fn: %-3d\n", rq->function); printf("Close File\n"); break; + case 67: + printf("fn: %-3d\n", rq->function); + printf("Create File\n"); + break; case 72: printf("fn: %-3d\n", rq->function); printf("Read from File\n"); @@ -488,6 +532,11 @@ void handle_ncp (struct sockaddr_ipx *source, printf("fn: %-3d\n", rq->function); printf("Set File Time Date Stamp\n"); break; + case 76: + printf("fn: %-3d\n", rq->function); + printf("Open File (old)\n"); + break; + case 87: printf("fn: %-3d, subfn: %-3d\n", rq->function, data[0]); diff --git a/kernel-1.2/linux/ncp.h b/kernel-1.2/linux/ncp.h index ab3f653..3d5286e 100644 --- a/kernel-1.2/linux/ncp.h +++ b/kernel-1.2/linux/ncp.h @@ -116,6 +116,12 @@ struct ncp_file_info { __u16 update_time; }; +/* Defines for Name Spaces */ +#define NW_NS_DOS 0 +#define NW_NS_MAC 1 +#define NW_NS_NFS 2 +#define NW_NS_FTAM 3 +#define NW_NS_OS2 4 /* Defines for ReturnInformationMask */ #define RIM_NAME (0x0001L) diff --git a/kernel-1.2/linux/ncp_fs_sb.h b/kernel-1.2/linux/ncp_fs_sb.h index 26e76ac..36fd36b 100644 --- a/kernel-1.2/linux/ncp_fs_sb.h +++ b/kernel-1.2/linux/ncp_fs_sb.h @@ -21,6 +21,8 @@ struct ncp_server { interest for us later, so we store it completely. */ + __u8 name_space[NCP_NUMBER_OF_VOLUMES]; + struct file *ncp_filp; /* File pointer to ncp socket */ struct file *wdog_filp; /* File pointer to wdog socket */ void *data_ready; /* The wdog socket gets a new diff --git a/kernel-1.2/src/dir.c b/kernel-1.2/src/dir.c index b1a7f77..56f86e0 100644 --- a/kernel-1.2/src/dir.c +++ b/kernel-1.2/src/dir.c @@ -97,6 +97,20 @@ str_lower(char *name) } } +static inline int +ncp_namespace(struct inode *i) +{ + struct ncp_server *server = NCP_SERVER(i); + struct nw_info_struct *info = NCP_ISTRUCT(i); + return server->name_space[info->volNumber]; +} + +static inline int +ncp_preserve_case(struct inode *i) +{ + return (ncp_namespace(i) == NW_NS_OS2); +} + static struct file_operations ncp_dir_operations = { NULL, /* lseek - default */ ncp_dir_read, /* read - bad */ @@ -133,7 +147,7 @@ struct inode_operations ncp_dir_inode_operations = { /* Here we encapsulate the inode number handling that depends upon the * mount mode: When we mount a complete server, the memory address of * the npc_inode_info is used as an inode. When only a single volume - * is mounted, then the DosDirNum is used as the inode number. As this + * is mounted, then the dirEntNum is used as the inode number. As this * is unique for the complete volume, this should enable the NFS * exportability of a ncpfs-mounted volume. */ @@ -148,7 +162,7 @@ inline ino_t ncp_info_ino(struct ncp_server *server, struct ncp_inode_info *info) { return ncp_single_volume(server) - ? info->finfo.i.DosDirNum : (ino_t)info; + ? info->finfo.i.dirEntNum : (ino_t)info; } static inline int @@ -351,9 +365,12 @@ ncp_readdir(struct inode *inode, struct file *filp, c_last_returned_index = 0; index = 0; - for (i = 0; i < c_size; i++) + if (!ncp_preserve_case(inode)) { - str_lower(c_entry[i].i.entryName); + for (i = 0; i < c_size; i++) + { + str_lower(c_entry[i].i.entryName); + } } } } @@ -375,7 +392,7 @@ ncp_readdir(struct inode *inode, struct file *filp, if (ncp_single_volume(server)) { - ino = (ino_t)(entry->i.DosDirNum); + ino = (ino_t)(entry->i.dirEntNum); } else { @@ -671,7 +688,7 @@ ncp_init_root(struct ncp_server *server) root->finfo.opened = 0; i->attributes = aDIR; i->dataStreamSize = 1024; - i->DosDirNum = 0; + i->dirEntNum = i->DosDirNum = 0; i->volNumber = NCP_NUMBER_OF_VOLUMES+1; /* illegal volnum */ ncp_date_unix2dos(0, &(i->creationTime), &(i->creationDate)); ncp_date_unix2dos(0, &(i->modifyTime), &(i->modifyDate)); @@ -748,7 +765,7 @@ ncp_find_dir_inode(struct inode *dir, const char *name) do { - if ( (result->dir->finfo.i.DosDirNum == dir_info->DosDirNum) + if ( (result->dir->finfo.i.dirEntNum == dir_info->dirEntNum) && (result->dir->finfo.i.volNumber == dir_info->volNumber) && (strcmp(result->finfo.i.entryName, name) == 0) /* The root dir is never looked up using this @@ -776,7 +793,7 @@ ncp_lookup(struct inode *dir, const char *__name, int len, struct ncp_server *server; struct ncp_inode_info *result_info; int found_in_cache; - + int down_case = 0; char name[len+1]; *result = NULL; @@ -887,20 +904,26 @@ ncp_lookup(struct inode *dir, const char *__name, int len, if (found_in_cache == 0) { int res; - str_upper(name); DDPRINTK("ncp_lookup: do_lookup on %s/%s\n", NCP_ISTRUCT(dir)->entryName, name); if (ncp_is_server_root(dir)) { + str_upper(name); + down_case = 1; res = ncp_lookup_volume(server, name, &(finfo.i)); } else { + if (!ncp_preserve_case(dir)) + { + str_upper(name); + down_case = 1; + } res = ncp_obtain_info(server, NCP_ISTRUCT(dir)->volNumber, - NCP_ISTRUCT(dir)->DosDirNum, + NCP_ISTRUCT(dir)->dirEntNum, name, &(finfo.i)); } if (res != 0) @@ -912,7 +935,11 @@ ncp_lookup(struct inode *dir, const char *__name, int len, } finfo.opened = 0; - str_lower(finfo.i.entryName); + + if (down_case != 0) + { + str_lower(finfo.i.entryName); + } if (!(*result = ncp_iget(dir, &finfo))) { @@ -949,7 +976,11 @@ ncp_create(struct inode *dir, const char *name, int len, int mode, strncpy(_name, name, len); _name[len] = '\0'; - str_upper(_name); + + if (!ncp_preserve_case(dir)) + { + str_upper(_name); + } lock_super(dir->i_sb); if (ncp_open_create_file_or_subdir(NCP_SERVER(dir), @@ -966,7 +997,11 @@ ncp_create(struct inode *dir, const char *name, int len, int mode, ncp_invalid_dir_cache(dir); - str_lower(finfo.i.entryName); + if (!ncp_preserve_case(dir)) + { + str_lower(finfo.i.entryName); + } + finfo.access = O_RDWR; if (!(*result = ncp_iget(dir, &finfo)) < 0) @@ -1000,7 +1035,11 @@ ncp_mkdir(struct inode *dir, const char *name, int len, int mode) strncpy(_name, name, len); _name[len] = '\0'; - str_upper(_name); + + if (!ncp_preserve_case(dir)) + { + str_upper(_name); + } if (!dir || !S_ISDIR(dir->i_mode)) { @@ -1058,7 +1097,11 @@ ncp_rmdir(struct inode *dir, const char *name, int len) strncpy(_name, name, len); _name[len] = '\0'; - str_upper(_name); + + if (!ncp_preserve_case(dir)) + { + str_upper(_name); + } if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir), NCP_ISTRUCT(dir), @@ -1101,7 +1144,11 @@ ncp_unlink(struct inode *dir, const char *name, int len) { strncpy(_name, name, len); _name[len] = '\0'; - str_upper(_name); + + if (!ncp_preserve_case(dir)) + { + str_upper(_name); + } if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir), NCP_ISTRUCT(dir), @@ -1155,11 +1202,19 @@ ncp_rename(struct inode *old_dir, const char *old_name, int old_len, strncpy(_old_name, old_name, old_len); _old_name[old_len] = '\0'; - str_upper(_old_name); + + if (!ncp_preserve_case(old_dir)) + { + str_upper(_old_name); + } strncpy(_new_name, new_name, new_len); _new_name[new_len] = '\0'; - str_upper(_new_name); + + if (!ncp_preserve_case(new_dir)) + { + str_upper(_new_name); + } res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir), NCP_ISTRUCT(old_dir), _old_name, diff --git a/kernel-1.2/src/ncplib_kernel.c b/kernel-1.2/src/ncplib_kernel.c index 09e0ef9..d987b6e 100644 --- a/kernel-1.2/src/ncplib_kernel.c +++ b/kernel-1.2/src/ncplib_kernel.c @@ -188,25 +188,6 @@ ncp_get_volume_info_with_number(struct ncp_server *server, int n, return 0; } -int -ncp_get_volume_number(struct ncp_server *server, const char *name, int *target) -{ - int result; - - ncp_init_request_s(server, 5); - ncp_add_pstring(server, name); - - if ((result = ncp_request(server, 22)) != 0) - { - ncp_unlock_server(server); - return result; - } - - *target = ncp_reply_byte(server, 0); - ncp_unlock_server(server); - return 0; -} - int ncp_close_file(struct ncp_server *server, const char *file_id) { @@ -282,8 +263,8 @@ ncp_obtain_info(struct ncp_server *server, ncp_init_request(server); ncp_add_byte(server, 6); /* subfunction */ - ncp_add_byte(server, 0); /* dos name space */ - ncp_add_byte(server, 0); /* dos name space as dest */ + ncp_add_byte(server, server->name_space[vol_num]); + ncp_add_byte(server, server->name_space[vol_num]); ncp_add_word(server, 0xff); /* get all */ ncp_add_dword(server, RIM_ALL); ncp_add_handle_path(server, vol_num, dir_base, 1, path); @@ -299,20 +280,57 @@ ncp_obtain_info(struct ncp_server *server, return 0; } +static inline int +ncp_has_os2_namespace(struct ncp_server *server, __u8 volume) +{ + int result; + __u8 *namespace; + __u16 no_namespaces; + + ncp_init_request(server); + ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */ + ncp_add_word(server, 0); + ncp_add_byte(server, volume); + + if ((result = ncp_request(server, 87)) != 0) + { + ncp_unlock_server(server); + return 0; + } + + no_namespaces = ncp_reply_word(server, 0); + namespace = ncp_reply_data(server, 2); + + while (no_namespaces > 0) + { + DPRINTK("get_namespaces: found %d on %d\n", *namespace,volume); + + if (*namespace == 4) + { + DPRINTK("get_namespaces: found OS2\n"); + ncp_unlock_server(server); + return 1; + } + namespace += 1; + no_namespaces -= 1; + } + ncp_unlock_server(server); + return 0; +} + int ncp_lookup_volume(struct ncp_server *server, char *volname, struct nw_info_struct *target) { int result; - __u8 vol_num; - __u32 dir_base; + int volnum; DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname); ncp_init_request(server); ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */ - ncp_add_byte(server, 0); /* DOS name space */ + ncp_add_byte(server, 0); /* DOS namespace */ ncp_add_byte(server, 0); /* reserved */ ncp_add_byte(server, 0); /* reserved */ ncp_add_byte(server, 0); /* reserved */ @@ -329,20 +347,19 @@ ncp_lookup_volume(struct ncp_server *server, return result; } - dir_base = ncp_reply_dword(server, 4); - vol_num = ncp_reply_byte(server, 8); + memset(target, 0, sizeof(*target)); + target->DosDirNum = target->dirEntNum = ncp_reply_dword(server, 4); + target->volNumber = volnum = ncp_reply_byte(server, 8); ncp_unlock_server(server); - if ((result = ncp_obtain_info(server, vol_num, dir_base, NULL, - target)) != 0) - { - return result; - } + server->name_space[volnum] = ncp_has_os2_namespace(server,volnum)?4:0; - DPRINTK("ncp_lookup_volume: attribs = %X\n", target->attributes); + DPRINTK("lookup_vol: namespace[%d] = %d\n", + volnum, server->name_space[volnum]); target->nameLen = strlen(volname); strcpy(target->entryName, volname); + target->attributes = aDIR; return 0; } @@ -356,14 +373,14 @@ ncp_modify_file_or_subdir_dos_info(struct ncp_server *server, ncp_init_request(server); ncp_add_byte(server, 7); /* subfunction */ - ncp_add_byte(server, 0); /* dos name space */ + ncp_add_byte(server, server->name_space[file->volNumber]); ncp_add_byte(server, 0); /* reserved */ ncp_add_word(server, 0x8006); /* search attribs: all */ ncp_add_dword(server, info_mask); ncp_add_mem(server, info, sizeof(*info)); ncp_add_handle_path(server, file->volNumber, - file->DosDirNum, 1, NULL); + file->dirEntNum, 1, NULL); if ((result = ncp_request(server, 87)) != 0) { @@ -383,11 +400,11 @@ ncp_del_file_or_subdir(struct ncp_server *server, ncp_init_request(server); ncp_add_byte(server, 8); /* subfunction */ - ncp_add_byte(server, 0); /* dos name space */ + ncp_add_byte(server, server->name_space[dir->volNumber]); ncp_add_byte(server, 0); /* reserved */ ncp_add_word(server, 0x8006); /* search attribs: all */ ncp_add_handle_path(server, dir->volNumber, - dir->DosDirNum, 1, name); + dir->dirEntNum, 1, name); if ((result = ncp_request(server, 87)) != 0) { @@ -420,15 +437,16 @@ ncp_open_create_file_or_subdir(struct ncp_server *server, { int result; __u16 search_attribs = 0x0006; + __u8 volume = (dir != NULL) ? dir->volNumber : target->i.volNumber; if ((create_attributes & aDIR) != 0) { - search_attribs |= 0x8000; - } + search_attribs |= 0x8000; +} ncp_init_request(server); ncp_add_byte(server, 1); /* subfunction */ - ncp_add_byte(server, 0); /* dos name space */ + ncp_add_byte(server, server->name_space[volume]); ncp_add_byte(server, open_create_mode); ncp_add_word(server, search_attribs); ncp_add_dword(server, RIM_ALL); @@ -439,13 +457,11 @@ ncp_open_create_file_or_subdir(struct ncp_server *server, if (dir != NULL) { - ncp_add_handle_path(server, dir->volNumber, - dir->DosDirNum, 1, name); + ncp_add_handle_path(server, volume, dir->dirEntNum, 1, name); } else { - ncp_add_handle_path(server, - target->i.volNumber, target->i.DosDirNum, + ncp_add_handle_path(server, volume, target->i.dirEntNum, 1, NULL); } @@ -481,9 +497,9 @@ ncp_initialize_search(struct ncp_server *server, ncp_init_request(server); ncp_add_byte(server, 2); /* subfunction */ - ncp_add_byte(server, 0); /* dos name space */ + ncp_add_byte(server, server->name_space[dir->volNumber]); ncp_add_byte(server, 0); /* reserved */ - ncp_add_handle_path(server, dir->volNumber, dir->DosDirNum, 1, NULL); + ncp_add_handle_path(server, dir->volNumber, dir->dirEntNum, 1, NULL); if ((result = ncp_request(server, 87)) != 0) { @@ -507,7 +523,7 @@ ncp_search_for_file_or_subdir(struct ncp_server *server, ncp_init_request(server); ncp_add_byte(server, 3); /* subfunction */ - ncp_add_byte(server, 0); /* dos name space */ + ncp_add_byte(server, server->name_space[seq->volNumber]); ncp_add_byte(server, 0); /* data stream (???) */ ncp_add_word(server, 0xffff); /* Search attribs */ ncp_add_dword(server, RIM_ALL); /* return info mask */ @@ -542,19 +558,19 @@ ncp_ren_or_mov_file_or_subdir(struct ncp_server *server, ncp_init_request(server); ncp_add_byte(server, 4); /* subfunction */ - ncp_add_byte(server, 0); /* dos name space */ + ncp_add_byte(server, server->name_space[old_dir->volNumber]); ncp_add_byte(server, 1); /* rename flag */ ncp_add_word(server, 0x8006); /* search attributes */ /* source Handle Path */ ncp_add_byte(server, old_dir->volNumber); - ncp_add_dword(server, old_dir->DosDirNum); + ncp_add_dword(server, old_dir->dirEntNum); ncp_add_byte(server, 1); ncp_add_byte(server, 1); /* 1 source component */ /* dest Handle Path */ ncp_add_byte(server, new_dir->volNumber); - ncp_add_dword(server, new_dir->DosDirNum); + ncp_add_dword(server, new_dir->dirEntNum); ncp_add_byte(server, 1); ncp_add_byte(server, 1); /* 1 destination component */ diff --git a/kernel-2.0/README b/kernel-2.0/README deleted file mode 100644 index ec19f0c..0000000 --- a/kernel-2.0/README +++ /dev/null @@ -1,18 +0,0 @@ -This directory contains the patch you have to apply to the Linux -kernel if you want to use the support for long file names using the -OS/2 namespace on the NetWare server. It did not make it into 2.0, but -patching your kernel is really no problem. - -To apply this patch, please take a clean Linux kernel. This patch is -against Linux 2.0.7, but any later kernel version in the 2.0.x series -should also work fine. Please perform the following two steps: - -cd /usr/src/linux -patch -p1 name_space[info->volNumber]; -+} -+ -+static inline int -+ncp_preserve_case(struct inode *i) -+{ -+ return (ncp_namespace(i) == NW_NS_OS2); -+} -+ - static struct file_operations ncp_dir_operations = { - NULL, /* lseek - default */ - ncp_dir_read, /* read - bad */ -@@ -128,7 +142,7 @@ - /* Here we encapsulate the inode number handling that depends upon the - * mount mode: When we mount a complete server, the memory address of - * the ncp_inode_info is used as the inode number. When only a single -- * volume is mounted, then the DosDirNum is used as the inode -+ * volume is mounted, then the dirEntNum is used as the inode - * number. As this is unique for the complete volume, this should - * enable the NFS exportability of a ncpfs-mounted volume. - */ -@@ -143,7 +157,7 @@ - ncp_info_ino(struct ncp_server *server, struct ncp_inode_info *info) - { - return ncp_single_volume(server) -- ? info->finfo.i.DosDirNum : (ino_t)info; -+ ? info->finfo.i.dirEntNum : (ino_t)info; - } - - static inline int -@@ -177,8 +191,6 @@ - return NULL; - } - -- -- - static int - ncp_dir_read(struct inode *inode, struct file *filp, char *buf, int count) - { -@@ -326,9 +338,12 @@ - c_last_returned_index = 0; - index = 0; - -- for (i = 0; i < c_size; i++) -+ if (!ncp_preserve_case(inode)) - { -- str_lower(c_entry[i].i.entryName); -+ for (i = 0; i < c_size; i++) -+ { -+ str_lower(c_entry[i].i.entryName); -+ } - } - } - } -@@ -345,7 +360,7 @@ - - if (ncp_single_volume(server)) - { -- ino = (ino_t)(entry->i.DosDirNum); -+ ino = (ino_t)(entry->i.dirEntNum); - } - else - { -@@ -652,7 +667,7 @@ - root->finfo.opened = 0; - i->attributes = aDIR; - i->dataStreamSize = 1024; -- i->DosDirNum = 0; -+ i->dirEntNum = i->DosDirNum = 0; - i->volNumber = NCP_NUMBER_OF_VOLUMES+1; /* illegal volnum */ - ncp_date_unix2dos(0, &(i->creationTime), &(i->creationDate)); - ncp_date_unix2dos(0, &(i->modifyTime), &(i->modifyDate)); -@@ -729,7 +744,7 @@ - - do - { -- if ( (result->dir->finfo.i.DosDirNum == dir_info->DosDirNum) -+ if ( (result->dir->finfo.i.dirEntNum == dir_info->dirEntNum) - && (result->dir->finfo.i.volNumber == dir_info->volNumber) - && (strcmp(result->finfo.i.entryName, name) == 0) - /* The root dir is never looked up using this -@@ -757,6 +772,7 @@ - struct ncp_server *server; - struct ncp_inode_info *result_info; - int found_in_cache; -+ int down_case = 0; - char name[len+1]; - - *result = NULL; -@@ -867,20 +883,26 @@ - if (found_in_cache == 0) - { - int res; -- str_upper(name); - - DDPRINTK("ncp_lookup: do_lookup on %s/%s\n", - NCP_ISTRUCT(dir)->entryName, name); - - if (ncp_is_server_root(dir)) - { -+ str_upper(name); -+ down_case = 1; - res = ncp_lookup_volume(server, name, &(finfo.i)); - } - else - { -+ if (!ncp_preserve_case(dir)) -+ { -+ str_upper(name); -+ down_case = 1; -+ } - res = ncp_obtain_info(server, - NCP_ISTRUCT(dir)->volNumber, -- NCP_ISTRUCT(dir)->DosDirNum, -+ NCP_ISTRUCT(dir)->dirEntNum, - name, &(finfo.i)); - } - if (res != 0) -@@ -892,7 +914,11 @@ - } - - finfo.opened = 0; -- str_lower(finfo.i.entryName); -+ -+ if (down_case != 0) -+ { -+ str_lower(finfo.i.entryName); -+ } - - if (!(*result = ncp_iget(dir, &finfo))) - { -@@ -929,7 +955,11 @@ - - strncpy(_name, name, len); - _name[len] = '\0'; -- str_upper(_name); -+ -+ if (!ncp_preserve_case(dir)) -+ { -+ str_upper(_name); -+ } - - lock_super(dir->i_sb); - if (ncp_open_create_file_or_subdir(NCP_SERVER(dir), -@@ -946,7 +976,11 @@ - - ncp_invalid_dir_cache(dir); - -- str_lower(finfo.i.entryName); -+ if (!ncp_preserve_case(dir)) -+ { -+ str_lower(finfo.i.entryName); -+ } -+ - finfo.access = O_RDWR; - - if (!(*result = ncp_iget(dir, &finfo)) < 0) -@@ -980,7 +1014,11 @@ - - strncpy(_name, name, len); - _name[len] = '\0'; -- str_upper(_name); -+ -+ if (!ncp_preserve_case(dir)) -+ { -+ str_upper(_name); -+ } - - if (!dir || !S_ISDIR(dir->i_mode)) - { -@@ -1038,7 +1076,11 @@ - - strncpy(_name, name, len); - _name[len] = '\0'; -- str_upper(_name); -+ -+ if (!ncp_preserve_case(dir)) -+ { -+ str_upper(_name); -+ } - - if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir), - NCP_ISTRUCT(dir), -@@ -1081,7 +1123,11 @@ - { - strncpy(_name, name, len); - _name[len] = '\0'; -- str_upper(_name); -+ -+ if (!ncp_preserve_case(dir)) -+ { -+ str_upper(_name); -+ } - - if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir), - NCP_ISTRUCT(dir), -@@ -1136,11 +1182,19 @@ - - strncpy(_old_name, old_name, old_len); - _old_name[old_len] = '\0'; -- str_upper(_old_name); -+ -+ if (!ncp_preserve_case(old_dir)) -+ { -+ str_upper(_old_name); -+ } - - strncpy(_new_name, new_name, new_len); - _new_name[new_len] = '\0'; -- str_upper(_new_name); -+ -+ if (!ncp_preserve_case(new_dir)) -+ { -+ str_upper(_new_name); -+ } - - res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir), - NCP_ISTRUCT(old_dir), _old_name, -diff -urN 2.0.7/fs/ncpfs/ncplib_kernel.c linux/fs/ncpfs/ncplib_kernel.c ---- 2.0.7/fs/ncpfs/ncplib_kernel.c Thu Apr 18 08:40:28 1996 -+++ linux/fs/ncpfs/ncplib_kernel.c Tue Jul 16 10:52:33 1996 -@@ -190,25 +190,6 @@ - } - - int --ncp_get_volume_number(struct ncp_server *server, const char *name, int *target) --{ -- int result; -- -- ncp_init_request_s(server, 5); -- ncp_add_pstring(server, name); -- -- if ((result = ncp_request(server, 22)) != 0) -- { -- ncp_unlock_server(server); -- return result; -- } -- -- *target = ncp_reply_byte(server, 0); -- ncp_unlock_server(server); -- return 0; --} -- --int - ncp_close_file(struct ncp_server *server, const char *file_id) - { - int result; -@@ -278,8 +259,8 @@ - - ncp_init_request(server); - ncp_add_byte(server, 6); /* subfunction */ -- ncp_add_byte(server, 0); /* dos name space */ -- ncp_add_byte(server, 0); /* dos name space as dest */ -+ ncp_add_byte(server, server->name_space[vol_num]); -+ ncp_add_byte(server, server->name_space[vol_num]); - ncp_add_word(server, 0xff); /* get all */ - ncp_add_dword(server, RIM_ALL); - ncp_add_handle_path(server, vol_num, dir_base, 1, path); -@@ -295,20 +276,57 @@ - return 0; - } - -+static inline int -+ncp_has_os2_namespace(struct ncp_server *server, __u8 volume) -+{ -+ int result; -+ __u8 *namespace; -+ __u16 no_namespaces; -+ -+ ncp_init_request(server); -+ ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */ -+ ncp_add_word(server, 0); -+ ncp_add_byte(server, volume); -+ -+ if ((result = ncp_request(server, 87)) != 0) -+ { -+ ncp_unlock_server(server); -+ return 0; -+ } -+ -+ no_namespaces = ncp_reply_word(server, 0); -+ namespace = ncp_reply_data(server, 2); -+ -+ while (no_namespaces > 0) -+ { -+ DPRINTK("get_namespaces: found %d on %d\n", *namespace,volume); -+ -+ if (*namespace == 4) -+ { -+ DPRINTK("get_namespaces: found OS2\n"); -+ ncp_unlock_server(server); -+ return 1; -+ } -+ namespace += 1; -+ no_namespaces -= 1; -+ } -+ ncp_unlock_server(server); -+ return 0; -+} -+ - int - ncp_lookup_volume(struct ncp_server *server, - char *volname, - struct nw_info_struct *target) - { - int result; -- __u8 vol_num; -- __u32 dir_base; -+ int volnum; - - DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname); - - ncp_init_request(server); - ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */ -- ncp_add_byte(server, 0); /* DOS name space */ -+ ncp_add_byte(server, 0); /* DOS namespace */ - ncp_add_byte(server, 0); /* reserved */ - ncp_add_byte(server, 0); /* reserved */ - ncp_add_byte(server, 0); /* reserved */ -@@ -325,20 +343,19 @@ - return result; - } - -- dir_base = ncp_reply_dword(server, 4); -- vol_num = ncp_reply_byte(server, 8); -+ memset(target, 0, sizeof(*target)); -+ target->DosDirNum = target->dirEntNum = ncp_reply_dword(server, 4); -+ target->volNumber = volnum = ncp_reply_byte(server, 8); - ncp_unlock_server(server); - -- if ((result = ncp_obtain_info(server, vol_num, dir_base, NULL, -- target)) != 0) -- { -- return result; -- } -+ server->name_space[volnum] = ncp_has_os2_namespace(server,volnum)?4:0; - -- DPRINTK("ncp_lookup_volume: attribs = %X\n", target->attributes); -+ DPRINTK("lookup_vol: namespace[%d] = %d\n", -+ volnum, server->name_space[volnum]); - - target->nameLen = strlen(volname); - strcpy(target->entryName, volname); -+ target->attributes = aDIR; - return 0; - } - -@@ -352,14 +369,14 @@ - - ncp_init_request(server); - ncp_add_byte(server, 7); /* subfunction */ -- ncp_add_byte(server, 0); /* dos name space */ -+ ncp_add_byte(server, server->name_space[file->volNumber]); - ncp_add_byte(server, 0); /* reserved */ - ncp_add_word(server, 0x8006); /* search attribs: all */ - - ncp_add_dword(server, info_mask); - ncp_add_mem(server, info, sizeof(*info)); - ncp_add_handle_path(server, file->volNumber, -- file->DosDirNum, 1, NULL); -+ file->dirEntNum, 1, NULL); - - result = ncp_request(server, 87); - ncp_unlock_server(server); -@@ -374,11 +391,11 @@ - - ncp_init_request(server); - ncp_add_byte(server, 8); /* subfunction */ -- ncp_add_byte(server, 0); /* dos name space */ -+ ncp_add_byte(server, server->name_space[dir->volNumber]); - ncp_add_byte(server, 0); /* reserved */ - ncp_add_word(server, 0x8006); /* search attribs: all */ - ncp_add_handle_path(server, dir->volNumber, -- dir->DosDirNum, 1, name); -+ dir->dirEntNum, 1, name); - - result = ncp_request(server, 87); - ncp_unlock_server(server); -@@ -406,15 +423,16 @@ - { - int result; - __u16 search_attribs = 0x0006; -+ __u8 volume = (dir != NULL) ? dir->volNumber : target->i.volNumber; - - if ((create_attributes & aDIR) != 0) - { -- search_attribs |= 0x8000; -- } -+ search_attribs |= 0x8000; -+} - - ncp_init_request(server); - ncp_add_byte(server, 1); /* subfunction */ -- ncp_add_byte(server, 0); /* dos name space */ -+ ncp_add_byte(server, server->name_space[volume]); - ncp_add_byte(server, open_create_mode); - ncp_add_word(server, search_attribs); - ncp_add_dword(server, RIM_ALL); -@@ -425,13 +443,11 @@ - - if (dir != NULL) - { -- ncp_add_handle_path(server, dir->volNumber, -- dir->DosDirNum, 1, name); -+ ncp_add_handle_path(server, volume, dir->dirEntNum, 1, name); - } - else - { -- ncp_add_handle_path(server, -- target->i.volNumber, target->i.DosDirNum, -+ ncp_add_handle_path(server, volume, target->i.dirEntNum, - 1, NULL); - } - -@@ -467,9 +483,9 @@ - - ncp_init_request(server); - ncp_add_byte(server, 2); /* subfunction */ -- ncp_add_byte(server, 0); /* dos name space */ -+ ncp_add_byte(server, server->name_space[dir->volNumber]); - ncp_add_byte(server, 0); /* reserved */ -- ncp_add_handle_path(server, dir->volNumber, dir->DosDirNum, 1, NULL); -+ ncp_add_handle_path(server, dir->volNumber, dir->dirEntNum, 1, NULL); - - if ((result = ncp_request(server, 87)) != 0) - { -@@ -493,7 +509,7 @@ - - ncp_init_request(server); - ncp_add_byte(server, 3); /* subfunction */ -- ncp_add_byte(server, 0); /* dos name space */ -+ ncp_add_byte(server, server->name_space[seq->volNumber]); - ncp_add_byte(server, 0); /* data stream (???) */ - ncp_add_word(server, 0xffff); /* Search attribs */ - ncp_add_dword(server, RIM_ALL); /* return info mask */ -@@ -528,19 +544,19 @@ - - ncp_init_request(server); - ncp_add_byte(server, 4); /* subfunction */ -- ncp_add_byte(server, 0); /* dos name space */ -+ ncp_add_byte(server, server->name_space[old_dir->volNumber]); - ncp_add_byte(server, 1); /* rename flag */ - ncp_add_word(server, 0x8006); /* search attributes */ - - /* source Handle Path */ - ncp_add_byte(server, old_dir->volNumber); -- ncp_add_dword(server, old_dir->DosDirNum); -+ ncp_add_dword(server, old_dir->dirEntNum); - ncp_add_byte(server, 1); - ncp_add_byte(server, 1); /* 1 source component */ - - /* dest Handle Path */ - ncp_add_byte(server, new_dir->volNumber); -- ncp_add_dword(server, new_dir->DosDirNum); -+ ncp_add_dword(server, new_dir->dirEntNum); - ncp_add_byte(server, 1); - ncp_add_byte(server, 1); /* 1 destination component */ - -diff -urN 2.0.7/include/linux/ncp.h linux/include/linux/ncp.h ---- 2.0.7/include/linux/ncp.h Thu Apr 18 08:40:36 1996 -+++ linux/include/linux/ncp.h Tue Jul 16 17:27:45 1996 -@@ -116,6 +116,12 @@ - __u16 update_time; - }; - -+/* Defines for Name Spaces */ -+#define NW_NS_DOS 0 -+#define NW_NS_MAC 1 -+#define NW_NS_NFS 2 -+#define NW_NS_FTAM 3 -+#define NW_NS_OS2 4 - - /* Defines for ReturnInformationMask */ - #define RIM_NAME (0x0001L) -diff -urN 2.0.7/include/linux/ncp_fs_sb.h linux/include/linux/ncp_fs_sb.h ---- 2.0.7/include/linux/ncp_fs_sb.h Thu Apr 18 08:40:36 1996 -+++ linux/include/linux/ncp_fs_sb.h Tue Jul 16 17:35:17 1996 -@@ -21,6 +21,8 @@ - interest for us later, so we store - it completely. */ - -+ __u8 name_space[NCP_NUMBER_OF_VOLUMES]; -+ - struct file *ncp_filp; /* File pointer to ncp socket */ - struct file *wdog_filp; /* File pointer to wdog socket */ - struct file *msg_filp; /* File pointer to message socket */ diff --git a/man/Makefile b/man/Makefile index feb9f2d..e8647b7 100644 --- a/man/Makefile +++ b/man/Makefile @@ -1,5 +1,5 @@ MAN1= slist nprint pqlist nsend pserver ncopy npasswd -MAN1 += nwbols nwboprops nwbpvalues +MAN1 += nwbols nwboprops nwbpvalues nwfsinfo nwuserlist MAN5= nwclient MAN8= ncpmount ncpumount ipx_configure ipx_interface ipx_internal_net \ ipx_route nwmsg diff --git a/man/nwfsinfo.1 b/man/nwfsinfo.1 new file mode 100644 index 0000000..e985f89 --- /dev/null +++ b/man/nwfsinfo.1 @@ -0,0 +1,52 @@ +.TH NWFSINFO 1 07/22/1996 nwfsinfo nwfsinfo +.SH NAME +nwfsinfo \- Print some information about the file server +.SH SYNOPSIS +.B nwfsinfo +[ +.B -h +] [ +.B -S +.I server +] [ +.B -t +] [ +.B -i +] [ +.B -d +] + +.SH DESCRIPTION +.B nwfsinfo +prints some of the information the NetWare servers present without +logging in. The options control what is printed. You should try the +different options to find out what is printed when. + +.SH OPTIONS + +.B -h +.RS 3 +With -h nwfsinfo prints a little help text. +.RE + +.B -S +.I server +.RS 3 +is the name of the server you want to know something about. +.RE + +.B -t +.RS 3 +Print what the file server believes to be the current time. +.RE + +.B -d +.RS 3 +Print the so-called file server description strings. +.RE + +.B -i +.RS 3 +Print the extended file server information such as NetWare version, +maximum connections an others. +.RE diff --git a/man/nwuserlist.1 b/man/nwuserlist.1 new file mode 100644 index 0000000..0991e6e --- /dev/null +++ b/man/nwuserlist.1 @@ -0,0 +1,93 @@ +.TH NWUSERLIST 1 7/22/1996 nwuserlist nwuserlist +.SH NAME +nwuserlist \- List Users logged in at a NetWare server +.SH SYNOPSIS +.B nwuserlist +[ +.B -h +] [ +.B -S +.I server +] [ +.B -U +.I user name +] [ +.B -P +.I password + | +.B -n +] [ +.B -C +] [ +.B -a +] + +.SH DESCRIPTION +.B nwuserlist +lists the users logged in at a NetWare server, together with their +connection number and their login time. + +.B nwuserlist +looks up the file +.I $HOME/.nwclient +to find a file server, a user name and possibly a password. See +nwclient(5) for more information. Please note that the access +permissions of $HOME/.nwclient MUST be 600 for security reasons. + +.SH OPTIONS + +.B -h +.RS 3 +.B -h +is used to print out a short help text. +.RE + +.B -S +.I server +.RS 3 +.B server +is the name of the server you want to use. +.RE + +.B -U +.I user +.RS 3 +.B user +is the user name to use for login. +.RE + +.B -P +.I password +.RS 3 +.B password +is the password to use for login. If neither +.B -n +nor +.B -P +are given, and the user has no open connection to the server, nwuserlist +prompts for a password. +.RE + +.B -n +.RS 3 +.B -n +should be given if no password is required for the login. +.RE + +.B -C +.RS 3 +By default, passwords are converted to uppercase before they are sent +to the server, because most servers require this. You can turn off +this conversion by +.B -C. +.RE + +.B -a +.RS 3 +With option -a the IPX address of the station the user is logged in +from is printed as well. +.RE + +.SH AUTHORS +nwuserlist was written by Volker Lendecke. See the Changes file of ncpfs +for other contributors. diff --git a/ncpfs-2.0.2.lsm b/ncpfs-2.0.3.lsm similarity index 76% rename from ncpfs-2.0.2.lsm rename to ncpfs-2.0.3.lsm index e52a046..f8e2439 100644 --- a/ncpfs-2.0.2.lsm +++ b/ncpfs-2.0.3.lsm @@ -1,7 +1,7 @@ Begin3 Title: ncpfs -Version: 2.0.2 -Entered-date: 18. July 1996 +Version: 2.0.3 +Entered-date: 22. July 1996 Description: With ncpfs you can mount volumes of your netware server under Linux. You can also print to netware print queues and spool netware print queues to the @@ -12,8 +12,8 @@ Keywords: filesystem ncp novell netware printing Author: lendecke@namu01.Num.Math.Uni-Goettingen.de (Volker Lendecke) Maintained-by: lendecke@namu01.Num.Math.Uni-Goettingen.de (Volker Lendecke) Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs -Alternate-site: sunsite.unc.edu:/pub/system/Filesystems/ncpfs - ~124k ncpfs-2.0.2.tgz - ~ 1k ncpfs-2.0.2.lsm +Alternate-site: sunsite.unc.edu:/pub/Linux/system/Filesystems/ncpfs + ~128k ncpfs-2.0.3.tgz + ~ 1k ncpfs-2.0.3.lsm Copying-policy: GPL End diff --git a/util/Makefile b/util/Makefile index 782f54c..f5b1dd7 100644 --- a/util/Makefile +++ b/util/Makefile @@ -5,17 +5,32 @@ USERUTILS = slist pqlist nwfsinfo pserver nprint nsend ncopy npasswd USERUTILS += nwbols nwbocreate nwborm nwboprops USERUTILS += nwbpcreate nwbprm nwbpvalues nwbpadd -USERUTILS += nwgrant nwrevoke +USERUTILS += nwgrant nwrevoke nwuserlist UIDUTILS = ncpmount ncpumount SBINUTILS = nwmsg UTIL_EXECS = $(USERUTILS) $(UIDUTILS) $(SBINUTILS) UTILS = $(addprefix $(INTERM_BINDIR)/,$(UTIL_EXECS)) -#CFLAGS = -Wall $(INCLUDES) $(KERNELD) -g -DNCPFS_VERSION=\"$(VERSION)\" -CFLAGS = -Wall $(INCLUDES) $(KERNELD) -O2 -DNCPFS_VERSION=\"$(VERSION)\" +CFLAGS = -Wall $(INCLUDES) $(KERNELD) -DNCPFS_VERSION=\"$(VERSION)\" CC = gcc +#CFLAGS += -g +CFLAGS += -O2 + +ifeq ($(HAVE_ELF),yes) +PIC_FLAG = -fPIC +NCP_LIB = libncp.so.1.0 +LIB_LINK_COMMAND = gcc -shared -Wl,-soname,libncp.so.1 -o $(NCP_LIB) +INSTALL_LIB = install $(NCP_LIB) -m 755 /lib; \ + ln -sf $(NCP_LIB) /lib/libncp.so.1; \ + ldconfig +export PIC_FLAG +else +NCP_LIB = libncp.a +LIB_LINK_COMMAND = ar r libncp.a +endif + default: make -C .. @@ -28,21 +43,26 @@ install: all do install $(INTERM_BINDIR)/$$i -m 4755 $(BINDIR); done for i in $(SBINUTILS); \ do install $(INTERM_BINDIR)/$$i -m 755 $(SBINDIR); done + $(INSTALL_LIB) -$(UTILS): $(addsuffix .o,$(UTIL_EXECS)) libncp.a +$(UTILS): $(addsuffix .o,$(UTIL_EXECS)) $(NCP_LIB) $(CC) -o $@ $(addsuffix .o,$(notdir $@)) -L. -lncp ncplib.o: ncplib.c ncplib.h ncplib_err.h - $(CC) $(CFLAGS) -finline-functions -c ncplib.c + $(CC) $(CFLAGS) $(PIC_FLAG) -finline-functions -c ncplib.c COM_ERR_CFILES = com_err/com_err.c com_err/error_message.c com_err/et_name.c \ com_err/init_et.c -libncp.a: ncplib.o ncplib_err.o $(COM_ERR_CFILES) +$(NCP_LIB): ncplib.o ncplib_err.o $(COM_ERR_CFILES) make -C com_err - ar r libncp.a ncplib.o ncplib_err.o \ + $(LIB_LINK_COMMAND) ncplib.o ncplib_err.o \ com_err/com_err.o com_err/error_message.o com_err/et_name.o \ com_err/init_et.o + ln -sf libncp.so.1.0 libncp.so.1 + +ncplib_err.o: ncplib_err.h ncplib_err.c + $(CC) $(CFLAGS) $(PIC_FLAG) -c ncplib_err.c ncplib_err.h: ncplib_err.et com_err/compile_et ncplib_err @@ -53,7 +73,7 @@ ncplib_err.c: ncplib_err.et test: test.o ncplib.o $(CC) -o test test.o ncplib.o -ncptest: ncptest.o libncp.a +ncptest: ncptest.o $(NCP_LIB) $(CC) -o ncptest ncptest.o -L. -lncp dep: ncplib_err.h @@ -63,6 +83,7 @@ dep: ncplib_err.h clean: make -C com_err clean rm -f *.o *~ slist test ncptest ncplib_err.[ch] libncp.a + rm -f libncp.so.* mrproper: clean make -C com_err mrproper diff --git a/util/com_err/Makefile b/util/com_err/Makefile index ba2f1a1..271ce59 100644 --- a/util/com_err/Makefile +++ b/util/com_err/Makefile @@ -3,7 +3,7 @@ # OBJECTS = com_err.o error_message.o et_name.o init_et.o -CFLAGS = -Wall -O2 +CFLAGS = -Wall -O2 $(PIC_FLAG) all: $(OBJECTS) diff --git a/util/ncplib.c b/util/ncplib.c index d584d0c..5b20a51 100644 --- a/util/ncplib.c +++ b/util/ncplib.c @@ -1149,6 +1149,11 @@ long ncp_close(struct ncp_conn *conn) { long result; + if (conn == NULL) + { + return 0; + } + if ((result = ncp_do_close(conn)) != 0) { return result; @@ -1292,7 +1297,7 @@ ncp_get_nwc_ent(FILE *nwc) } FILE * -ncp_fopen_nwc(const char *user, const char *mode) +ncp_fopen_nwc(const char *user, const char *mode, long *err) { char path[MAXPATHLEN]; char *home = NULL; @@ -1320,7 +1325,7 @@ ncp_fopen_nwc(const char *user, const char *mode) if ( (home == NULL) || (strlen(home) + sizeof(NWCLIENT) + 2 > sizeof(path))) { - errno = ENAMETOOLONG; + *err = ENAMETOOLONG; return NULL; } @@ -1330,12 +1335,13 @@ ncp_fopen_nwc(const char *user, const char *mode) if (stat(path, &st) != 0) { + *err = errno; return NULL; } if ((st.st_mode & (S_IRWXO | S_IRWXG)) != 0) { - errno = EINVAL; + *err = NCPL_ET_INVALID_MODE; return NULL; } @@ -1371,11 +1377,9 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, } else { - nwc = ncp_fopen_nwc(NULL, NULL); - - if (nwc == NULL) + if ((nwc = ncp_fopen_nwc(NULL, NULL, err)) == NULL) { - *err = NCPL_ET_NO_SPEC; + *err = NCPL_ET_NO_SERVER; return NULL; } @@ -1391,6 +1395,15 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, strcpy(spec.user, nwc_ent->user); } + str_upper(spec.server); + + if (login_necessary == 0) + { + memset(spec.user, 0, sizeof(spec.user)); + memset(spec.password, 0, sizeof(spec.password)); + return &spec; + } + if (user != NULL) { if (strlen(user) >= sizeof(spec.user)) @@ -1401,7 +1414,6 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, strcpy(spec.user, user); } - str_upper(spec.server); str_upper(spec.user); spec.login_type = NCP_BINDERY_USER; @@ -1422,7 +1434,7 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, } else { - if ((nwc = ncp_fopen_nwc(NULL, NULL)) != NULL) + if ((nwc = ncp_fopen_nwc(NULL, NULL, err)) != NULL) { while ((nwc_ent = ncp_get_nwc_ent(nwc)) != NULL) { @@ -1442,15 +1454,10 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, } } - if (login_necessary == 0) - { - memset(spec.user, 0, sizeof(spec.user)); - memset(spec.password, 0, sizeof(spec.password)); - } - if (strlen(spec.user) == 0) { - return &spec; + *err = NCPL_ET_NO_USER; + return NULL; } if ((strlen(spec.password) == 0) && (password == NULL)) @@ -1817,6 +1824,31 @@ ncp_get_file_server_time(struct ncp_conn *conn, time_t *target) return 0; } +long +ncp_get_file_server_information(struct ncp_conn *conn, + struct ncp_file_server_info *target) +{ + long result; + ncp_init_request_s(conn, 17); + if ((result = ncp_request(conn, 23)) != 0) + { + ncp_unlock_conn(conn); + return result; + } + + memcpy(target, ncp_reply_data(conn, 0), sizeof(*target)); + target->MaximumServiceConnections + = htons(target->MaximumServiceConnections); + target->ConnectionsInUse + = htons(target->ConnectionsInUse); + target->MaxConnectionsEverUsed + = htons(target->MaxConnectionsEverUsed); + target->NumberMountedVolumes + = htons(target->NumberMountedVolumes); + ncp_unlock_conn(conn); + return 0; +} + long ncp_get_connlist(struct ncp_conn *conn, __u16 object_type, const char *object_name, @@ -1840,6 +1872,57 @@ ncp_get_connlist(struct ncp_conn *conn, return 0; } +long +ncp_get_stations_logged_info(struct ncp_conn *conn, + __u32 connection, + struct ncp_bindery_object *target, + time_t *login_time) +{ + long result; + ncp_init_request_s(conn, 28); + ncp_add_dword(conn, connection); + + if ((result = ncp_request(conn, 23)) != 0) + { + ncp_unlock_conn(conn); + return result; + } + memset(target, 0, sizeof(*target)); + target->object_id = ntohl(ncp_reply_dword(conn, 0)); + target->object_type = ntohs(ncp_reply_word(conn, 4)); + memcpy(target->object_name, ncp_reply_data(conn, 6), + sizeof(target->object_name)); + *login_time = nw_to_ctime((struct nw_time_buffer *) + ncp_reply_data(conn, 54)); + ncp_unlock_conn(conn); + return 0; +} + +long +ncp_get_internet_address(struct ncp_conn *conn, + __u32 connection, + struct sockaddr_ipx *target, + __u8 *conn_type) +{ + long result; + ncp_init_request_s(conn, 26); + ncp_add_dword(conn, connection); + + if ((result = ncp_request(conn, 23)) != 0) + { + ncp_unlock_conn(conn); + return result; + } + + memset(target, 0, sizeof(*target)); + target->sipx_network = ncp_reply_dword(conn, 0); + memcpy(&(target->sipx_node), ncp_reply_data(conn, 4), 6); + target->sipx_port = ncp_reply_word(conn, 10); + *conn_type = ncp_reply_byte(conn, 12); + ncp_unlock_conn(conn); + return 0; +} + long ncp_send_broadcast(struct ncp_conn *conn, __u8 no_conn, const __u8 *connections, @@ -2196,6 +2279,21 @@ ncp_login_encrypted(struct ncp_conn *conn, return result; } +long +ncp_login_unencrypted(struct ncp_conn *conn, + __u16 object_type, const char *object_name, + const unsigned char *passwd) +{ + long result; + ncp_init_request_s(conn, 20); + ncp_add_word(conn, htons(object_type)); + ncp_add_pstring(conn, object_name); + ncp_add_pstring(conn, passwd); + result = ncp_request(conn, 23); + ncp_unlock_conn(conn); + return result; +} + long ncp_change_login_passwd(struct ncp_conn *conn, const struct ncp_bindery_object *object, @@ -2252,7 +2350,8 @@ ncp_login_object(struct ncp_conn *conn, struct ncp_bindery_object user; if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0) { - return result; + return ncp_login_unencrypted(conn, login_type, username, + password); } if ((result = ncp_get_bindery_object_id(conn, login_type, @@ -2672,7 +2771,7 @@ static void ncp_add_handle_path(struct ncp_conn *conn, __u8 vol_num, __u32 dir_base, int have_dir_base, - char *path) + const char *path) { ncp_add_byte(conn, vol_num); ncp_add_dword(conn, dir_base); @@ -2705,6 +2804,33 @@ ncp_extract_file_info(void *structure, struct nw_info_struct *target) return; } +long +ncp_obtain_file_or_subdir_info(struct ncp_conn *conn, + __u8 source_ns, __u8 target_ns, + __u16 search_attribs, __u32 rim, + __u8 vol, __u32 dirent, const char *path, + struct nw_info_struct *target) +{ + long result; + + ncp_init_request(conn); + ncp_add_byte(conn, 6); + ncp_add_byte(conn, source_ns); + ncp_add_byte(conn, target_ns); + ncp_add_word(conn, search_attribs); + ncp_add_dword(conn, rim); + ncp_add_handle_path(conn, vol, dirent, 1, path); + + if ((result = ncp_request(conn, 87)) != 0) + { + ncp_unlock_conn(conn); + return result; + } + ncp_extract_file_info(ncp_reply_data(conn, 0), target); + ncp_unlock_conn(conn); + return 0; +} + long ncp_do_lookup(struct ncp_conn *conn, struct nw_info_struct *dir, @@ -2893,7 +3019,7 @@ ncp_initialize_search(struct ncp_conn *conn, return result; } - memcpy(&(target->s), ncp_reply_data(conn, 0), sizeof(target->s)); + memcpy(&(target->s), ncp_reply_data(conn, 0), 9); target->namespace = namespace; ncp_unlock_conn(conn); diff --git a/util/ncplib.h b/util/ncplib.h index d4fe7bb..1586e86 100644 --- a/util/ncplib.h +++ b/util/ncplib.h @@ -155,11 +155,48 @@ ncp_get_file_server_description_strings(struct ncp_conn *conn, long ncp_get_file_server_time(struct ncp_conn *conn, time_t *target); +struct ncp_file_server_info { + __u8 ServerName[48] __attribute__ ((packed)); + __u8 FileServiceVersion __attribute__ ((packed)); + __u8 FileServiceSubVersion __attribute__ ((packed)); + __u16 MaximumServiceConnections __attribute__ ((packed)); + __u16 ConnectionsInUse __attribute__ ((packed)); + __u16 NumberMountedVolumes __attribute__ ((packed)); + __u8 Revision __attribute__ ((packed)); + __u8 SFTLevel __attribute__ ((packed)); + __u8 TTSLevel __attribute__ ((packed)); + __u16 MaxConnectionsEverUsed __attribute__ ((packed)); + __u8 AccountVersion __attribute__ ((packed)); + __u8 VAPVersion __attribute__ ((packed)); + __u8 QueueVersion __attribute__ ((packed)); + __u8 PrintVersion __attribute__ ((packed)); + __u8 VirtualConsoleVersion __attribute__ ((packed)); + __u8 RestrictionLevel __attribute__ ((packed)); + __u8 InternetBridge __attribute__ ((packed)); + __u8 Reserved[60] __attribute__ ((packed)); +}; + +long +ncp_get_file_server_information(struct ncp_conn *conn, + struct ncp_file_server_info *target); + long ncp_get_connlist(struct ncp_conn *conn, __u16 object_type, const char *object_name, int *returned_no, __u8 conn_numbers[256]); +long +ncp_get_stations_logged_info(struct ncp_conn *conn, + __u32 connection, + struct ncp_bindery_object *target, + time_t *login_time); + +long +ncp_get_internet_address(struct ncp_conn *conn, + __u32 connection, + struct sockaddr_ipx *target, + __u8 *conn_type); + long ncp_send_broadcast(struct ncp_conn *conn, __u8 no_conn, const __u8 *connections, @@ -265,6 +302,11 @@ ncp_login_encrypted(struct ncp_conn *conn, const unsigned char *key, const unsigned char *passwd); +long +ncp_login_unencrypted(struct ncp_conn *conn, + __u16 object_type, const char *object_name, + const unsigned char *passwd); + long ncp_change_login_passwd(struct ncp_conn *conn, const struct ncp_bindery_object *object, @@ -373,6 +415,14 @@ ncp_copy_file(struct ncp_conn *conn, __u32 count, __u32 *copied_count); +long +ncp_obtain_file_or_subdir_info(struct ncp_conn *conn, + __u8 source_ns, __u8 target_ns, + __u16 search_attribs, __u32 rim, + __u8 vol, __u32 dirent, const char *path, + struct nw_info_struct *target); + + long ncp_do_lookup(struct ncp_conn *conn, struct nw_info_struct *dir, diff --git a/util/ncplib_err.et b/util/ncplib_err.et index f0d5bb6..5deeca4 100644 --- a/util/ncplib_err.et +++ b/util/ncplib_err.et @@ -3,6 +3,9 @@ error_table NCPL ec NCPL_ET_NO_SERVER, "No server found" +ec NCPL_ET_NO_USER, + "No username found" + ec NCPL_ET_HOST_UNKNOWN, "Server Unknown" @@ -19,7 +22,7 @@ ec NCPL_ET_NO_SPEC, "Could not find valid connection spec" ec NCPL_ET_INVALID_MODE, - "$HOME/.nwclient has invalid mode" + "$HOME/.nwclient has invalid mode, must be 600" ec NCPL_ET_LOGIN_DENIED, "Login denied" diff --git a/util/ncpmount.c b/util/ncpmount.c index eafb928..b05b1a9 100644 --- a/util/ncpmount.c +++ b/util/ncpmount.c @@ -201,7 +201,7 @@ main(int argc, char *argv[]) upcase_password = 1; - while ((opt = getopt (argc, argv, "CS:U:c:u:g:f:d:P:nhvV:t:r:")) + while ((opt = getopt (argc, argv, "CS:U:c:u:g:f:d:P:nh?vV:t:r:")) != EOF) { switch (opt) @@ -310,6 +310,7 @@ main(int argc, char *argv[]) data.retry_count = atoi(optarg); break; case 'h': + case '?': help(); exit(1); case 'v': diff --git a/util/ncptest.c b/util/ncptest.c index 75488c4..8533633 100644 --- a/util/ncptest.c +++ b/util/ncptest.c @@ -131,6 +131,58 @@ test_change(struct ncp_conn *conn) return 0; } +void +test_readdir(struct ncp_conn *conn) +{ + struct nw_info_struct sys; + struct nw_info_struct blub; + struct ncp_search_seq seq; + struct nw_info_struct entry; + + if (ncp_do_lookup(conn, NULL, "SYS", &sys) != 0) + { + printf("lookup error\n"); + return; + } + if (ncp_do_lookup(conn, &sys, "BLUB", &blub) != 0) + { + printf("lookup blub error\n"); + return; + } + + if (ncp_initialize_search(conn, &sys, 0, &seq) != 0) + { + printf("init error\n"); + return; + } + + while (ncp_search_for_file_or_subdir(conn, &seq, &entry) == 0) + { + struct nw_info_struct nfs; + printf("found: %s\n", entry.entryName); + if (ncp_obtain_file_or_subdir_info(conn, NW_NS_DOS, NW_NS_NFS, + 0x8006, RIM_ALL, + entry.volNumber, + entry.DosDirNum, + NULL, + &nfs) == 0) + { + printf("nfs name: %s\n", nfs.entryName); + } + if (ncp_obtain_file_or_subdir_info(conn, NW_NS_DOS, NW_NS_OS2, + 0x8006, RIM_ALL, + entry.volNumber, + entry.DosDirNum, + NULL, + &nfs) == 0) + { + printf("os2 name: %s\n", nfs.entryName); + } + } + +} + + int main(int argc, char *argv[]) { @@ -143,7 +195,7 @@ main(int argc, char *argv[]) return 1; } - test_change(conn); + test_readdir(conn); ncp_close(conn); return 0; } diff --git a/util/npasswd.c b/util/npasswd.c index 0f2e551..edcf1ea 100644 --- a/util/npasswd.c +++ b/util/npasswd.c @@ -53,7 +53,7 @@ main(int argc, char *argv[]) progname = argv[0]; - while ((opt = getopt(argc, argv, "hS:U:t:")) != EOF) + while ((opt = getopt(argc, argv, "h?S:U:t:")) != EOF) { switch(opt) { case 'S': @@ -66,6 +66,7 @@ main(int argc, char *argv[]) object_type = atoi(optarg); break; case 'h': + case '?': help(); exit(1); default: diff --git a/util/nprint.c b/util/nprint.c index 8c6a806..a4ab053 100644 --- a/util/nprint.c +++ b/util/nprint.c @@ -57,7 +57,7 @@ main(int argc, char *argv[]) if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { - com_err(argv[0], err, "in ncp_initialize"); + com_err(argv[0], err, "when initializing connection"); exit(1); } @@ -78,10 +78,11 @@ main(int argc, char *argv[]) pj.Rows = htons(80); strcpy(pj.FnameHeader, "stdin"); - while ((opt = getopt(argc, argv, "hq:d:p:b:f:l:r:c:t:F:TN"))!=EOF) + while ((opt = getopt(argc, argv, "h?q:d:p:b:f:l:r:c:t:F:TN"))!=EOF) { switch (opt) { case 'h': + case '?': help(); ncp_close(conn); exit(1); diff --git a/util/nsend.c b/util/nsend.c index 14c5828..9a58fd2 100644 --- a/util/nsend.c +++ b/util/nsend.c @@ -25,7 +25,7 @@ main(int argc, char **argv) if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { - com_err(argv[0], err, "in ncp_initialize"); + com_err(argv[0], err, "when initializing"); exit(1); } diff --git a/util/nwbocreate.c b/util/nwbocreate.c index a3f3309..8f006b8 100644 --- a/util/nwbocreate.c +++ b/util/nwbocreate.c @@ -83,11 +83,11 @@ main(int argc, char *argv[]) if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { - com_err(argv[0], err, "in ncp_initialize"); + com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "ho:t:r:w:")) != EOF) + while ((opt = getopt(argc, argv, "h?o:t:r:w:")) != EOF) { switch(opt) { case 'o': @@ -122,6 +122,7 @@ main(int argc, char *argv[]) } break; case 'h': + case '?': help(); goto finished; default: diff --git a/util/nwbols.c b/util/nwbols.c index 7f0459d..f55d759 100644 --- a/util/nwbols.c +++ b/util/nwbols.c @@ -59,14 +59,15 @@ main(int argc, char **argv) if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { - com_err(argv[0], err, "in ncp_initialize"); + com_err(argv[0], err, "when initializing"); return 1; } - while ((opt = getopt(argc, argv, "hvt:")) != EOF) + while ((opt = getopt(argc, argv, "h?vt:")) != EOF) { switch(opt) { case 'h': + case '?': help(); exit(1); case 't': diff --git a/util/nwboprops.c b/util/nwboprops.c index a02db3e..c60a9b5 100644 --- a/util/nwboprops.c +++ b/util/nwboprops.c @@ -56,11 +56,11 @@ main(int argc, char *argv[]) if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { - com_err(argv[0], err, "in ncp_initialize"); + com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "ho:t:v")) != EOF) + while ((opt = getopt(argc, argv, "h?o:t:v")) != EOF) { switch(opt) { case 'o': @@ -74,6 +74,7 @@ main(int argc, char *argv[]) verbose = 1; break; case 'h': + case '?': help(); goto finished; default: diff --git a/util/nwborm.c b/util/nwborm.c index 7087a96..2da2fa0 100644 --- a/util/nwborm.c +++ b/util/nwborm.c @@ -53,11 +53,11 @@ main(int argc, char *argv[]) if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { - com_err(argv[0], err, "in ncp_initialize"); + com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "ho:t:")) != EOF) + while ((opt = getopt(argc, argv, "h?o:t:")) != EOF) { switch(opt) { case 'o': @@ -68,6 +68,7 @@ main(int argc, char *argv[]) object_type = atoi(optarg); break; case 'h': + case '?': help(); goto finished; default: diff --git a/util/nwbpadd.c b/util/nwbpadd.c index 4aec345..70d5ea7 100644 --- a/util/nwbpadd.c +++ b/util/nwbpadd.c @@ -63,11 +63,11 @@ main(int argc, char *argv[]) if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { - com_err(argv[0], err, "in ncp_initialize"); + com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "ho:t:p:v:")) != EOF) + while ((opt = getopt(argc, argv, "h?o:t:p:v:")) != EOF) { switch(opt) { case 'o': @@ -91,6 +91,7 @@ main(int argc, char *argv[]) value = optarg; break; case 'h': + case '?': help(); goto finished; default: diff --git a/util/nwbpcreate.c b/util/nwbpcreate.c index 641ef58..740cd06 100644 --- a/util/nwbpcreate.c +++ b/util/nwbpcreate.c @@ -87,11 +87,11 @@ main(int argc, char *argv[]) if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { - com_err(argv[0], err, "in ncp_initialize"); + com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "ho:t:p:sr:w:")) != EOF) + while ((opt = getopt(argc, argv, "h?o:t:p:sr:w:")) != EOF) { switch(opt) { case 'o': @@ -139,6 +139,7 @@ main(int argc, char *argv[]) } break; case 'h': + case '?': help(); goto finished; default: diff --git a/util/nwbprm.c b/util/nwbprm.c index 3c85356..116a0ed 100644 --- a/util/nwbprm.c +++ b/util/nwbprm.c @@ -55,11 +55,11 @@ main(int argc, char *argv[]) if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { - com_err(argv[0], err, "in ncp_initialize"); + com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "ho:t:p:")) != EOF) + while ((opt = getopt(argc, argv, "h?o:t:p:")) != EOF) { switch(opt) { case 'o': @@ -80,6 +80,7 @@ main(int argc, char *argv[]) str_upper(property_name); break; case 'h': + case '?': help(); goto finished; default: diff --git a/util/nwbpvalues.c b/util/nwbpvalues.c index 4911ad7..3b77d40 100644 --- a/util/nwbpvalues.c +++ b/util/nwbpvalues.c @@ -65,11 +65,11 @@ main(int argc, char *argv[]) if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { - com_err(argv[0], err, "in ncp_initialize"); + com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "ho:t:p:v")) != EOF) + while ((opt = getopt(argc, argv, "h?o:t:p:v")) != EOF) { switch(opt) { case 'o': @@ -93,6 +93,7 @@ main(int argc, char *argv[]) verbose = 1; break; case 'h': + case '?': help(); goto finished; default: diff --git a/util/nwfsinfo.c b/util/nwfsinfo.c index e820715..1c01685 100644 --- a/util/nwfsinfo.c +++ b/util/nwfsinfo.c @@ -11,6 +11,64 @@ #include #include "ncplib.h" +static char *progname; + +static void +usage(void) +{ + fprintf(stderr, "usage: %s [pattern]\n", progname); +} + +static void +help(void) +{ + printf("\n"); + printf("usage: %s [options]\n", progname); + printf("\n" + "-h Print this help text\n" + "-S server Server name to be used\n" + "\n" + "-d Print Description Strings\n" + "-t Print File Server's time\n" + "-i Print File Server Information\n" + "\n"); +} + +static void +print_info(struct ncp_file_server_info *info) +{ + printf ( "\n" ) ; + printf ( "Fileservername %-48.48s\n" , info->ServerName ) ; + printf ( "\n" ) ; + printf ( "Version %d.%d Revision %c\n" , + info->FileServiceVersion , info->FileServiceSubVersion, + info->Revision + 'A' ) ; + printf ( "Max. Connections %d\n" , + info->MaximumServiceConnections ) ; + printf ( "currently in use %d\n" , + info->ConnectionsInUse ) ; + printf ( "peak connections %d\n" , + info->MaxConnectionsEverUsed ) ; + printf ( "Max. Volumes %d\n" , + info->NumberMountedVolumes ) ; + printf ( "SFTLevel %d\n" , + info->SFTLevel ) ; + printf ( "TTSLevel %d\n" , + info->TTSLevel ) ; + printf ( "Accountversion %d\n" , + info->AccountVersion ) ; + printf ( "Queueversion %d\n" , + info->QueueVersion ) ; + printf ( "Printversion %d\n" , + info->PrintVersion ) ; + printf ( "Virt.Consolvers. %d\n" , + info->VirtualConsoleVersion ) ; + printf ( "RestrictionLevel %d\n" , + info->RestrictionLevel ) ; + printf("\n"); + return; +} + int main(int argc, char **argv) { @@ -18,16 +76,22 @@ main(int argc, char **argv) int opt; long err; + progname = argv[0]; + if ((conn = ncp_initialize(&argc, argv, 0, &err)) == NULL) { - com_err(argv[0], err, "in ncp_initialize"); + com_err(argv[0], err, "when initializing"); return 1; } - while ((opt = getopt(argc, argv, "dt")) != EOF) + while ((opt = getopt(argc, argv, "h?dti")) != EOF) { switch(opt) { + case 'h': + case '?': + help(); + break; case 'd': { char strings[512]; @@ -68,12 +132,26 @@ main(int argc, char **argv) fputs(ctime(&t), stdout); break; } - default: - printf("unknown option: %c\n", opt); + case 'i': + { + struct ncp_file_server_info info; + if (ncp_get_file_server_information(conn, &info) != 0) + { + perror("Could not get server information"); + ncp_close(conn); + return 1; + } + print_info(&info); break; } + + default: + usage(); + goto finished; + } } - + + finished: ncp_close(conn); return 0; } diff --git a/util/nwgrant.c b/util/nwgrant.c index 9f07752..98a0576 100644 --- a/util/nwgrant.c +++ b/util/nwgrant.c @@ -57,11 +57,11 @@ main(int argc, char *argv[]) if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { - com_err(argv[0], err, "in ncp_initialize"); + com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "ho:t:r:")) != EOF) + while ((opt = getopt(argc, argv, "h?o:t:r:")) != EOF) { switch(opt) { case 'o': @@ -75,6 +75,7 @@ main(int argc, char *argv[]) rights = strtol(optarg, NULL, 16); break; case 'h': + case '?': help(); goto finished; default: diff --git a/util/nwrevoke.c b/util/nwrevoke.c index 0147fb9..f37a400 100644 --- a/util/nwrevoke.c +++ b/util/nwrevoke.c @@ -55,11 +55,11 @@ main(int argc, char *argv[]) if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { - com_err(argv[0], err, "in ncp_initialize"); + com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "ho:t:")) != EOF) + while ((opt = getopt(argc, argv, "h?o:t:")) != EOF) { switch(opt) { case 'o': @@ -70,6 +70,7 @@ main(int argc, char *argv[]) object_type = atoi(optarg); break; case 'h': + case '?': help(); goto finished; default: diff --git a/util/nwuserlist.c b/util/nwuserlist.c new file mode 100644 index 0000000..bca22e2 --- /dev/null +++ b/util/nwuserlist.c @@ -0,0 +1,143 @@ +/* + * nwfsinfo.c + * + * Print the info strings of a server, maybe sometime more. + * + * Copyright (C) 1996 by Volker Lendecke + * + */ + +#include +#include +#include "ncplib.h" + +static char *progname; + +static void +usage(void) +{ + fprintf(stderr, "usage: %s [pattern]\n", progname); +} + +static void +str_trim_right(char *s, char c) +{ + int len = strlen(s) - 1; + + while ((len > 0) && (s[len] == c)) + { + s[len] = '\0'; + len -= 1; + } +} + +static void +help(void) +{ + printf("\n"); + printf("usage: %s [options]\n", progname); + printf("\n" + "-h Print this help text\n" + "-S server Server name to be used\n" + "-a Print Station's addr\n" + "\n"); +} + +int +main(int argc, char **argv) +{ + struct ncp_conn *conn; + int opt; + long err; + struct ncp_file_server_info info; + struct ncp_bindery_object user; + time_t login_time; + int i; + int print_addr = 0; + + progname = argv[0]; + + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { + com_err(argv[0], err, "when initializing"); + goto finished; + } + + while ((opt = getopt(argc, argv, "h?a")) != EOF) + { + switch(opt) + { + case 'h': + case '?': + help(); + goto finished; + case 'a': + print_addr = 1; + break; + default: + usage(); + goto finished; + } + } + + if (ncp_get_file_server_information(conn, &info) != 0) + { + perror("Could not get server information"); + ncp_close(conn); + return 1; + } + + if (isatty(1)) + { + if (print_addr == 0) + { + printf("\n%-6s%-21s%-12s\n" + "---------------------------------------------" + "------\n", + "Conn", + "User name", + "Login time"); + } + else + { + 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'; + if (ncp_get_stations_logged_info(conn, i, &user, + &login_time) != 0) + { + continue; + } + memcpy(name, user.object_name, 48); + str_trim_right(name, ' '); + printf("%4d: %-20s ", i, name); + + if (print_addr != 0) + { + struct sockaddr_ipx addr; + __u8 conn_type; + + memset(&addr, 0, sizeof(addr)); + ncp_get_internet_address(conn, i, &addr, &conn_type); + ipx_print_saddr(&addr); + printf(" "); + } + + printf("%s", ctime(&login_time)); + } + + finished: + ncp_close(conn); + return 0; +} diff --git a/util/pqlist.c b/util/pqlist.c index 4c44728..dd5215c 100644 --- a/util/pqlist.c +++ b/util/pqlist.c @@ -26,7 +26,7 @@ main(int argc, char **argv) if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { - com_err(argv[0], err, "in ncp_initialize"); + com_err(argv[0], err, "when initializing"); return 1; } diff --git a/util/pserver.c b/util/pserver.c index 048aeb9..a80b389 100644 --- a/util/pserver.c +++ b/util/pserver.c @@ -150,7 +150,7 @@ main(int argc, char *argv[]) if ((conn = ncp_initialize_as(&argc, argv, 1, NCP_BINDERY_PSERVER, &err)) == NULL) { - com_err(argv[0], err, "in ncp_initialize"); + com_err(argv[0], err, "when initializing"); return 1; }