From f88460b2e67a859a52c4d7374bd20b8a4cf43623 Mon Sep 17 00:00:00 2001 From: ncpfs archive import Date: Tue, 28 Apr 2026 20:39:58 +0200 Subject: [PATCH] Import ncpfs 2.0.9 --- .downloads/ncpfs-2.0.9.tgz | Bin 0 -> 158702 bytes Changes | 5 + Makefile | 6 +- TODO | 12 - include/com_err.h | 28 +- include/ipxlib.h | 69 +- include/ncplib.h | 694 ++++++++------- lib/Makefile | 2 +- lib/ncplib.c | 1145 +++++++++++------------- lib/nwcrypt.c | 154 ++-- man/nwpasswd.1 | 15 +- man/nwvolinfo.1 | 100 +++ ncpfs-2.0.8.lsm => ncpfs-2.0.9.lsm | 8 +- patches/README | 13 + patches/linux-2.1.26.diff | 35 + patches/lockup-2.0.28.diff | 44 + sutil/ncplib.c | 702 +++++++-------- sutil/ncplib.h | 84 ++ sutil/ncpmount.c | 434 +++++---- sutil/ncpumount.c | 225 +++-- sutil/nwcrypt.c | 93 +- sutil/nwsfind.c | 20 +- util/Makefile | 2 +- util/ncopy.c | 1337 +++++++++++++++------------- util/ncptest.c | 30 +- util/nprint.c | 97 +- util/nsend.c | 7 +- util/nwauth.c | 19 +- util/nwbocreate.c | 31 +- util/nwbols.c | 32 +- util/nwboprops.c | 27 +- util/nwborm.c | 27 +- util/nwbpadd.c | 45 +- util/nwbpcreate.c | 34 +- util/nwbprm.c | 30 +- util/nwbpset.c | 51 +- util/nwbpvalues.c | 238 ++--- util/nwfsinfo.c | 148 ++- util/nwfstime.c | 24 +- util/nwgrant.c | 29 +- util/nwmsg.c | 55 +- util/nwpasswd.c | 69 +- util/nwrevoke.c | 26 +- util/nwrights.c | 41 +- util/nwtrustee.c | 159 ++++ util/nwuserlist.c | 19 +- util/nwvolinfo.c | 119 +++ util/pqlist.c | 7 +- util/pserver.c | 93 +- util/slist.c | 8 +- 50 files changed, 3616 insertions(+), 3076 deletions(-) create mode 100644 .downloads/ncpfs-2.0.9.tgz delete mode 100644 TODO create mode 100644 man/nwvolinfo.1 rename ncpfs-2.0.8.lsm => ncpfs-2.0.9.lsm (83%) create mode 100644 patches/README create mode 100644 patches/linux-2.1.26.diff create mode 100644 patches/lockup-2.0.28.diff create mode 100644 util/nwtrustee.c create mode 100644 util/nwvolinfo.c diff --git a/.downloads/ncpfs-2.0.9.tgz b/.downloads/ncpfs-2.0.9.tgz new file mode 100644 index 0000000000000000000000000000000000000000..767ddd7b36b7db3a674ad7fa7ae7e003d6939333 GIT binary patch literal 158702 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
Od6x|MuD04sL_v%VB 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 BF(v>2 literal 0 HcmV?d00001 diff --git a/Changes b/Changes index 7350721..3cd8536 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,11 @@ 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.8 -> ncpfs-2.0.9 +- Added patches directory +- Added nwvolinfo and nwtrustee. Thanks to Jacek Stepniewski +- nwpasswd can change other's passwords. Thanks to Martin Stover. + ncpfs-2.0.7 -> ncpfs-2.0.8 - Fixed util/Makefile for easier optimization handling. Thanks to Rik Faith for this one diff --git a/Makefile b/Makefile index 7a74f76..8cf8201 100644 --- a/Makefile +++ b/Makefile @@ -2,11 +2,11 @@ # Makefile for the linux ncp-filesystem routines. # -VERSION = 2.0.8 +VERSION = 2.0.9 # If you are using kerneld to autoload ncp support, # uncomment this (kerneld is in linux since about 1.3.57): -#KERNELD = -DHAVE_KERNELD +KERNELD = -DHAVE_KERNELD # If your system is ELF, either also do a 'make install', or append the util/ # directory where the dynamic library resides to the environment @@ -29,7 +29,7 @@ INCLUDES += -I$(TOPDIR)/kernel-1.2 endif COPT = -O2 -# COPT += -g +COPT += -g CFLAGS = $(COPT) -Wall $(INCLUDES) $(KERNELD) -DNCPFS_VERSION=\"$(VERSION)\" export INCLUDES BINDIR SBINDIR KERNELD VERSION HAVE_ELF CFLAGS diff --git a/TODO b/TODO deleted file mode 100644 index b5e4d5c..0000000 --- a/TODO +++ /dev/null @@ -1,12 +0,0 @@ -Here's a list of things I want to do. Feel free to send suggestions, -or even help me ;-). - -- do rtt estimation, like tcp does. - -- Do better connection management. I imagine to create a ncpd. - -- When ncpd is done, one can think about mounting several volumes over - a single NCP connection. This should make the trade-off mentioned in - ncpmount.8 unnecessary. - -- Do some kind of mapping of NCP uid's to unix uid's diff --git a/include/com_err.h b/include/com_err.h index f28dce8..8e8ad11 100644 --- a/include/com_err.h +++ b/include/com_err.h @@ -16,25 +16,25 @@ typedef long errcode_t; #include /* ANSI C -- use prototypes etc */ -void com_err (const char *, long, const char *, ...); -void com_err_va (const char *whoami, errcode_t code, const char *fmt, - va_list args); -char const *error_message (long); +void com_err(const char *, long, const char *,...); +void com_err_va(const char *whoami, errcode_t code, const char *fmt, + va_list args); +char const *error_message(long); extern void (*com_err_hook) (const char *, long, const char *, va_list); -void (*set_com_err_hook (void (*) (const char *, long, const char *, va_list))) - (const char *, long, const char *, va_list); -void (*reset_com_err_hook (void)) (const char *, long, const char *, va_list); -int init_error_table(const char * const *msgs, int base, int count); +void (*set_com_err_hook(void (*)(const char *, long, const char *, va_list))) + (const char *, long, const char *, va_list); +void (*reset_com_err_hook(void)) (const char *, long, const char *, va_list); +int init_error_table(const char *const *msgs, int base, int count); #else /* no prototypes */ -void com_err (); -void com_err_va (); -char *error_message (); +void com_err(); +void com_err_va(); +char *error_message(); extern void (*com_err_hook) (); -void (*set_com_err_hook ()) (); -void (*reset_com_err_hook ()) (); +void (*set_com_err_hook()) (); +void (*reset_com_err_hook()) (); int init_error_table(); #endif #define __COM_ERR_H -#endif /* ! defined(__COM_ERR_H) */ +#endif /* ! defined(__COM_ERR_H) */ diff --git a/include/ipxlib.h b/include/ipxlib.h index ac243b0..bf16bf4 100644 --- a/include/ipxlib.h +++ b/include/ipxlib.h @@ -15,9 +15,9 @@ #include #include -typedef unsigned long IPXNet; +typedef unsigned long IPXNet; typedef unsigned short IPXPort; -typedef unsigned char IPXNode[IPX_NODE_LEN]; +typedef unsigned char IPXNode[IPX_NODE_LEN]; #define IPX_USER_PTYPE (0x00) #define IPX_RIP_PTYPE (0x01) @@ -33,30 +33,35 @@ typedef unsigned char IPXNode[IPX_NODE_LEN]; #define IPX_SAP_FILE_SERVER (0x0004) -struct sap_query { - unsigned short query_type; /* net order */ - unsigned short server_type; /* net order */ +struct sap_query +{ + unsigned short query_type; /* net order */ + unsigned short server_type; /* net order */ }; -struct sap_server_ident { - unsigned short server_type __attribute__ ((packed)); - char server_name[48] __attribute__ ((packed)); - IPXNet server_network __attribute__ ((packed)); - IPXNode server_node __attribute__ ((packed)); - IPXPort server_port __attribute__ ((packed)); - unsigned short intermediate_network __attribute__ ((packed)); +struct sap_server_ident +{ + unsigned short server_type __attribute__((packed)); + char server_name[48] __attribute__((packed)); + IPXNet server_network __attribute__((packed)); + IPXNode server_node __attribute__((packed)); + IPXPort server_port __attribute__((packed)); + unsigned short intermediate_network __attribute__((packed)); }; - + #define IPX_RIP_REQUEST (0x1) #define IPX_RIP_RESPONSE (0x2) -struct ipx_rip_packet { - __u16 operation __attribute__ ((packed)); - struct ipx_rt_def { - __u32 network __attribute__ ((packed)); - __u16 hops __attribute__ ((packed)); - __u16 ticks __attribute__ ((packed)); - } rt[1] __attribute__ ((packed)); +struct ipx_rip_packet +{ + __u16 operation __attribute__((packed)); + struct ipx_rt_def + { + __u32 network __attribute__((packed)); + __u16 hops __attribute__((packed)); + __u16 ticks __attribute__((packed)); + } + rt[1] __attribute__((packed)); }; #define IPX_BROADCAST_NODE ("\xff\xff\xff\xff\xff\xff") @@ -68,26 +73,26 @@ struct ipx_rip_packet { #endif void -ipx_print_node(IPXNode node); + ipx_print_node(IPXNode node); void -ipx_print_network(IPXNet net); + ipx_print_network(IPXNet net); void -ipx_print_port(IPXPort port); + ipx_print_port(IPXPort port); void -ipx_print_saddr(struct sockaddr_ipx* sipx); + ipx_print_saddr(struct sockaddr_ipx *sipx); void -ipx_fprint_node(FILE *file, IPXNode node); + ipx_fprint_node(FILE * file, IPXNode node); void -ipx_fprint_network(FILE *file, IPXNet net); + ipx_fprint_network(FILE * file, IPXNet net); void -ipx_fprint_port(FILE *file, IPXPort port); + ipx_fprint_port(FILE * file, IPXPort port); void -ipx_fprint_saddr(FILE *file, struct sockaddr_ipx* sipx); + ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx); int -ipx_sscanf_node(char *buf, unsigned char node[IPX_NODE_LEN]); + ipx_sscanf_node(char *buf, unsigned char node[IPX_NODE_LEN]); void -ipx_assign_node(IPXNode dest, IPXNode src); + ipx_assign_node(IPXNode dest, IPXNode src); int -ipx_node_equal(IPXNode n1,IPXNode n2); + ipx_node_equal(IPXNode n1, IPXNode n2); -#endif /* _IPXLIB_H */ +#endif /* _IPXLIB_H */ diff --git a/include/ncplib.h b/include/ncplib.h index ebc637b..a73c038 100644 --- a/include/ncplib.h +++ b/include/ncplib.h @@ -19,26 +19,115 @@ #include "ipxlib.h" #include "com_err.h" +typedef __u8 byte; +typedef __u16 word; +typedef __u32 dword; + #ifndef memzero #include #define memzero(object) memset(&(object), 0, sizeof(object)) #endif -void -str_upper(char *name); +#define BVAL(buf,pos) (((__u8 *)(buf))[pos]) +#define PVAL(buf,pos) ((unsigned)BVAL(buf,pos)) +#define BSET(buf,pos,val) (BVAL(buf,pos) = (val)) -enum connect_state { +static inline word +WVAL_HL(__u8 * buf, int pos) +{ + return PVAL(buf, pos) << 8 | PVAL(buf, pos + 1); +} +static inline dword +DVAL_HL(__u8 * buf, int pos) +{ + return WVAL_HL(buf, pos) << 16 | WVAL_HL(buf, pos + 2); +} +static inline void +WSET_HL(__u8 * buf, int pos, word val) +{ + BSET(buf, pos, val >> 8); + BSET(buf, pos + 1, val & 0xff); +} +static inline void +DSET_HL(__u8 * buf, int pos, dword val) +{ + WSET_HL(buf, pos, val >> 16); + WSET_HL(buf, pos + 2, val & 0xffff); +} + + +/* we know that the 386 can handle misalignment and has the "right" + byteorder */ +#if defined(__i386__) + +static inline word +WVAL_LH(__u8 * buf, int pos) +{ + return *((word *) (buf + pos)); +} +static inline dword +DVAL_LH(__u8 * buf, int pos) +{ + return *((dword *) (buf + pos)); +} +static inline void +WSET_LH(__u8 * buf, int pos, word val) +{ + *((word *) (buf + pos)) = val; +} +static inline void +DSET_LH(__u8 * buf, int pos, dword val) +{ + *((dword *) (buf + pos)) = val; +} + +#else + +static inline word +WVAL_LH(__u8 * buf, int pos) +{ + return PVAL(buf, pos) | PVAL(buf, pos + 1) << 8; +} +static inline dword +DVAL_LH(__u8 * buf, int pos) +{ + return WVAL_LH(buf, pos) | WVAL_LH(buf, pos + 2) << 16; +} +static inline void +WSET_LH(__u8 * buf, int pos, word val) +{ + BSET(buf, pos, val & 0xff); + BSET(buf, pos + 1, val >> 8); +} +static inline void +DSET_LH(__u8 * buf, int pos, dword val) +{ + WSET_LH(buf, pos, val & 0xffff); + WSET_LH(buf, pos + 2, val >> 16); +} + +#endif + + + + +void + str_upper(char *name); + +enum connect_state +{ NOT_CONNECTED = 0, CONN_PERMANENT, CONN_TEMPORARY }; -struct ncp_conn { +struct ncp_conn +{ enum connect_state is_connected; char server[NCP_BINDERY_NAME_LEN]; - char user [NCP_BINDERY_NAME_LEN]; + char user[NCP_BINDERY_NAME_LEN]; struct ncp_fs_info i; @@ -66,7 +155,8 @@ struct ncp_conn { char packet[NCP_PACKET_SIZE]; }; -struct ncp_conn_spec { +struct ncp_conn_spec +{ char server[NCP_BINDERY_NAME_LEN]; char user[NCP_BINDERY_NAME_LEN]; uid_t uid; @@ -74,12 +164,14 @@ struct ncp_conn_spec { char password[NCP_BINDERY_NAME_LEN]; }; -struct ncp_search_seq { +struct ncp_search_seq +{ struct nw_search_sequence s; int namespace; }; -struct ncp_property_info { +struct ncp_property_info +{ __u8 property_name[16]; __u8 property_flags; __u8 property_security; @@ -94,46 +186,47 @@ struct ncp_property_info { from the list. It was designed after the X Windows init functions. */ struct ncp_conn * -ncp_initialize(int *argc, char **argv, - int login_necessary, long *err); + ncp_initialize(int *argc, char **argv, + int login_necessary, long *err); /* You can login as another object by this procedure. As a first use pserver comes to mind. */ struct ncp_conn * -ncp_initialize_as(int *argc, char **argv, - int login_necessary, int login_type, long *err); + ncp_initialize_as(int *argc, char **argv, + int login_necessary, int login_type, long *err); /* Open a connection */ struct ncp_conn * -ncp_open(const struct ncp_conn_spec *spec, long *err); + ncp_open(const struct ncp_conn_spec *spec, long *err); /* Open a connection on an existing mount point */ struct ncp_conn * -ncp_open_mount(const char *mount_point, long *err); + ncp_open_mount(const char *mount_point, long *err); /* Find a permanent connection that fits the spec, return NULL if * there is none. */ char * -ncp_find_permanent(const struct ncp_conn_spec *spec); + ncp_find_permanent(const struct ncp_conn_spec *spec); /* Find the address of a file server */ struct sockaddr_ipx * -ncp_find_fileserver(const char *server_name, long *err); + ncp_find_fileserver(const char *server_name, long *err); /* Find the address of a server */ struct sockaddr_ipx * -ncp_find_server(const char **server_name, int type, long *err); + ncp_find_server(const char **server_name, int type, long *err); /* Detach from a permanent connection or destroy a temporary connection */ long -ncp_close(struct ncp_conn *conn); + ncp_close(struct ncp_conn *conn); /* like getmntent, get_ncp_conn_ent scans /etc/mtab for usable connections */ -struct ncp_conn_ent { +struct ncp_conn_ent +{ char server[NCP_BINDERY_NAME_LEN]; char user[NCP_BINDERY_NAME_LEN]; uid_t uid; @@ -141,7 +234,7 @@ struct ncp_conn_ent { }; struct ncp_conn_ent * -ncp_get_conn_ent(FILE *filep); + ncp_get_conn_ent(FILE * filep); #define NWCLIENT (".nwclient") #define NWC_NOPASSWORD ("-") @@ -149,165 +242,168 @@ ncp_get_conn_ent(FILE *filep); /* find an appropriate connection */ struct ncp_conn_spec * -ncp_find_conn_spec(const char *server, const char *user, const char *password, - int login_necessary, uid_t uid, long *err); + ncp_find_conn_spec(const char *server, const char *user, const char *password, + int login_necessary, uid_t uid, long *err); long -ncp_get_file_server_description_strings(struct ncp_conn *conn, - char target[512]); + ncp_get_file_server_description_strings(struct ncp_conn *conn, + char target[512]); long -ncp_get_file_server_time(struct ncp_conn *conn, time_t *target); + ncp_get_file_server_time(struct ncp_conn *conn, time_t * target); long -ncp_set_file_server_time(struct ncp_conn *conn, time_t *source); + ncp_set_file_server_time(struct ncp_conn *conn, time_t * source); -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)); +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); + 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]); + 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); + 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); + 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, - const char *message); + ncp_send_broadcast(struct ncp_conn *conn, + __u8 no_conn, const __u8 * connections, + const char *message); long -ncp_get_encryption_key(struct ncp_conn *conn, - char *target); + ncp_get_encryption_key(struct ncp_conn *conn, + char *target); long -ncp_get_bindery_object_id(struct ncp_conn *conn, - __u16 object_type, - const char *object_name, - struct ncp_bindery_object *target); -long -ncp_get_bindery_object_name(struct ncp_conn *conn, - __u32 object_id, - struct ncp_bindery_object *target); -long -ncp_scan_bindery_object(struct ncp_conn *conn, - __u32 last_id, __u16 object_type, char *search_string, - struct ncp_bindery_object *target); -long -ncp_create_bindery_object(struct ncp_conn *conn, - __u16 object_type, - const char *object_name, - __u8 object_security, - __u8 object_status); -long -ncp_delete_bindery_object(struct ncp_conn *conn, - __u16 object_type, - const char *object_name); - -long -ncp_change_object_security(struct ncp_conn *conn, + ncp_get_bindery_object_id(struct ncp_conn *conn, __u16 object_type, const char *object_name, - __u8 security); + struct ncp_bindery_object *target); +long + ncp_get_bindery_object_name(struct ncp_conn *conn, + __u32 object_id, + struct ncp_bindery_object *target); +long + ncp_scan_bindery_object(struct ncp_conn *conn, + __u32 last_id, __u16 object_type, char *search_string, + struct ncp_bindery_object *target); +long + ncp_create_bindery_object(struct ncp_conn *conn, + __u16 object_type, + const char *object_name, + __u8 object_security, + __u8 object_status); +long + ncp_delete_bindery_object(struct ncp_conn *conn, + __u16 object_type, + const char *object_name); -struct ncp_station_addr { - __u32 NetWork __attribute__ ((packed)); - __u8 Node[6] __attribute__ ((packed)); - __u16 Socket __attribute__ ((packed)); +long + ncp_change_object_security(struct ncp_conn *conn, + __u16 object_type, + const char *object_name, + __u8 security); + +struct ncp_station_addr +{ + __u32 NetWork __attribute__((packed)); + __u8 Node[6] __attribute__((packed)); + __u16 Socket __attribute__((packed)); }; -struct ncp_prop_login_control { - __u8 AccountExpireDate[3] __attribute__ ((packed)); - __u8 Disabled __attribute__ ((packed)); - __u8 PasswordExpireDate[3] __attribute__ ((packed)); - __u8 GraceLogins __attribute__ ((packed)); - __u16 PasswordExpireInterval __attribute__ ((packed)); - __u8 MaxGraceLogins __attribute__ ((packed)); - __u8 MinPasswordLength __attribute__ ((packed)); - __u16 MaxConnections __attribute__ ((packed)); - __u8 ConnectionTimeMask[42] __attribute__ ((packed)); - __u8 LastLogin[6] __attribute__ ((packed)); - __u8 RestrictionMask __attribute__ ((packed)); - __u8 reserved __attribute__ ((packed)); - __u32 MaxDiskUsage __attribute__ ((packed)); - __u16 BadLoginCount __attribute__ ((packed)); - __u32 BadLoginCountDown __attribute__ ((packed)); - struct ncp_station_addr LastIntruder __attribute__ ((packed)); -}; +struct ncp_prop_login_control +{ + __u8 AccountExpireDate[3] __attribute__((packed)); + __u8 Disabled __attribute__((packed)); + __u8 PasswordExpireDate[3] __attribute__((packed)); + __u8 GraceLogins __attribute__((packed)); + __u16 PasswordExpireInterval __attribute__((packed)); + __u8 MaxGraceLogins __attribute__((packed)); + __u8 MinPasswordLength __attribute__((packed)); + __u16 MaxConnections __attribute__((packed)); + __u8 ConnectionTimeMask[42] __attribute__((packed)); + __u8 LastLogin[6] __attribute__((packed)); + __u8 RestrictionMask __attribute__((packed)); + __u8 reserved __attribute__((packed)); + __u32 MaxDiskUsage __attribute__((packed)); + __u16 BadLoginCount __attribute__((packed)); + __u32 BadLoginCountDown __attribute__((packed)); + struct ncp_station_addr LastIntruder __attribute__((packed)); +}; long -ncp_read_property_value(struct ncp_conn *conn, - int object_type, const char *object_name, - int segment, const char *prop_name, - struct nw_property *target); + ncp_read_property_value(struct ncp_conn *conn, + int object_type, const char *object_name, + int segment, const char *prop_name, + struct nw_property *target); long -ncp_scan_property(struct ncp_conn *conn, - __u16 object_type, const char *object_name, - __u32 last_id, char *search_string, - struct ncp_property_info *property_info); + ncp_scan_property(struct ncp_conn *conn, + __u16 object_type, const char *object_name, + __u32 last_id, char *search_string, + struct ncp_property_info *property_info); long -ncp_add_object_to_set(struct ncp_conn *conn, - __u16 object_type, const char *object_name, - const char *property_name, - __u16 member_type, - const char *member_name); + ncp_add_object_to_set(struct ncp_conn *conn, + __u16 object_type, const char *object_name, + const char *property_name, + __u16 member_type, + const char *member_name); long -ncp_change_property_security(struct ncp_conn *conn, - __u16 object_type, const char *object_name, - const char *property_name, - __u8 property_security); + ncp_change_property_security(struct ncp_conn *conn, + __u16 object_type, const char *object_name, + const char *property_name, + __u8 property_security); long -ncp_create_property(struct ncp_conn *conn, + ncp_create_property(struct ncp_conn *conn, __u16 object_type, const char *object_name, - const char *property_name, + const char *property_name, __u8 property_flags, __u8 property_security); long -ncp_delete_object_from_set(struct ncp_conn *conn, - __u16 object_type, const char *object_name, - const char *property_name, - __u16 member_type, - const char *member_name); -long -ncp_delete_property(struct ncp_conn *conn, - __u16 object_type, const char *object_name, - const char *property_name); + ncp_delete_object_from_set(struct ncp_conn *conn, + __u16 object_type, const char *object_name, + const char *property_name, + __u16 member_type, + const char *member_name); long -ncp_write_property_value(struct ncp_conn *conn, - __u16 object_type, const char *object_name, - const char *property_name, - __u8 segment, - struct nw_property *property_value); + ncp_delete_property(struct ncp_conn *conn, + __u16 object_type, const char *object_name, + const char *property_name); +long + ncp_write_property_value(struct ncp_conn *conn, + __u16 object_type, const char *object_name, + const char *property_name, + __u8 segment, + struct nw_property *property_value); /* Bit masks for security flag */ #define NCP_SEC_CHECKSUMMING_REQUESTED (1) @@ -317,138 +413,138 @@ ncp_write_property_value(struct ncp_conn *conn, #define NCP_SEC_LIP_DISABLED (128) long -ncp_get_big_ncp_max_packet_size(struct ncp_conn *conn, - __u16 proposed_max_size, - __u8 proposed_security_flag, - __u16 *accepted_max_size, - __u16 *echo_socket, - __u8 *accepted_security_flag); + ncp_get_big_ncp_max_packet_size(struct ncp_conn *conn, + __u16 proposed_max_size, + __u8 proposed_security_flag, + __u16 * accepted_max_size, + __u16 * echo_socket, + __u8 * accepted_security_flag); long -ncp_login_encrypted(struct ncp_conn *conn, - const struct ncp_bindery_object *object, - const unsigned char *key, - const unsigned char *passwd); + ncp_login_encrypted(struct ncp_conn *conn, + const struct ncp_bindery_object *object, + 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); + 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, - const unsigned char *key, - const unsigned char *oldpasswd, - const unsigned char *newpasswd); + ncp_change_login_passwd(struct ncp_conn *conn, + const struct ncp_bindery_object *object, + const unsigned char *key, + const unsigned char *oldpasswd, + const unsigned char *newpasswd); #define NCP_GRACE_PERIOD (0xdf) long -ncp_login_user(struct ncp_conn *conn, - const unsigned char *username, - const unsigned char *password); + ncp_login_user(struct ncp_conn *conn, + const unsigned char *username, + const unsigned char *password); long -ncp_get_volume_info_with_number(struct ncp_conn *conn, int n, - struct ncp_volume_info *target); + ncp_get_volume_info_with_number(struct ncp_conn *conn, int n, + struct ncp_volume_info *target); long -ncp_get_volume_number(struct ncp_conn *conn, const char *name, - int *target); + ncp_get_volume_number(struct ncp_conn *conn, const char *name, + int *target); long -ncp_file_search_init(struct ncp_conn *conn, - int dir_handle, const char *path, - struct ncp_filesearch_info *target); + ncp_file_search_init(struct ncp_conn *conn, + int dir_handle, const char *path, + struct ncp_filesearch_info *target); long -ncp_file_search_continue(struct ncp_conn *conn, - struct ncp_filesearch_info *fsinfo, - int attributes, const char *path, - struct ncp_file_info *target); + ncp_file_search_continue(struct ncp_conn *conn, + struct ncp_filesearch_info *fsinfo, + int attributes, const char *path, + struct ncp_file_info *target); long -ncp_get_finfo(struct ncp_conn *conn, - int dir_handle, const char *path, const char *name, - struct ncp_file_info *target); + ncp_get_finfo(struct ncp_conn *conn, + int dir_handle, const char *path, const char *name, + struct ncp_file_info *target); long -ncp_open_file(struct ncp_conn *conn, - int dir_handle, const char *path, - int attr, int access, - struct ncp_file_info *target); -long -ncp_close_file(struct ncp_conn *conn, const char *file_id); - -long -ncp_create_newfile(struct ncp_conn *conn, - int dir_handle, const char *path, - int attr, - struct ncp_file_info *target); - -long -ncp_create_file(struct ncp_conn *conn, - int dir_handle, const char *path, - int attr, - struct ncp_file_info *target); - -long -ncp_erase_file(struct ncp_conn *conn, + ncp_open_file(struct ncp_conn *conn, int dir_handle, const char *path, - int attr); + int attr, int access, + struct ncp_file_info *target); +long + ncp_close_file(struct ncp_conn *conn, const char *file_id); long -ncp_rename_file(struct ncp_conn *conn, - int old_handle, const char *old_path, - int attr, - int new_handle, const char *new_path); + ncp_create_newfile(struct ncp_conn *conn, + int dir_handle, const char *path, + int attr, + struct ncp_file_info *target); long -ncp_create_directory(struct ncp_conn *conn, - int dir_handle, const char *path, - int inherit_mask); + ncp_create_file(struct ncp_conn *conn, + int dir_handle, const char *path, + int attr, + struct ncp_file_info *target); long -ncp_delete_directory(struct ncp_conn *conn, - int dir_handle, const char *path); - -long -ncp_rename_directory(struct ncp_conn *conn, - int dir_handle, - const char *old_path, const char *new_path); - -long -ncp_add_trustee(struct ncp_conn *conn, + ncp_erase_file(struct ncp_conn *conn, int dir_handle, const char *path, - __u32 object_id, __u8 rights); + int attr); long -ncp_delete_trustee(struct ncp_conn *conn, - int dir_handle, const char *path, __u32 object_id); + ncp_rename_file(struct ncp_conn *conn, + int old_handle, const char *old_path, + int attr, + int new_handle, const char *new_path); long -ncp_read(struct ncp_conn *conn, const char *file_id, - off_t offset, size_t count, char *target); + ncp_create_directory(struct ncp_conn *conn, + int dir_handle, const char *path, + int inherit_mask); long -ncp_write(struct ncp_conn *conn, const char *file_id, - off_t offset, size_t count, const char *source); + ncp_delete_directory(struct ncp_conn *conn, + int dir_handle, const char *path); long -ncp_copy_file(struct ncp_conn *conn, - const char source_file[6], - const char target_file[6], - __u32 source_offset, - __u32 target_offset, - __u32 count, - __u32 *copied_count); + ncp_rename_directory(struct ncp_conn *conn, + int dir_handle, + const char *old_path, const char *new_path); 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); + ncp_add_trustee(struct ncp_conn *conn, + int dir_handle, const char *path, + __u32 object_id, __u8 rights); + +long + ncp_delete_trustee(struct ncp_conn *conn, + int dir_handle, const char *path, __u32 object_id); + +long + ncp_read(struct ncp_conn *conn, const char *file_id, + off_t offset, size_t count, char *target); + +long + ncp_write(struct ncp_conn *conn, const char *file_id, + off_t offset, size_t count, const char *source); + +long + ncp_copy_file(struct ncp_conn *conn, + const char source_file[6], + const char target_file[6], + __u32 source_offset, + __u32 target_offset, + __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); #define NCP_PERM_READ (0x001) #define NCP_PERM_WRITE (0x002) @@ -461,103 +557,103 @@ ncp_obtain_file_or_subdir_info(struct ncp_conn *conn, #define NCP_PERM_SUPER (0x100) long -ncp_get_eff_directory_rights(struct ncp_conn *conn, - __u8 source_ns, __u8 target_ns, - __u16 search_attribs, - __u8 vol, __u32 dirent, const char *path, - __u16 *my_effective_rights); + ncp_get_eff_directory_rights(struct ncp_conn *conn, + __u8 source_ns, __u8 target_ns, + __u16 search_attribs, + __u8 vol, __u32 dirent, const char *path, + __u16 * my_effective_rights); long -ncp_do_lookup(struct ncp_conn *conn, - struct nw_info_struct *dir, - char *path, /* may only be one component */ - struct nw_info_struct *target); + ncp_do_lookup(struct ncp_conn *conn, + struct nw_info_struct *dir, + char *path, /* may only be one component */ + struct nw_info_struct *target); long -ncp_modify_file_or_subdir_dos_info(struct ncp_conn *conn, - struct nw_info_struct *file, - __u32 info_mask, - struct nw_modify_dos_info *info); + ncp_modify_file_or_subdir_dos_info(struct ncp_conn *conn, + struct nw_info_struct *file, + __u32 info_mask, + struct nw_modify_dos_info *info); long -ncp_del_file_or_subdir(struct ncp_conn *conn, - struct nw_info_struct *dir, char *name); + ncp_del_file_or_subdir(struct ncp_conn *conn, + struct nw_info_struct *dir, char *name); long -ncp_open_create_file_or_subdir(struct ncp_conn *conn, - struct nw_info_struct *dir, char *name, - int open_create_mode, - __u32 create_attributes, - int desired_acc_rights, - struct nw_file_info *target); + ncp_open_create_file_or_subdir(struct ncp_conn *conn, + struct nw_info_struct *dir, char *name, + int open_create_mode, + __u32 create_attributes, + int desired_acc_rights, + struct nw_file_info *target); long -ncp_initialize_search(struct ncp_conn *conn, - const struct nw_info_struct *dir, - int namespace, - struct ncp_search_seq *target); + ncp_initialize_search(struct ncp_conn *conn, + const struct nw_info_struct *dir, + int namespace, + struct ncp_search_seq *target); long -ncp_search_for_file_or_subdir(struct ncp_conn *conn, - struct ncp_search_seq *seq, - struct nw_info_struct *target); + ncp_search_for_file_or_subdir(struct ncp_conn *conn, + struct ncp_search_seq *seq, + struct nw_info_struct *target); long -ncp_ren_or_mov_file_or_subdir(struct ncp_conn *conn, - struct nw_info_struct *old_dir, char *old_name, - struct nw_info_struct *new_dir, char *new_name); + ncp_ren_or_mov_file_or_subdir(struct ncp_conn *conn, + struct nw_info_struct *old_dir, char *old_name, + struct nw_info_struct *new_dir, char *new_name); long -ncp_create_queue_job_and_file(struct ncp_conn *conn, + ncp_create_queue_job_and_file(struct ncp_conn *conn, + __u32 queue_id, + struct queue_job *job); + +long + ncp_close_file_and_start_job(struct ncp_conn *conn, __u32 queue_id, struct queue_job *job); long -ncp_close_file_and_start_job(struct ncp_conn *conn, - __u32 queue_id, - struct queue_job *job); + ncp_attach_to_queue(struct ncp_conn *conn, + __u32 queue_id); long -ncp_attach_to_queue(struct ncp_conn *conn, - __u32 queue_id); + ncp_detach_from_queue(struct ncp_conn *conn, + __u32 queue_id); long -ncp_detach_from_queue(struct ncp_conn *conn, - __u32 queue_id); + ncp_service_queue_job(struct ncp_conn *conn, __u32 queue_id, __u16 job_type, + struct queue_job *job); long -ncp_service_queue_job(struct ncp_conn *conn, __u32 queue_id, __u16 job_type, - struct queue_job *job); + ncp_finish_servicing_job(struct ncp_conn *conn, __u32 queue_id, + __u32 job_number, __u32 charge_info); long -ncp_finish_servicing_job(struct ncp_conn *conn, __u32 queue_id, - __u32 job_number, __u32 charge_info); + ncp_abort_servicing_job(struct ncp_conn *conn, __u32 queue_id, + __u32 job_number); long -ncp_abort_servicing_job(struct ncp_conn *conn, __u32 queue_id, - __u32 job_number); + ncp_get_broadcast_message(struct ncp_conn *conn, char message[256]); long -ncp_get_broadcast_message(struct ncp_conn *conn, char message[256]); - -long -ncp_dealloc_dir_handle(struct ncp_conn *conn, __u8 dir_handle); + ncp_dealloc_dir_handle(struct ncp_conn *conn, __u8 dir_handle); #define NCP_ALLOC_PERMANENT (0x0000) #define NCP_ALLOC_TEMPORARY (0x0001) #define NCP_ALLOC_SPECIAL (0x0002) long -ncp_alloc_short_dir_handle(struct ncp_conn *conn, - struct nw_info_struct *dir, - __u16 alloc_mode, - __u8 *target); + ncp_alloc_short_dir_handle(struct ncp_conn *conn, + struct nw_info_struct *dir, + __u16 alloc_mode, + __u8 * target); long -ncp_get_effective_dir_rights(struct ncp_conn *conn, - struct nw_info_struct *file, - __u16 *target); + ncp_get_effective_dir_rights(struct ncp_conn *conn, + struct nw_info_struct *file, + __u16 * target); struct ncp_trustee_struct { @@ -566,10 +662,10 @@ struct ncp_trustee_struct }; long -ncp_add_trustee_set(struct ncp_conn *conn, - __u8 volume_number, __u32 dir_entry, - __u16 rights_mask, - int object_count, struct ncp_trustee_struct *rights); - + ncp_add_trustee_set(struct ncp_conn *conn, + __u8 volume_number, __u32 dir_entry, + __u16 rights_mask, + int object_count, struct ncp_trustee_struct *rights); -#endif /* _NCPLIB_H */ + +#endif /* _NCPLIB_H */ diff --git a/lib/Makefile b/lib/Makefile index fa86697..5e73e9f 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -28,7 +28,7 @@ install: $(INSTALL_LIB) ncplib.o: ncplib.c ncplib_err.h - $(CC) $(CFLAGS) -finline-functions -c ncplib.c + $(CC) $(CFLAGS) -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 diff --git a/lib/ncplib.c b/lib/ncplib.c index 7ff183a..5ccad92 100644 --- a/lib/ncplib.c +++ b/lib/ncplib.c @@ -8,12 +8,7 @@ #include "ncplib.h" #include "ncplib_err.h" -typedef __u8 byte; -typedef __u16 word; -typedef __u32 dword; - #include -/* #include */ /* generates a warning here */ extern pid_t wait(int *); #include #include @@ -34,21 +29,22 @@ extern pid_t wait(int *); #include static long -ncp_negotiate_buffersize(struct ncp_conn *conn, - int size, int *target); + ncp_negotiate_buffersize(struct ncp_conn *conn, + int size, int *target); static long -ncp_login_object(struct ncp_conn *conn, - const unsigned char *username, - int login_type, - const unsigned char *password); + ncp_login_object(struct ncp_conn *conn, + const unsigned char *username, + int login_type, + const unsigned char *password); static long -ncp_do_close(struct ncp_conn *conn); + ncp_do_close(struct ncp_conn *conn); void str_upper(char *name) { - while (*name) { + while (*name) + { *name = toupper(*name); name = name + 1; } @@ -60,7 +56,7 @@ static int debug_level = 5; static FILE *logfile = stderr; static void -dprintf(int level, char *p, ...) +dprintf(int level, char *p,...) { va_list ap; @@ -68,7 +64,6 @@ dprintf(int level, char *p, ...) { return; } - va_start(ap, p); vfprintf(logfile, p, ap); va_end(ap); @@ -83,62 +78,62 @@ dprintf(int level, char *p, ...) #include "nwcrypt.c" void -ipx_fprint_node(FILE* file,IPXNode node) +ipx_fprint_node(FILE * file, IPXNode node) { - fprintf(file,"%02X%02X%02X%02X%02X%02X", - (unsigned char)node[0], - (unsigned char)node[1], - (unsigned char)node[2], - (unsigned char)node[3], - (unsigned char)node[4], - (unsigned char)node[5] - ); + fprintf(file, "%02X%02X%02X%02X%02X%02X", + (unsigned char) node[0], + (unsigned char) node[1], + (unsigned char) node[2], + (unsigned char) node[3], + (unsigned char) node[4], + (unsigned char) node[5] + ); } void -ipx_fprint_network(FILE* file,IPXNet net) +ipx_fprint_network(FILE * file, IPXNet net) { - fprintf(file,"%08lX",ntohl(net)); + fprintf(file, "%08lX", ntohl(net)); } void -ipx_fprint_port(FILE* file,IPXPort port) +ipx_fprint_port(FILE * file, IPXPort port) { - fprintf(file,"%04X",ntohs(port)); + fprintf(file, "%04X", ntohs(port)); } void -ipx_fprint_saddr(FILE* file,struct sockaddr_ipx* sipx) +ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx) { - ipx_fprint_network(file,sipx->sipx_network); - fprintf(file,":"); - ipx_fprint_node(file,sipx->sipx_node); - fprintf(file,":"); - ipx_fprint_port(file,sipx->sipx_port); + ipx_fprint_network(file, sipx->sipx_network); + fprintf(file, ":"); + ipx_fprint_node(file, sipx->sipx_node); + fprintf(file, ":"); + ipx_fprint_port(file, sipx->sipx_port); } void ipx_print_node(IPXNode node) { - ipx_fprint_node(stdout,node); + ipx_fprint_node(stdout, node); } void ipx_print_network(IPXNet net) { - ipx_fprint_network(stdout,net); + ipx_fprint_network(stdout, net); } void ipx_print_port(IPXPort port) { - ipx_fprint_port(stdout,port); + ipx_fprint_port(stdout, port); } void -ipx_print_saddr(struct sockaddr_ipx* sipx) +ipx_print_saddr(struct sockaddr_ipx *sipx) { - ipx_fprint_saddr(stdout,sipx); + ipx_fprint_saddr(stdout, sipx); } int @@ -153,8 +148,7 @@ ipx_sscanf_node(char *buf, unsigned char node[6]) { return i; } - - for (i=0; i<6; i++) + for (i = 0; i < 6; i++) { node[i] = n[i]; } @@ -169,7 +163,7 @@ ipx_sscanf_saddr(char *buf, struct sockaddr_ipx *target) addr.sipx_family = AF_IPX; addr.sipx_type = NCP_PTYPE; - + if (sscanf(buf, "%lx", &addr.sipx_network) != 1) { return 1; @@ -205,9 +199,9 @@ ipx_assign_node(IPXNode dest, IPXNode src) } int -ipx_node_equal(IPXNode n1,IPXNode n2) +ipx_node_equal(IPXNode n1, IPXNode n2) { - return memcmp(n1,n2, IPX_NODE_LEN)==0; + return memcmp(n1, n2, IPX_NODE_LEN) == 0; } static int @@ -219,24 +213,24 @@ ipx_recvfrom(int sock, void *buf, int len, unsigned int flags, struct timeval tv; int result; - FD_ZERO(&rd); FD_ZERO(&wr); FD_ZERO(&ex); + FD_ZERO(&rd); + FD_ZERO(&wr); + FD_ZERO(&ex); FD_SET(sock, &rd); - tv.tv_sec = timeout; + tv.tv_sec = timeout; tv.tv_usec = 0; - - if ((result = select(sock+1, &rd, &wr, &ex, &tv)) == -1) + + if ((result = select(sock + 1, &rd, &wr, &ex, &tv)) == -1) { *err = errno; return -1; } - if (FD_ISSET(sock, &rd)) { result = recvfrom(sock, buf, len, flags, - (struct sockaddr *)sender, addrlen); - } - else + (struct sockaddr *) sender, addrlen); + } else { result = -1; errno = ETIMEDOUT; @@ -276,14 +270,12 @@ install_wdog(struct ncp_conn *conn) { return -1; } - if (pid != 0) { /* Parent, should go on as usual */ conn->wdog_pid = pid; return 0; } - while (1) { long err; @@ -298,16 +290,14 @@ install_wdog(struct ncp_conn *conn) anymore */ exit(0); } - - if ( (pktsize != 2) + if ((pktsize != 2) || (buf[1] != '?')) { continue; } - buf[1] = 'Y'; pktsize = sendto(sock, buf, 2, 0, - (struct sockaddr *)&sender, + (struct sockaddr *) &sender, sizeof(sender)); } } @@ -315,7 +305,7 @@ install_wdog(struct ncp_conn *conn) #define ncp_printf printf static void -assert_conn_locked(struct ncp_conn *conn); + assert_conn_locked(struct ncp_conn *conn); static void assert_conn_not_locked(struct ncp_conn *conn) @@ -343,14 +333,15 @@ ncp_unlock_conn(struct ncp_conn *conn) static long do_ncp_call(struct ncp_conn *conn, int request_size) { - struct ncp_request_header request = - *((struct ncp_request_header *)(&(conn->packet))); + struct ncp_request_header request; int result; int retries = 20; int len; long err; + memcpy(&request, conn->packet, sizeof(request)); + while (retries > 0) { struct ncp_reply_header reply; @@ -361,17 +352,16 @@ do_ncp_call(struct ncp_conn *conn, int request_size) result = sendto(conn->ncp_sock, conn->packet, request_size, - 0, (struct sockaddr *)&(conn->i.addr), + 0, (struct sockaddr *) &(conn->i.addr), sizeof(conn->i.addr)); if (result < 0) { return errno; } - - re_select: + re_select: len = ipx_recvfrom(conn->ncp_sock, - (char *)&reply, sizeof(reply), + (char *) &reply, sizeof(reply), MSG_PEEK, &sender, &sizeofaddr, 3, &err); if ((len < 0) && (err == ETIMEDOUT)) @@ -382,30 +372,28 @@ do_ncp_call(struct ncp_conn *conn, int request_size) { return err; } + if ( /* Is the sender wrong? */ + (memcmp(&sender.sipx_node, + &(conn->i.addr.sipx_node), 6) != 0) + || (sender.sipx_port != conn->i.addr.sipx_port) - if ( /* Is the sender wrong? */ - (memcmp(&sender.sipx_node, - &(conn->i.addr.sipx_node), 6) != 0) - || (sender.sipx_port != conn->i.addr.sipx_port) + /* Did the sender send a positive acknowledge? */ + || ((len == sizeof(reply)) + && (reply.type == NCP_POSITIVE_ACK)) - /* Did the sender send a positive acknowledge? */ - || ( (len == sizeof(reply)) - && (reply.type == NCP_POSITIVE_ACK)) - - /* Did we get a bogus answer? */ - || ( (len < sizeof(reply)) - || (reply.type != NCP_REPLY) - || ( (request.type != NCP_ALLOC_SLOT_REQUEST) - && ( (reply.sequence != request.sequence) - || (reply.conn_low != request.conn_low) - || (reply.conn_high != request.conn_high))))) + /* Did we get a bogus answer? */ + || ((len < sizeof(reply)) + || (reply.type != NCP_REPLY) + || ((request.type != NCP_ALLOC_SLOT_REQUEST) + && ((reply.sequence != request.sequence) + || (reply.conn_low != request.conn_low) + || (reply.conn_high != request.conn_high))))) { /* Then throw away the packet */ - ipx_recv(conn->ncp_sock, (char *)&reply, sizeof(reply), + ipx_recv(conn->ncp_sock, (char *) &reply, sizeof(reply), 0, 1, &err); goto re_select; } - ipx_recv(conn->ncp_sock, conn->packet, NCP_PACKET_SIZE, 0, 1, &err); conn->reply_size = len; @@ -417,86 +405,70 @@ do_ncp_call(struct ncp_conn *conn, int request_size) static int ncp_mount_request(struct ncp_conn *conn, int function) { - struct ncp_request_header *h - = (struct ncp_request_header *)(conn->packet); - struct ncp_reply_header *reply - = (struct ncp_reply_header *)(conn->packet); struct ncp_ioctl_request request; - int result; assert_conn_locked(conn); if (conn->has_subfunction != 0) { - *(__u16 *)&(h->data[0]) - = htons(conn->current_size - - sizeof(struct ncp_request_header) - 2); + WSET_HL(conn->packet, 7, conn->current_size + - sizeof(struct ncp_request_header) - 2); } + request.function = function; + request.size = conn->current_size; + request.data = conn->packet; - request.function = function; - request.size = conn->current_size; - request.data = conn->packet; - - if ((result = ioctl(conn->mount_fid,NCP_IOC_NCPREQUEST, &request)) < 0) + if ((result = ioctl(conn->mount_fid, NCP_IOC_NCPREQUEST, &request)) < 0) { return result; } - - conn->completion = reply->completion_code; - conn->conn_status = reply->connection_state; + conn->completion = BVAL(conn->packet, 6); + conn->conn_status = BVAL(conn->packet, 7); conn->ncp_reply_size = result - sizeof(struct ncp_reply_header); - if ((reply->completion_code != 0) && (conn->verbose != 0)) + if ((conn->completion != 0) && (conn->verbose != 0)) { - ncp_printf("ncp_request_error: %d\n", reply->completion_code); + ncp_printf("ncp_request_error: %d\n", conn->completion); } - return reply->completion_code == 0 ? 0 : NCPL_ET_REQUEST_ERROR; + return conn->completion == 0 ? 0 : NCPL_ET_REQUEST_ERROR; } static long ncp_temp_request(struct ncp_conn *conn, int function) { - struct ncp_request_header *h - = (struct ncp_request_header *)&(conn->packet); - struct ncp_reply_header *r - = (struct ncp_reply_header *)&(conn->packet); - long err; assert_conn_locked(conn); + conn->sequence += 1; + + WSET_LH(conn->packet, 0, NCP_REQUEST); + BSET(conn->packet, 2, conn->sequence); + BSET(conn->packet, 3, (conn->i.connection) & 0xff); + BSET(conn->packet, 5, (conn->i.connection) >> 8); + BSET(conn->packet, 4, 1); + BSET(conn->packet, 6, function); + if (conn->has_subfunction != 0) { - *(__u16 *)&(h->data[0]) - = htons(conn->current_size - - sizeof(struct ncp_request_header) - 2); + WSET_HL(conn->packet, 7, conn->current_size + - sizeof(struct ncp_request_header) - 2); } - - h->type = NCP_REQUEST; - - conn->sequence += 1; - h->sequence = conn->sequence; - h->conn_low = (conn->i.connection) & 0xff; - h->conn_high = ((conn->i.connection) & 0xff00) >> 8; - h->task = 1; - h->function = function; - if ((err = do_ncp_call(conn, conn->current_size)) != 0) { return err; } - - conn->completion = r->completion_code; - conn->conn_status = r->connection_state; + conn->completion = BVAL(conn->packet, 6); + conn->conn_status = BVAL(conn->packet, 7); conn->ncp_reply_size = - conn->reply_size - sizeof(struct ncp_reply_header); + conn->reply_size - sizeof(struct ncp_reply_header); - if ((r->completion_code != 0) && (conn->verbose != 0)) + if ((conn->completion != 0) && (conn->verbose != 0)) { - ncp_printf("ncp_completion_code: %d\n", r->completion_code); + ncp_printf("ncp_completion_code: %d\n", conn->completion); } - return r->completion_code == 0 ? 0 : NCPL_ET_REQUEST_ERROR; + return conn->completion == 0 ? 0 : NCPL_ET_REQUEST_ERROR; } #ifdef PACKET_SIGNATURES @@ -513,7 +485,6 @@ ncp_setup_security(struct ncp_conn *conn) { return 0; } - if ((accepted_security & NCP_SEC_SIGNATURE_REQUESTED) == 0) { return 0; @@ -537,9 +508,6 @@ static long ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *target, int wdog_needed) { - struct ncp_request_header *h = - (struct ncp_request_header *)&(conn->packet); - struct sockaddr_ipx addr; int addrlen; @@ -548,83 +516,80 @@ ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *target, conn->is_connected = NOT_CONNECTED; conn->verbose = 0; - + if ((ncp_sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX)) == -1) { return errno; } - if ((wdog_sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX)) == -1) { return errno; } - - addr.sipx_family = AF_IPX; - addr.sipx_port = htons(0x0); - addr.sipx_type = NCP_PTYPE; + addr.sipx_family = AF_IPX; + addr.sipx_port = htons(0x0); + addr.sipx_type = NCP_PTYPE; addr.sipx_network = IPX_THIS_NET; ipx_assign_node(addr.sipx_node, IPX_THIS_NODE); addrlen = sizeof(addr); - if ( (bind(ncp_sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) - || (getsockname(ncp_sock, (struct sockaddr *)&addr, &addrlen)==-1)) + if ((bind(ncp_sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) + || (getsockname(ncp_sock, (struct sockaddr *) &addr, &addrlen) == -1)) { int saved_errno = errno; - close(ncp_sock); close(wdog_sock); + close(ncp_sock); + close(wdog_sock); return saved_errno; } - addr.sipx_port = htons(ntohs(addr.sipx_port) + 1); - if (bind(wdog_sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) + if (bind(wdog_sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) { int saved_errno = errno; - close(ncp_sock); close(wdog_sock); + close(ncp_sock); + close(wdog_sock); return saved_errno; } - conn->ncp_sock = ncp_sock; conn->wdog_sock = wdog_sock; - h->type = NCP_ALLOC_SLOT_REQUEST; - conn->sequence = 0; - conn->i.addr = *target; - h->sequence = conn->sequence; - h->conn_low = 0xff; - h->conn_high = 0xff; - h->task = 1; - h->function = 0; + conn->i.addr = *target; - if ((err = do_ncp_call(conn, sizeof(*h))) != 0) + WSET_LH(conn->packet, 0, NCP_ALLOC_SLOT_REQUEST); + BSET(conn->packet, 2, conn->sequence); + BSET(conn->packet, 3, 0xff); + BSET(conn->packet, 4, 1); + BSET(conn->packet, 5, 0xff); + BSET(conn->packet, 6, 0); + + if ((err = do_ncp_call(conn, sizeof(struct ncp_request_header))) != 0) { - close(ncp_sock); close(wdog_sock); + close(ncp_sock); + close(wdog_sock); return err; } - if (wdog_needed != 0) { install_wdog(conn); - } - else + } else { conn->wdog_pid = 0; } - conn->sequence = 0; - conn->i.connection = h->conn_low + (h->conn_high * 256); + conn->sequence = 0; + conn->i.connection = + BVAL(conn->packet, 3) + (BVAL(conn->packet, 5) << 8); conn->is_connected = CONN_TEMPORARY; - if ( (ncp_negotiate_buffersize(conn, 1024, - &(conn->i.buffer_size)) != 0) + if ((ncp_negotiate_buffersize(conn, 1024, + &(conn->i.buffer_size)) != 0) || (conn->i.buffer_size < 512) || (conn->i.buffer_size > 1024)) { ncp_do_close(conn); return -1; } - return 0; } @@ -636,11 +601,10 @@ ncp_connect_any(struct ncp_conn *conn, int wdog_needed) const char *server = NULL; long err; - if ((addr = ncp_find_server(&server,NCP_BINDERY_FSERVER,&err)) == NULL) + if ((addr = ncp_find_server(&server, NCP_BINDERY_FSERVER, &err)) == NULL) { return err; } - if ((result = ncp_connect_addr(conn, addr, wdog_needed)) != 0) { return result; @@ -660,7 +624,7 @@ ncp_find_server(const char **server_name, int type, long *err) { char command[256]; char buf[128]; - char server[NCP_BINDERY_NAME_LEN+1]; + char server[NCP_BINDERY_NAME_LEN + 1]; static struct sockaddr_ipx result; FILE *p; int res; @@ -670,10 +634,9 @@ ncp_find_server(const char **server_name, int type, long *err) if (*server_name != NULL) { - strncpy(server, *server_name, sizeof(server)-1); + strncpy(server, *server_name, sizeof(server) - 1); str_upper(server); } - sprintf(command, "nwsfind -t %d %s", type, server); p = popen(command, "r"); @@ -682,7 +645,6 @@ ncp_find_server(const char **server_name, int type, long *err) *err = errno; return NULL; } - fgets(buf, sizeof(buf), p); if (buf[strlen(buf)] - 1 == '\n'); @@ -693,10 +655,9 @@ ncp_find_server(const char **server_name, int type, long *err) if (((res = pclose(p)) != 0) || (ipx_sscanf_saddr(buf, &result) != 0)) { *err = (*server_name != NULL) - ? NCPL_ET_HOST_UNKNOWN : NCPL_ET_NO_SERVER; + ? NCPL_ET_HOST_UNKNOWN : NCPL_ET_NO_SERVER; return NULL; } - if (*server_name == NULL) { if ((n = strchr(buf, ' ')) == NULL) @@ -706,7 +667,6 @@ ncp_find_server(const char **server_name, int type, long *err) } *server_name = n; } - return &result; } @@ -721,17 +681,14 @@ ncp_open_temporary(struct ncp_conn *conn, { return ncp_connect_any(conn, 1); } - if ((addr = ncp_find_fileserver(spec->server, &err)) == NULL) { return err; } - if ((err = ncp_connect_addr(conn, addr, 1)) != 0) { return err; } - strcpy(conn->server, spec->server); if (strlen(spec->user) != 0) @@ -744,7 +701,6 @@ ncp_open_temporary(struct ncp_conn *conn, } strcpy(conn->user, spec->user); } - return 0; } @@ -757,35 +713,32 @@ ncp_find_permanent(const struct ncp_conn_spec *spec) int mount_fid; struct ncp_fs_info i; - initialize_NCPL_error_table(); + initialize_NCPL_error_table(); if ((mtab = fopen(MOUNTED, "r")) == NULL) { return NULL; } - while ((conn_ent = ncp_get_conn_ent(mtab)) != NULL) { if (spec != NULL) { - if ( (conn_ent->uid != spec->uid) - || ( (strlen(spec->server) != 0) + if ((conn_ent->uid != spec->uid) + || ((strlen(spec->server) != 0) && (strcasecmp(conn_ent->server, spec->server) != 0)) - || ( (strlen(spec->user) != 0) + || ((strlen(spec->user) != 0) && (strcasecmp(conn_ent->user, spec->user) != 0))) { continue; } } - mount_fid = open(conn_ent->mount_point, O_RDONLY, 0); if (mount_fid < 0) { continue; } - i.version = NCP_GET_FS_INFO_VERSION; if (ioctl(mount_fid, NCP_IOC_GET_FS_INFO, &i) < 0) @@ -793,7 +746,6 @@ ncp_find_permanent(const struct ncp_conn_spec *spec) close(mount_fid); continue; } - close(mount_fid); result = conn_ent->mount_point; break; @@ -803,7 +755,7 @@ ncp_find_permanent(const struct ncp_conn_spec *spec) errno = (result == NULL) ? ENOENT : 0; return result; } - + static int ncp_open_permanent(struct ncp_conn *conn, const struct ncp_conn_spec *spec) @@ -815,18 +767,15 @@ ncp_open_permanent(struct ncp_conn *conn, errno = EBUSY; return -1; } - if ((mount_point = ncp_find_permanent(spec)) == NULL) { return -1; } - if (strlen(mount_point) >= sizeof(conn->mount_point)) { errno = ENAMETOOLONG; return -1; } - /* The rest has already been done in ncp_find_permanent, so we * do not check errors anymore */ conn->mount_fid = open(mount_point, O_RDONLY, 0); @@ -836,12 +785,11 @@ ncp_open_permanent(struct ncp_conn *conn, { strncpy(conn->server, spec->server, sizeof(conn->server)); strncpy(conn->user, spec->user, sizeof(conn->user)); - } - else + } else { - memset(conn->server, '\0', sizeof(conn->server)); - memset(conn->user, '\0', sizeof(conn->user)); - } + memset(conn->server, '\0', sizeof(conn->server)); + memset(conn->user, '\0', sizeof(conn->user)); + } strcpy(conn->mount_point, mount_point); conn->is_connected = CONN_PERMANENT; return 0; @@ -852,7 +800,7 @@ ncp_open(const struct ncp_conn_spec *spec, long *err) { struct ncp_conn *result; - initialize_NCPL_error_table(); + initialize_NCPL_error_table(); result = malloc(sizeof(struct ncp_conn)); @@ -861,14 +809,12 @@ ncp_open(const struct ncp_conn_spec *spec, long *err) *err = ENOMEM; return NULL; } - memzero(*result); if (ncp_open_permanent(result, spec) == 0) { return result; } - if ((*err = ncp_open_temporary(result, spec)) != 0) { free(result); @@ -883,14 +829,13 @@ ncp_open_mount(const char *mount_point, long *err) { struct ncp_conn *result; - initialize_NCPL_error_table(); + initialize_NCPL_error_table(); if (strlen(mount_point) >= sizeof(result->mount_point)) { *err = ENAMETOOLONG; return NULL; } - result = malloc(sizeof(struct ncp_conn)); if (result == NULL) @@ -898,7 +843,6 @@ ncp_open_mount(const char *mount_point, long *err) *err = ENOMEM; return NULL; } - memzero(*result); result->is_connected = NOT_CONNECTED; @@ -927,24 +871,21 @@ ncp_open_mount(const char *mount_point, long *err) static long ncp_user_disconnect(struct ncp_conn *conn) { - struct ncp_request_header *h - = (struct ncp_request_header *)(conn->packet); long result; - h->type = NCP_DEALLOC_SLOT_REQUEST; - conn->sequence += 1; - h->sequence = conn->sequence; - h->conn_low = (conn->i.connection) & 0xff; - h->conn_high = ((conn->i.connection) & 0xff00) >> 8; - h->task = 1; - h->function = 0; - if ((result = do_ncp_call(conn, sizeof(*h))) != 0) + WSET_LH(conn->packet, 0, NCP_DEALLOC_SLOT_REQUEST); + BSET(conn->packet, 2, conn->sequence); + BSET(conn->packet, 3, (conn->i.connection) & 0xff); + BSET(conn->packet, 4, 1); + BSET(conn->packet, 5, (conn->i.connection) >> 8); + BSET(conn->packet, 6, 0); + + if ((result = do_ncp_call(conn, sizeof(struct ncp_request_header))) != 0) { return result; } - close(conn->ncp_sock); close(conn->wdog_sock); @@ -953,7 +894,6 @@ ncp_user_disconnect(struct ncp_conn *conn) kill(conn->wdog_pid, SIGTERM); wait(NULL); } - return 0; } @@ -967,7 +907,7 @@ ncp_do_close(struct ncp_conn *conn) case CONN_PERMANENT: result = close(conn->mount_fid); break; - + case CONN_TEMPORARY: result = ncp_user_disconnect(conn); break; @@ -975,7 +915,7 @@ ncp_do_close(struct ncp_conn *conn) default: break; } - + conn->is_connected = NOT_CONNECTED; return result; @@ -989,7 +929,6 @@ ncp_close(struct ncp_conn *conn) { return 0; } - if ((result = ncp_do_close(conn)) != 0) { return result; @@ -999,10 +938,10 @@ ncp_close(struct ncp_conn *conn) } struct ncp_conn_ent * -ncp_get_conn_ent(FILE *filep) +ncp_get_conn_ent(FILE * filep) { static struct ncp_conn_ent entry; - char server[2*NCP_BINDERY_NAME_LEN]; + char server[2 * NCP_BINDERY_NAME_LEN]; char *user; struct mntent *mnt_ent; int fid; @@ -1016,12 +955,10 @@ ncp_get_conn_ent(FILE *filep) { continue; } - if (strlen(mnt_ent->mnt_fsname) >= sizeof(server)) { continue; } - strcpy(server, mnt_ent->mnt_fsname); user = strchr(server, '/'); if (user != NULL) @@ -1034,8 +971,7 @@ ncp_get_conn_ent(FILE *filep) } strcpy(entry.user, user); } - - if ( (strlen(server) >= sizeof(entry.server)) + if ((strlen(server) >= sizeof(entry.server)) || (strlen(mnt_ent->mnt_dir) >= sizeof(entry.mount_point))) { continue; @@ -1049,12 +985,11 @@ ncp_get_conn_ent(FILE *filep) { continue; } - - if (ioctl(fid, NCP_IOC_GETMOUNTUID, &entry.uid) != 0) { + if (ioctl(fid, NCP_IOC_GETMOUNTUID, &entry.uid) != 0) + { close(fid); continue; } - close(fid); return &entry; } @@ -1063,7 +998,7 @@ ncp_get_conn_ent(FILE *filep) } static struct ncp_conn_spec * -ncp_get_nwc_ent(FILE *nwc) +ncp_get_nwc_ent(FILE * nwc) { static struct ncp_conn_spec spec; char line[512]; @@ -1076,18 +1011,16 @@ ncp_get_nwc_ent(FILE *nwc) while (fgets(line, sizeof(line), nwc) != NULL) { - if ( (line[0] == '\n') + if ((line[0] == '\n') || (line[0] == '#')) { continue; } - line_len = strlen(line); - if (line[line_len-1] == '\n') + if (line[line_len - 1] == '\n') { - line[line_len-1] = '\0'; + line[line_len - 1] = '\0'; } - user = strchr(line, '/'); password = strchr(user != NULL ? user : line, ' '); @@ -1096,7 +1029,6 @@ ncp_get_nwc_ent(FILE *nwc) *password = '\0'; password += 1; } - if (user != NULL) { *user = '\0'; @@ -1107,7 +1039,6 @@ ncp_get_nwc_ent(FILE *nwc) } strcpy(spec.user, user); } - if (strlen(line) >= sizeof(spec.server)) { continue; @@ -1143,12 +1074,10 @@ ncp_fopen_nwc(const char *user, const char *mode, long *err) { mode = "r"; } - if (user == NULL) { home = getenv("HOME"); - } - else + } else { struct passwd *pwd; @@ -1158,13 +1087,12 @@ ncp_fopen_nwc(const char *user, const char *mode, long *err) } } - if ( (home == NULL) - || (strlen(home) + sizeof(NWCLIENT) + 2 > sizeof(path))) + if ((home == NULL) + || (strlen(home) + sizeof(NWCLIENT) + 2 > sizeof(path))) { *err = ENAMETOOLONG; return NULL; } - strcpy(path, home); strcat(path, "/"); strcat(path, NWCLIENT); @@ -1174,13 +1102,11 @@ ncp_fopen_nwc(const char *user, const char *mode, long *err) *err = errno; return NULL; } - if ((st.st_mode & (S_IRWXO | S_IRWXG)) != 0) { *err = NCPL_ET_INVALID_MODE; return NULL; } - return fopen(path, mode); } @@ -1196,7 +1122,7 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, FILE *nwc; struct ncp_conn_spec *nwc_ent; - initialize_NCPL_error_table(); + initialize_NCPL_error_table(); *err = 0; memzero(spec); @@ -1210,15 +1136,13 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, return NULL; } strcpy(spec.server, server); - } - else + } else { if ((nwc = ncp_fopen_nwc(NULL, NULL, err)) == NULL) { *err = NCPL_ET_NO_SERVER; return NULL; } - nwc_ent = ncp_get_nwc_ent(nwc); fclose(nwc); @@ -1239,7 +1163,6 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, memset(spec.password, 0, sizeof(spec.password)); return &spec; } - if (user != NULL) { if (strlen(user) >= sizeof(spec.user)) @@ -1249,7 +1172,6 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, } strcpy(spec.user, user); } - str_upper(spec.user); spec.login_type = NCP_BINDERY_USER; @@ -1258,7 +1180,6 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, ncp_do_close(&conn); return &spec; } - if (password != NULL) { if (strlen(password) >= sizeof(spec.password)) @@ -1267,16 +1188,15 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, return NULL; } strcpy(spec.password, password); - } - else + } else { if ((nwc = ncp_fopen_nwc(NULL, NULL, err)) != NULL) { while ((nwc_ent = ncp_get_nwc_ent(nwc)) != NULL) { - if ( (strcasecmp(spec.server, - nwc_ent->server) != 0) - || ( (*spec.user != '\0') + if ((strcasecmp(spec.server, + nwc_ent->server) != 0) + || ((*spec.user != '\0') && (strcasecmp(spec.user, nwc_ent->user) != 0))) { @@ -1295,7 +1215,6 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, *err = NCPL_ET_NO_USER; return NULL; } - if ((strlen(spec.password) == 0) && (password == NULL)) { char *password; @@ -1312,8 +1231,7 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, return NULL; } strcpy(spec.password, password); - } - else + } else { if (strcmp(spec.password, NWC_NOPASSWORD) == 0) { @@ -1331,8 +1249,8 @@ struct ncp_conn * ncp_initialize_as(int *argc, char **argv, int login_necessary, int login_type, long *err) { - char *server = NULL; - char *user = NULL; + char *server = NULL; + char *user = NULL; char *password = NULL; struct ncp_conn_spec *spec; int i = 1; @@ -1343,40 +1261,38 @@ ncp_initialize_as(int *argc, char **argv, if (target != NULL) { - if (arg_no+1 >= *argc) + if (arg_no + 1 >= *argc) { /* No argument to switch */ errno = EINVAL; return -1; } - *target = argv[arg_no+1]; + *target = argv[arg_no + 1]; count = 2; } - /* Delete the consumed switch from the argument list and decrement the argument count */ - while (count+arg_no < *argc) + while (count + arg_no < *argc) { - argv[arg_no] = argv[arg_no+count]; + argv[arg_no] = argv[arg_no + count]; arg_no += 1; } *argc -= count; return 0; } - initialize_NCPL_error_table(); + initialize_NCPL_error_table(); *err = EINVAL; while (i < *argc) { - if ( (argv[i][0] != '-') + if ((argv[i][0] != '-') || (strlen(argv[i]) != 2)) { i += 1; continue; } - switch (argv[i][1]) { case 'S': @@ -1416,23 +1332,20 @@ ncp_initialize_as(int *argc, char **argv, if (login_necessary != 0) { return NULL; - } - else + } else { return ncp_open(NULL, err); } } - spec->login_type = login_type; if (login_necessary == 0) { spec->user[0] = '\0'; } - return ncp_open(spec, err); } - + struct ncp_conn * ncp_initialize(int *argc, char **argv, int login_necessary, long *err) @@ -1444,7 +1357,8 @@ ncp_initialize(int *argc, char **argv, static long ncp_request(struct ncp_conn *conn, int function) { - switch (conn->is_connected) { + switch (conn->is_connected) + { case CONN_PERMANENT: return ncp_mount_request(conn, function); case CONN_TEMPORARY: @@ -1463,17 +1377,18 @@ ncp_request(struct ncp_conn *conn, int function) static inline int min(int a, int b) { - return (asecond; - u_time.tm_min = source->minute; - u_time.tm_hour = source->hour; - u_time.tm_mday = source->day; - u_time.tm_mon = source->month - 1; - u_time.tm_year = source->year; + u_time.tm_sec = source->second; + u_time.tm_min = source->minute; + u_time.tm_hour = source->hour; + u_time.tm_mday = source->day; + u_time.tm_mon = source->month - 1; + u_time.tm_year = source->year; if (u_time.tm_year < 80) { u_time.tm_year += 100; } - return mktime(&u_time); } static void assert_conn_locked(struct ncp_conn *conn) { - if (conn->lock == 0) { + if (conn->lock == 0) + { ncp_printf("ncpfs: conn not locked!\n"); } } @@ -1509,25 +1424,43 @@ static void ncp_add_byte(struct ncp_conn *conn, byte x) { assert_conn_locked(conn); - *(byte *)(&(conn->packet[conn->current_size])) = x; + BSET(conn->packet, conn->current_size, x); conn->current_size += 1; return; } static void -ncp_add_word(struct ncp_conn *conn, word x) +ncp_add_word_lh(struct ncp_conn *conn, word x) { assert_conn_locked(conn); - *(word *)(&(conn->packet[conn->current_size])) = x; + WSET_LH(conn->packet, conn->current_size, x); conn->current_size += 2; return; } static void -ncp_add_dword(struct ncp_conn *conn, dword x) +ncp_add_dword_lh(struct ncp_conn *conn, dword x) { assert_conn_locked(conn); - *(dword *)(&(conn->packet[conn->current_size])) = x; + DSET_LH(conn->packet, conn->current_size, x); + conn->current_size += 4; + return; +} + +static void +ncp_add_word_hl(struct ncp_conn *conn, word x) +{ + assert_conn_locked(conn); + WSET_HL(conn->packet, conn->current_size, x); + conn->current_size += 2; + return; +} + +static void +ncp_add_dword_hl(struct ncp_conn *conn, dword x) +{ + assert_conn_locked(conn); + DSET_HL(conn->packet, conn->current_size, x); conn->current_size += 4; return; } @@ -1546,7 +1479,8 @@ ncp_add_pstring(struct ncp_conn *conn, const char *s) { int len = strlen(s); assert_conn_locked(conn); - if (len > 255) { + if (len > 255) + { ncp_printf("ncpfs: string too long: %s\n", s); len = 255; } @@ -1568,7 +1502,7 @@ static void ncp_init_request_s(struct ncp_conn *conn, int subfunction) { ncp_init_request(conn); - ncp_add_word(conn, 0); /* preliminary size */ + ncp_add_word_lh(conn, 0); /* preliminary size */ ncp_add_byte(conn, subfunction); @@ -1584,19 +1518,31 @@ ncp_reply_data(struct ncp_conn *conn, int offset) static byte ncp_reply_byte(struct ncp_conn *conn, int offset) { - return *(byte *)(ncp_reply_data(conn, offset)); + return *(byte *) (ncp_reply_data(conn, offset)); } static word -ncp_reply_word(struct ncp_conn *conn, int offset) +ncp_reply_word_hl(struct ncp_conn *conn, int offset) { - return *(word *)(ncp_reply_data(conn, offset)); + return WVAL_HL(ncp_reply_data(conn, offset), 0); +} + +static word +ncp_reply_word_lh(struct ncp_conn *conn, int offset) +{ + return WVAL_LH(ncp_reply_data(conn, offset), 0); } static dword -ncp_reply_dword(struct ncp_conn *conn, int offset) +ncp_reply_dword_hl(struct ncp_conn *conn, int offset) { - return *(dword *)(ncp_reply_data(conn, offset)); + return DVAL_HL(ncp_reply_data(conn, offset), 0); +} + +static dword +ncp_reply_dword_lh(struct ncp_conn *conn, int offset) +{ + return DVAL_LH(ncp_reply_data(conn, offset), 0); } /* Here the ncp calls begin @@ -1609,14 +1555,14 @@ ncp_negotiate_buffersize(struct ncp_conn *conn, long result; ncp_init_request(conn); - ncp_add_word(conn, htons(size)); - - if ((result = ncp_request(conn, 33)) != 0) { + ncp_add_word_hl(conn, size); + + if ((result = ncp_request(conn, 33)) != 0) + { ncp_unlock_conn(conn); return result; } - - *target =min(ntohs(ncp_reply_word(conn, 0)), size); + *target = min(ncp_reply_word_hl(conn, 0), size); ncp_unlock_conn(conn); return 0; @@ -1636,14 +1582,13 @@ ncp_get_file_server_description_strings(struct ncp_conn *conn, ncp_unlock_conn(conn); return result; } - memcpy(target, ncp_reply_data(conn, 0), 512); ncp_unlock_conn(conn); return 0; } long -ncp_get_file_server_time(struct ncp_conn *conn, time_t *target) +ncp_get_file_server_time(struct ncp_conn *conn, time_t * target) { long result; @@ -1654,14 +1599,13 @@ ncp_get_file_server_time(struct ncp_conn *conn, time_t *target) ncp_unlock_conn(conn); return result; } - - *target= nw_to_ctime((struct nw_time_buffer *)ncp_reply_data(conn, 0)); + *target = nw_to_ctime((struct nw_time_buffer *) ncp_reply_data(conn, 0)); ncp_unlock_conn(conn); return 0; } long -ncp_set_file_server_time(struct ncp_conn *conn, time_t *source) +ncp_set_file_server_time(struct ncp_conn *conn, time_t * source) { long result; int year; @@ -1672,10 +1616,9 @@ ncp_set_file_server_time(struct ncp_conn *conn, time_t *source) { year -= 100; } - ncp_init_request_s(conn, 202); ncp_add_byte(conn, year); - ncp_add_byte(conn, utime->tm_mon+1); + ncp_add_byte(conn, utime->tm_mon + 1); ncp_add_byte(conn, utime->tm_mday); ncp_add_byte(conn, utime->tm_hour); ncp_add_byte(conn, utime->tm_min); @@ -1697,16 +1640,15 @@ ncp_get_file_server_information(struct ncp_conn *conn, ncp_unlock_conn(conn); return result; } - memcpy(target, ncp_reply_data(conn, 0), sizeof(*target)); target->MaximumServiceConnections - = htons(target->MaximumServiceConnections); + = htons(target->MaximumServiceConnections); target->ConnectionsInUse - = htons(target->ConnectionsInUse); + = htons(target->ConnectionsInUse); target->MaxConnectionsEverUsed - = htons(target->MaxConnectionsEverUsed); + = htons(target->MaxConnectionsEverUsed); target->NumberMountedVolumes - = htons(target->NumberMountedVolumes); + = htons(target->NumberMountedVolumes); ncp_unlock_conn(conn); return 0; } @@ -1719,7 +1661,7 @@ ncp_get_connlist(struct ncp_conn *conn, long result; ncp_init_request_s(conn, 21); - ncp_add_word(conn, htons(object_type)); + ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); if ((result = ncp_request(conn, 23)) != 0) @@ -1727,7 +1669,6 @@ ncp_get_connlist(struct ncp_conn *conn, ncp_unlock_conn(conn); return result; } - *returned_no = ncp_reply_byte(conn, 0); memcpy(conn_numbers, ncp_reply_data(conn, 1), (*returned_no)); ncp_unlock_conn(conn); @@ -1738,11 +1679,11 @@ long ncp_get_stations_logged_info(struct ncp_conn *conn, __u32 connection, struct ncp_bindery_object *target, - time_t *login_time) + time_t * login_time) { long result; ncp_init_request_s(conn, 28); - ncp_add_dword(conn, connection); + ncp_add_dword_lh(conn, connection); if ((result = ncp_request(conn, 23)) != 0) { @@ -1750,8 +1691,8 @@ ncp_get_stations_logged_info(struct ncp_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)); + target->object_id = ncp_reply_dword_hl(conn, 0); + target->object_type = ncp_reply_word_hl(conn, 4); memcpy(target->object_name, ncp_reply_data(conn, 6), sizeof(target->object_name)); *login_time = nw_to_ctime((struct nw_time_buffer *) @@ -1764,22 +1705,21 @@ long ncp_get_internet_address(struct ncp_conn *conn, __u32 connection, struct sockaddr_ipx *target, - __u8 *conn_type) + __u8 * conn_type) { long result; ncp_init_request_s(conn, 26); - ncp_add_dword(conn, connection); + ncp_add_dword_lh(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); + target->sipx_network = ncp_reply_dword_lh(conn, 0); memcpy(&(target->sipx_node), ncp_reply_data(conn, 4), 6); - target->sipx_port = ncp_reply_word(conn, 10); + target->sipx_port = ncp_reply_word_lh(conn, 10); *conn_type = ncp_reply_byte(conn, 12); ncp_unlock_conn(conn); return 0; @@ -1787,7 +1727,7 @@ ncp_get_internet_address(struct ncp_conn *conn, long ncp_send_broadcast(struct ncp_conn *conn, - __u8 no_conn, const __u8 *connections, + __u8 no_conn, const __u8 * connections, const char *message) { long result; @@ -1796,10 +1736,9 @@ ncp_send_broadcast(struct ncp_conn *conn, { return NCPL_ET_MSG_TOO_LONG; } - ncp_init_request_s(conn, 0); ncp_add_byte(conn, no_conn); - ncp_add_mem(conn, (char *)(connections), no_conn); + ncp_add_mem(conn, (char *) (connections), no_conn); ncp_add_pstring(conn, message); result = ncp_request(conn, 21); @@ -1818,18 +1757,18 @@ ncp_get_encryption_key(struct ncp_conn *conn, ncp_init_request_s(conn, 23); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } - - if (conn->ncp_reply_size < 8) { + if (conn->ncp_reply_size < 8) + { ncp_printf("ncp_reply_size %d < 8\n", - conn->ncp_reply_size); + conn->ncp_reply_size); ncp_unlock_conn(conn); return result; } - memcpy(target, ncp_reply_data(conn, 0), 8); ncp_unlock_conn(conn); return 0; @@ -1843,23 +1782,23 @@ ncp_get_bindery_object_id(struct ncp_conn *conn, { long result; ncp_init_request_s(conn, 53); - ncp_add_word(conn, htons(object_type)); + ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } - - if (conn->ncp_reply_size < 54) { + if (conn->ncp_reply_size < 54) + { ncp_printf("ncp_reply_size %d < 54\n", - conn->ncp_reply_size); + conn->ncp_reply_size); ncp_unlock_conn(conn); return result; } - - target->object_id = ntohl(ncp_reply_dword(conn, 0)); - target->object_type = ntohs(ncp_reply_word (conn, 4)); + target->object_id = ncp_reply_dword_hl(conn, 0); + target->object_type = ncp_reply_word_hl(conn, 4); memcpy(target->object_name, ncp_reply_data(conn, 6), 48); ncp_unlock_conn(conn); return 0; @@ -1872,15 +1811,15 @@ ncp_get_bindery_object_name(struct ncp_conn *conn, { long result; ncp_init_request_s(conn, 54); - ncp_add_dword(conn, htonl(object_id)); + ncp_add_dword_hl(conn, object_id); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } - - target->object_id = ntohl(ncp_reply_dword(conn, 0)); - target->object_type = ntohs(ncp_reply_word (conn, 4)); + target->object_id = ncp_reply_dword_hl(conn, 0); + target->object_type = ncp_reply_word_hl(conn, 4); memcpy(target->object_name, ncp_reply_data(conn, 6), 48); ncp_unlock_conn(conn); return 0; @@ -1893,17 +1832,17 @@ ncp_scan_bindery_object(struct ncp_conn *conn, { long result; ncp_init_request_s(conn, 55); - ncp_add_dword(conn, htonl(last_id)); - ncp_add_word(conn, htons(object_type)); + ncp_add_dword_hl(conn, last_id); + ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, search_string); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } - - target->object_id = ntohl(ncp_reply_dword(conn, 0)); - target->object_type = ntohs(ncp_reply_word(conn, 4)); + target->object_id = ncp_reply_dword_hl(conn, 0); + target->object_type = ncp_reply_word_hl(conn, 4); memcpy(target->object_name, ncp_reply_data(conn, 6), NCP_BINDERY_NAME_LEN); target->object_flags = ncp_reply_byte(conn, 54); @@ -1913,7 +1852,7 @@ ncp_scan_bindery_object(struct ncp_conn *conn, ncp_unlock_conn(conn); return 0; } - + long ncp_create_bindery_object(struct ncp_conn *conn, __u16 object_type, @@ -1925,7 +1864,7 @@ ncp_create_bindery_object(struct ncp_conn *conn, ncp_init_request_s(conn, 50); ncp_add_byte(conn, object_status); ncp_add_byte(conn, object_security); - ncp_add_word(conn, htons(object_type)); + ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); result = ncp_request(conn, 23); @@ -1941,7 +1880,7 @@ ncp_delete_bindery_object(struct ncp_conn *conn, { long result; ncp_init_request_s(conn, 51); - ncp_add_word(conn, htons(object_type)); + ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); result = ncp_request(conn, 23); @@ -1957,16 +1896,16 @@ ncp_read_property_value(struct ncp_conn *conn, { long result; ncp_init_request_s(conn, 61); - ncp_add_word(conn, htons(object_type)); + ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); ncp_add_byte(conn, segment); ncp_add_pstring(conn, prop_name); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } - memcpy(&(target->value), ncp_reply_data(conn, 0), 128); target->more_flag = ncp_reply_byte(conn, 128); target->property_flag = ncp_reply_byte(conn, 129); @@ -1979,26 +1918,26 @@ long ncp_scan_property(struct ncp_conn *conn, __u16 object_type, const char *object_name, __u32 last_id, char *search_string, - struct ncp_property_info *property_info) + struct ncp_property_info *property_info) { long result; ncp_init_request_s(conn, 60); - ncp_add_word(conn, htons(object_type)); + ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); - ncp_add_dword(conn, htonl(last_id)); + ncp_add_dword_hl(conn, last_id); ncp_add_pstring(conn, search_string); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } - - memcpy(property_info->property_name,ncp_reply_data(conn, 0), 16); - property_info->property_flags = ncp_reply_byte(conn,16); - property_info->property_security = ncp_reply_byte(conn,17); - property_info->search_instance = ntohl(ncp_reply_dword(conn,18)); - property_info->value_available_flag = ncp_reply_byte(conn,22); - property_info->more_properties_flag = ncp_reply_byte(conn,23); + memcpy(property_info->property_name, ncp_reply_data(conn, 0), 16); + property_info->property_flags = ncp_reply_byte(conn, 16); + property_info->property_security = ncp_reply_byte(conn, 17); + property_info->search_instance = ncp_reply_dword_hl(conn, 18); + property_info->value_available_flag = ncp_reply_byte(conn, 22); + property_info->more_properties_flag = ncp_reply_byte(conn, 23); ncp_unlock_conn(conn); return 0; } @@ -2012,10 +1951,10 @@ ncp_add_object_to_set(struct ncp_conn *conn, { long result; ncp_init_request_s(conn, 65); - ncp_add_word(conn, htons(object_type)); + ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); ncp_add_pstring(conn, property_name); - ncp_add_word(conn, htons(member_type)); + ncp_add_word_hl(conn, member_type); ncp_add_pstring(conn, member_name); result = ncp_request(conn, 23); @@ -2026,12 +1965,12 @@ ncp_add_object_to_set(struct ncp_conn *conn, long ncp_change_property_security(struct ncp_conn *conn, __u16 object_type, const char *object_name, - const char *property_name, + const char *property_name, __u8 property_security) { long result; ncp_init_request_s(conn, 59); - ncp_add_word(conn, htons(object_type)); + ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); ncp_add_byte(conn, property_security); ncp_add_pstring(conn, property_name); @@ -2043,13 +1982,13 @@ ncp_change_property_security(struct ncp_conn *conn, long ncp_create_property(struct ncp_conn *conn, - __u16 object_type, const char *object_name, - const char *property_name, - __u8 property_flags, __u8 property_security) + __u16 object_type, const char *object_name, + const char *property_name, + __u8 property_flags, __u8 property_security) { long result; ncp_init_request_s(conn, 57); - ncp_add_word(conn, htons(object_type)); + ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); ncp_add_byte(conn, property_flags); ncp_add_byte(conn, property_security); @@ -2069,10 +2008,10 @@ ncp_delete_object_from_set(struct ncp_conn *conn, { long result; ncp_init_request_s(conn, 66); - ncp_add_word(conn, htons(object_type)); + ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); ncp_add_pstring(conn, property_name); - ncp_add_word(conn, htons(member_type)); + ncp_add_word_hl(conn, member_type); ncp_add_pstring(conn, member_name); result = ncp_request(conn, 23); @@ -2080,14 +2019,14 @@ ncp_delete_object_from_set(struct ncp_conn *conn, return result; } -long +long ncp_delete_property(struct ncp_conn *conn, __u16 object_type, const char *object_name, const char *property_name) { long result; ncp_init_request_s(conn, 58); - ncp_add_word(conn, htons(object_type)); + ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); ncp_add_pstring(conn, property_name); @@ -2098,16 +2037,16 @@ ncp_delete_property(struct ncp_conn *conn, long ncp_write_property_value(struct ncp_conn *conn, - __u16 object_type, const char *object_name, - const char *property_name, + __u16 object_type, const char *object_name, + const char *property_name, __u8 segment, struct nw_property *property_value) { long result; ncp_init_request_s(conn, 62); - ncp_add_word(conn, htons(object_type)); + ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); - ncp_add_byte(conn,segment); + ncp_add_byte(conn, segment); ncp_add_byte(conn, property_value->more_flag); ncp_add_pstring(conn, property_name); ncp_add_mem(conn, property_value->value, 128); @@ -2120,14 +2059,14 @@ ncp_write_property_value(struct ncp_conn *conn, long ncp_get_big_ncp_max_packet_size(struct ncp_conn *conn, __u16 proposed_max_size, - __u8 proposed_security_flag, - __u16 *accepted_max_size, - __u16 *echo_socket, - __u8 *accepted_security_flag) + __u8 proposed_security_flag, + __u16 * accepted_max_size, + __u16 * echo_socket, + __u8 * accepted_security_flag) { long result; ncp_init_request(conn); - ncp_add_word(conn, htons(proposed_max_size)); + ncp_add_word_hl(conn, proposed_max_size); ncp_add_byte(conn, proposed_security_flag); if ((result = ncp_request(conn, 97)) != 0) @@ -2135,8 +2074,8 @@ ncp_get_big_ncp_max_packet_size(struct ncp_conn *conn, ncp_unlock_conn(conn); return result; } - *accepted_max_size = ntohs(ncp_reply_word(conn, 0)); - *echo_socket = ntohs(ncp_reply_word(conn, 2)); + *accepted_max_size = ncp_reply_word_hl(conn, 0); + *echo_socket = ncp_reply_word_hl(conn, 2); *accepted_security_flag = ncp_reply_byte(conn, 4); ncp_unlock_conn(conn); return 0; @@ -2153,12 +2092,12 @@ ncp_login_encrypted(struct ncp_conn *conn, unsigned char encrypted[8]; long result; - shuffle((byte *)&tmpID, passwd, strlen(passwd), buf); + shuffle((byte *) & tmpID, passwd, strlen(passwd), buf); nw_encrypt(key, buf, encrypted); ncp_init_request_s(conn, 24); ncp_add_mem(conn, encrypted, 8); - ncp_add_word(conn, htons(object->object_type)); + ncp_add_word_hl(conn, object->object_type); ncp_add_pstring(conn, object->object_name); result = ncp_request(conn, 23); @@ -2173,7 +2112,7 @@ ncp_login_unencrypted(struct ncp_conn *conn, { long result; ncp_init_request_s(conn, 20); - ncp_add_word(conn, htons(object_type)); + ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); ncp_add_pstring(conn, passwd); result = ncp_request(conn, 23); @@ -2190,17 +2129,17 @@ ncp_change_login_passwd(struct ncp_conn *conn, { long id = htonl(object->object_id); unsigned char cryptkey[8]; - unsigned char newpwd[16]; /* new passwd as stored by server */ - unsigned char oldpwd[16]; /* old passwd as stored by server */ + unsigned char newpwd[16]; /* new passwd as stored by server */ + unsigned char oldpwd[16]; /* old passwd as stored by server */ unsigned char len; long result; memcpy(cryptkey, key, 8); - shuffle((byte *)&id, oldpasswd, strlen(oldpasswd), oldpwd); - shuffle((byte *)&id, newpasswd, strlen(newpasswd), newpwd); + shuffle((byte *) & id, oldpasswd, strlen(oldpasswd), oldpwd); + shuffle((byte *) & id, newpasswd, strlen(newpasswd), newpwd); nw_encrypt(cryptkey, oldpwd, cryptkey); newpassencrypt(oldpwd, newpwd, newpwd); - newpassencrypt(oldpwd+8, newpwd+8, newpwd+8); + newpassencrypt(oldpwd + 8, newpwd + 8, newpwd + 8); if ((len = strlen(newpasswd)) > 63) { len = 63; @@ -2209,7 +2148,7 @@ ncp_change_login_passwd(struct ncp_conn *conn, ncp_init_request_s(conn, 75); ncp_add_mem(conn, cryptkey, 8); - ncp_add_word(conn, htons(object->object_type)); + ncp_add_word_hl(conn, object->object_type); ncp_add_pstring(conn, object->object_name); ncp_add_byte(conn, len); ncp_add_mem(conn, newpwd, 16); @@ -2225,7 +2164,7 @@ ncp_login_user(struct ncp_conn *conn, { return ncp_login_object(conn, username, NCP_BINDERY_USER, password); } - + static long ncp_login_object(struct ncp_conn *conn, const unsigned char *username, @@ -2236,28 +2175,27 @@ ncp_login_object(struct ncp_conn *conn, unsigned char ncp_key[8]; struct ncp_bindery_object user; - if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0) { + if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0) + { return ncp_login_unencrypted(conn, login_type, username, password); } - if ((result = ncp_get_bindery_object_id(conn, login_type, - username, &user)) != 0) { + username, &user)) != 0) + { return result; } - if ((result = ncp_login_encrypted(conn, &user, ncp_key, password)) != 0) { struct nw_property p; struct ncp_prop_login_control *l - = (struct ncp_prop_login_control *)&p; + = (struct ncp_prop_login_control *) &p; if (conn->completion != NCP_GRACE_PERIOD) { return result; } - fprintf(stderr, "Your password has expired\n"); if ((result = ncp_read_property_value(conn, NCP_BINDERY_USER, @@ -2282,28 +2220,28 @@ ncp_get_volume_info_with_number(struct ncp_conn *conn, int n, ncp_init_request_s(conn, 44); ncp_add_byte(conn, n); - if ((result = ncp_request(conn, 22)) != 0) { + if ((result = ncp_request(conn, 22)) != 0) + { ncp_unlock_conn(conn); return result; } - - target->total_blocks = ncp_reply_dword(conn, 0); - target->free_blocks = ncp_reply_dword(conn, 4); - target->purgeable_blocks = ncp_reply_dword(conn, 8); - target->not_yet_purgeable_blocks = ncp_reply_dword(conn, 12); - target->total_dir_entries = ncp_reply_dword(conn, 16); - target->available_dir_entries = ncp_reply_dword(conn, 20); + target->total_blocks = ncp_reply_dword_lh(conn, 0); + target->free_blocks = ncp_reply_dword_lh(conn, 4); + target->purgeable_blocks = ncp_reply_dword_lh(conn, 8); + target->not_yet_purgeable_blocks = ncp_reply_dword_lh(conn, 12); + target->total_dir_entries = ncp_reply_dword_lh(conn, 16); + target->available_dir_entries = ncp_reply_dword_lh(conn, 20); target->sectors_per_block = ncp_reply_byte(conn, 28); memzero(target->volume_name); len = ncp_reply_byte(conn, 29); - if (len > NCP_VOLNAME_LEN) { + if (len > NCP_VOLNAME_LEN) + { ncp_printf("ncpfs: volume name too long: %d\n", len); ncp_unlock_conn(conn); return -EIO; } - memcpy(&(target->volume_name), ncp_reply_data(conn, 30), len); ncp_unlock_conn(conn); return 0; @@ -2317,11 +2255,11 @@ ncp_get_volume_number(struct ncp_conn *conn, const char *name, int *target) ncp_init_request_s(conn, 5); ncp_add_pstring(conn, name); - if ((result = ncp_request(conn, 22)) != 0) { + if ((result = ncp_request(conn, 22)) != 0) + { ncp_unlock_conn(conn); return result; } - *target = ncp_reply_byte(conn, 0); ncp_unlock_conn(conn); return 0; @@ -2339,19 +2277,19 @@ ncp_file_search_init(struct ncp_conn *conn, ncp_add_byte(conn, dir_handle); ncp_add_pstring(conn, path); - if ((result = ncp_request(conn, 62)) != 0) { + if ((result = ncp_request(conn, 62)) != 0) + { ncp_unlock_conn(conn); return result; } - target->volume_number = ncp_reply_byte(conn, 0); - target->directory_id = ntohs(ncp_reply_word(conn, 1)); - target->sequence_no = ntohs(ncp_reply_word(conn, 3)); + target->directory_id = ncp_reply_word_hl(conn, 1); + target->sequence_no = ncp_reply_word_hl(conn, 3); target->access_rights = ncp_reply_byte(conn, 5); ncp_unlock_conn(conn); return 0; } - + long ncp_file_search_continue(struct ncp_conn *conn, @@ -2364,30 +2302,30 @@ ncp_file_search_continue(struct ncp_conn *conn, ncp_init_request(conn); ncp_add_byte(conn, fsinfo->volume_number); - ncp_add_word(conn, htons(fsinfo->directory_id)); - ncp_add_word(conn, htons(fsinfo->sequence_no)); + ncp_add_word_hl(conn, fsinfo->directory_id); + ncp_add_word_hl(conn, fsinfo->sequence_no); ncp_add_byte(conn, attributes); ncp_add_pstring(conn, name); - if ((result = ncp_request(conn, 63)) != 0) { + if ((result = ncp_request(conn, 63)) != 0) + { ncp_unlock_conn(conn); return result; } - - fsinfo->sequence_no = ntohs(ncp_reply_word(conn, 0)); + fsinfo->sequence_no = ncp_reply_word_hl(conn, 0); memzero(target->file_name); memcpy(&(target->file_name), ncp_reply_data(conn, 4), NCP_MAX_FILENAME); target->file_attributes = ncp_reply_byte(conn, 18); - target->file_mode = ncp_reply_byte(conn, 19); - target->file_length = ntohl(ncp_reply_dword(conn, 20)); - target->creation_date = ntohs(ncp_reply_word(conn, 24)); - target->access_date = ntohs(ncp_reply_word(conn, 26)); - target->update_date = ntohs(ncp_reply_word(conn, 28)); - target->update_time = ntohs(ncp_reply_word(conn, 30)); + target->file_mode = ncp_reply_byte(conn, 19); + target->file_length = ncp_reply_dword_hl(conn, 20); + target->creation_date = ncp_reply_word_hl(conn, 24); + target->access_date = ncp_reply_word_hl(conn, 26); + target->update_date = ncp_reply_word_hl(conn, 28); + target->update_time = ncp_reply_word_hl(conn, 30); ncp_unlock_conn(conn); return 0; @@ -2403,20 +2341,20 @@ ncp_get_finfo(struct ncp_conn *conn, struct ncp_filesearch_info fsinfo; if ((result = ncp_file_search_init(conn, dir_handle, path, - &fsinfo)) != 0) { + &fsinfo)) != 0) + { return result; } - if ((result = ncp_file_search_continue(conn, &fsinfo, 0, name, - target)) == 0) { + target)) == 0) + { return result; } - if ((result = ncp_file_search_init(conn, dir_handle, path, - &fsinfo)) != 0) { + &fsinfo)) != 0) + { return result; } - return ncp_file_search_continue(conn, &fsinfo, aDIR, name, target); } @@ -2434,25 +2372,25 @@ ncp_open_file(struct ncp_conn *conn, ncp_add_byte(conn, access); ncp_add_pstring(conn, path); - if ((result = ncp_request(conn, 76)) != 0) { + if ((result = ncp_request(conn, 76)) != 0) + { ncp_unlock_conn(conn); return result; } - memcpy(&(target->file_id), ncp_reply_data(conn, 0), NCP_FILE_ID_LEN); - + memzero(target->file_name); memcpy(&(target->file_name), ncp_reply_data(conn, 8), NCP_MAX_FILENAME); target->file_attributes = ncp_reply_byte(conn, 22); - target->file_mode = ncp_reply_byte(conn, 23); - target->file_length = ntohl(ncp_reply_dword(conn, 24)); - target->creation_date = ntohs(ncp_reply_word(conn, 28)); - target->access_date = ntohs(ncp_reply_word(conn, 30)); - target->update_date = ntohs(ncp_reply_word(conn, 32)); - target->update_time = ntohs(ncp_reply_word(conn, 34)); + target->file_mode = ncp_reply_byte(conn, 23); + target->file_length = ncp_reply_dword_hl(conn, 24); + target->creation_date = ncp_reply_word_hl(conn, 28); + target->access_date = ncp_reply_word_hl(conn, 30); + target->update_date = ncp_reply_word_hl(conn, 32); + target->update_time = ncp_reply_word_hl(conn, 34); ncp_unlock_conn(conn); return 0; @@ -2480,35 +2418,35 @@ ncp_do_create(struct ncp_conn *conn, int function) { long result; - + ncp_init_request(conn); ncp_add_byte(conn, dir_handle); ncp_add_byte(conn, attr); ncp_add_pstring(conn, path); - if ((result = ncp_request(conn, function)) != 0) { + if ((result = ncp_request(conn, function)) != 0) + { ncp_unlock_conn(conn); return result; } - memcpy(&(target->file_id), ncp_reply_data(conn, 0), NCP_FILE_ID_LEN); - + memzero(target->file_name); memcpy(&(target->file_name), ncp_reply_data(conn, 8), NCP_MAX_FILENAME); target->file_attributes = ncp_reply_byte(conn, 22); - target->file_mode = ncp_reply_byte(conn, 23); - target->file_length = ntohl(ncp_reply_dword(conn, 24)); - target->creation_date = ntohs(ncp_reply_word(conn, 28)); - target->access_date = ntohs(ncp_reply_word(conn, 30)); - target->update_date = ntohs(ncp_reply_word(conn, 32)); - target->update_time = ntohs(ncp_reply_word(conn, 34)); + target->file_mode = ncp_reply_byte(conn, 23); + target->file_length = ncp_reply_dword_hl(conn, 24); + target->creation_date = ncp_reply_word_hl(conn, 28); + target->access_date = ncp_reply_word_hl(conn, 30); + target->update_date = ncp_reply_word_hl(conn, 32); + target->update_time = ncp_reply_word_hl(conn, 34); ncp_unlock_conn(conn); return 0; -} +} long ncp_create_newfile(struct ncp_conn *conn, @@ -2544,7 +2482,7 @@ ncp_erase_file(struct ncp_conn *conn, ncp_unlock_conn(conn); return result; } - + long ncp_rename_file(struct ncp_conn *conn, int old_handle, const char *old_path, @@ -2560,11 +2498,11 @@ ncp_rename_file(struct ncp_conn *conn, ncp_add_byte(conn, new_handle); ncp_add_pstring(conn, new_path); - if ((result = ncp_request(conn, 69)) != 0) { + if ((result = ncp_request(conn, 69)) != 0) + { ncp_unlock_conn(conn); return result; } - ncp_unlock_conn(conn); return 0; } @@ -2611,7 +2549,7 @@ ncp_add_trustee(struct ncp_conn *conn, ncp_init_request_s(conn, 13); ncp_add_byte(conn, dir_handle); - ncp_add_dword(conn, htonl(object_id)); + ncp_add_dword_hl(conn, object_id); ncp_add_byte(conn, rights); ncp_add_pstring(conn, path); @@ -2622,13 +2560,13 @@ ncp_add_trustee(struct ncp_conn *conn, long ncp_delete_trustee(struct ncp_conn *conn, - int dir_handle, const char *path,__u32 object_id) + int dir_handle, const char *path, __u32 object_id) { long result; ncp_init_request_s(conn, 14); ncp_add_byte(conn, dir_handle); - ncp_add_dword(conn, htonl(object_id)); + ncp_add_dword_hl(conn, object_id); ncp_add_byte(conn, 0); ncp_add_pstring(conn, path); @@ -2661,17 +2599,19 @@ ncp_add_handle_path(struct ncp_conn *conn, const char *path) { ncp_add_byte(conn, vol_num); - ncp_add_dword(conn, dir_base); - if (have_dir_base != 0) { - ncp_add_byte(conn, 1); /* dir_base */ - } else { - ncp_add_byte(conn, 0xff); /* no handle */ + ncp_add_dword_lh(conn, dir_base); + if (have_dir_base != 0) + { + ncp_add_byte(conn, 1); /* dir_base */ + } else + { + ncp_add_byte(conn, 0xff); /* no handle */ } - if (path != NULL) { - ncp_add_byte(conn, 1); /* 1 component */ + if (path != NULL) + { + ncp_add_byte(conn, 1); /* 1 component */ ncp_add_pstring(conn, path); - } - else + } else { ncp_add_byte(conn, 0); } @@ -2686,7 +2626,7 @@ ncp_extract_file_info(void *structure, struct nw_info_struct *target) memcpy(target, structure, info_struct_size); name_len = structure + info_struct_size; target->nameLen = *name_len; - strncpy(target->entryName, name_len+1, *name_len); + strncpy(target->entryName, name_len + 1, *name_len); target->entryName[*name_len] = '\0'; return; } @@ -2704,8 +2644,8 @@ ncp_obtain_file_or_subdir_info(struct ncp_conn *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_word_lh(conn, search_attribs); + ncp_add_dword_lh(conn, rim); ncp_add_handle_path(conn, vol, dirent, 1, path); if ((result = ncp_request(conn, 87)) != 0) @@ -2716,14 +2656,14 @@ ncp_obtain_file_or_subdir_info(struct ncp_conn *conn, ncp_extract_file_info(ncp_reply_data(conn, 0), target); ncp_unlock_conn(conn); return 0; -} +} long ncp_get_eff_directory_rights(struct ncp_conn *conn, __u8 source_ns, __u8 target_ns, __u16 search_attribs, __u8 vol, __u32 dirent, const char *path, - __u16 *my_effective_rights) + __u16 * my_effective_rights) { long result; @@ -2731,8 +2671,8 @@ ncp_get_eff_directory_rights(struct ncp_conn *conn, ncp_add_byte(conn, 29); ncp_add_byte(conn, source_ns); ncp_add_byte(conn, target_ns); - ncp_add_word(conn, search_attribs); - ncp_add_dword(conn, 0); + ncp_add_word_lh(conn, search_attribs); + ncp_add_dword_lh(conn, 0); ncp_add_handle_path(conn, vol, dirent, 1, path); if ((result = ncp_request(conn, 87)) != 0) @@ -2740,8 +2680,7 @@ ncp_get_eff_directory_rights(struct ncp_conn *conn, ncp_unlock_conn(conn); return result; } - - *my_effective_rights = ncp_reply_word(conn, 0); + *my_effective_rights = ncp_reply_word_lh(conn, 0); ncp_unlock_conn(conn); return 0; } @@ -2752,65 +2691,65 @@ ncp_do_lookup(struct ncp_conn *conn, char *path, /* may only be one component */ struct nw_info_struct *target) { - __u8 vol_num; + __u8 vol_num; __u32 dir_base; long result; char *volname = NULL; - if (target == NULL) { + if (target == NULL) + { return -EINVAL; } - - if (dir == NULL) { + if (dir == NULL) + { /* Access a volume's root directory */ ncp_init_request(conn); - ncp_add_byte(conn, 22); /* subfunction */ - ncp_add_byte(conn, 0); /* dos name space */ - ncp_add_byte(conn, 0); /* reserved */ - ncp_add_byte(conn, 0); /* reserved */ - ncp_add_byte(conn, 0); /* reserved */ - ncp_add_handle_path(conn, 0, 0, 0, /* no handle */ + ncp_add_byte(conn, 22); /* subfunction */ + ncp_add_byte(conn, 0); /* dos name space */ + ncp_add_byte(conn, 0); /* reserved */ + ncp_add_byte(conn, 0); /* reserved */ + ncp_add_byte(conn, 0); /* reserved */ + ncp_add_handle_path(conn, 0, 0, 0, /* no handle */ path); - if ((result = ncp_request(conn, 87)) != 0) { + if ((result = ncp_request(conn, 87)) != 0) + { ncp_unlock_conn(conn); return result; } - - dir_base = ncp_reply_dword(conn, 4); - vol_num = ncp_reply_byte (conn, 8); + dir_base = ncp_reply_dword_lh(conn, 4); + vol_num = ncp_reply_byte(conn, 8); ncp_unlock_conn(conn); volname = path; path = NULL; - } - else + } else { vol_num = dir->volNumber; dir_base = dir->DosDirNum; } ncp_init_request(conn); - ncp_add_byte(conn, 6); /* subfunction */ - ncp_add_byte(conn, 0); /* dos name space */ - ncp_add_byte(conn, 0); /* dos name space as dest */ - ncp_add_word(conn, 0xff); /* get all */ - ncp_add_dword(conn, RIM_ALL); + ncp_add_byte(conn, 6); /* subfunction */ + ncp_add_byte(conn, 0); /* dos name space */ + ncp_add_byte(conn, 0); /* dos name space as dest */ + ncp_add_word_lh(conn, 0xff); /* get all */ + ncp_add_dword_lh(conn, RIM_ALL); ncp_add_handle_path(conn, vol_num, dir_base, 1, path); - if ((result = ncp_request(conn, 87)) != 0) { + if ((result = ncp_request(conn, 87)) != 0) + { ncp_unlock_conn(conn); return result; } - ncp_extract_file_info(ncp_reply_data(conn, 0), target); - if (volname != NULL) { + if (volname != NULL) + { target->nameLen = strlen(volname); strcpy(target->entryName, volname); } - ncp_unlock_conn(conn); return 0; } @@ -2827,9 +2766,9 @@ ncp_modify_file_or_subdir_dos_info(struct ncp_conn *conn, ncp_add_byte(conn, 7); /* subfunction */ ncp_add_byte(conn, 0); /* dos name space */ ncp_add_byte(conn, 0); /* reserved */ - ncp_add_word(conn, 0x8006); /* search attribs: all */ + ncp_add_word_lh(conn, 0x8006); /* search attribs: all */ - ncp_add_dword(conn, info_mask); + ncp_add_dword_lh(conn, info_mask); ncp_add_mem(conn, info, sizeof(*info)); ncp_add_handle_path(conn, file->volNumber, file->DosDirNum, 1, NULL); @@ -2838,7 +2777,7 @@ ncp_modify_file_or_subdir_dos_info(struct ncp_conn *conn, ncp_unlock_conn(conn); return result; } - + long ncp_del_file_or_subdir(struct ncp_conn *conn, struct nw_info_struct *dir, char *name) @@ -2849,22 +2788,22 @@ ncp_del_file_or_subdir(struct ncp_conn *conn, ncp_add_byte(conn, 8); /* subfunction */ ncp_add_byte(conn, 0); /* dos name space */ ncp_add_byte(conn, 0); /* reserved */ - ncp_add_word(conn, 0x8006); /* search attribs: all */ + ncp_add_word_lh(conn, 0x8006); /* search attribs: all */ ncp_add_handle_path(conn, dir->volNumber, dir->DosDirNum, 1, name); - + result = ncp_request(conn, 87); ncp_unlock_conn(conn); return result; } static inline void -ConvertToNWfromDWORD ( __u32 sfd , __u8 ret[6] ) +ConvertToNWfromDWORD(__u32 sfd, __u8 ret[6]) { - __u16 *dest = (__u16 *) ret; - memcpy(&(dest[1]), &sfd, 4); - dest[0] = dest[1] + 1; - return; + __u16 *dest = (__u16 *) ret; + memcpy(&(dest[1]), &sfd, 4); + dest[0] = dest[1] + 1; + return; } long @@ -2880,25 +2819,25 @@ ncp_open_create_file_or_subdir(struct ncp_conn *conn, target->opened = 0; ncp_init_request(conn); - ncp_add_byte(conn, 1); /* subfunction */ - ncp_add_byte(conn, 0); /* dos name space */ + ncp_add_byte(conn, 1); /* subfunction */ + ncp_add_byte(conn, 0); /* dos name space */ ncp_add_byte(conn, open_create_mode); - ncp_add_word(conn, 0x8006); - ncp_add_dword(conn, RIM_ALL); - ncp_add_dword(conn, create_attributes); + ncp_add_word_lh(conn, 0x8006); + ncp_add_dword_lh(conn, RIM_ALL); + ncp_add_dword_lh(conn, create_attributes); /* The desired acc rights seem to be the inherited rights mask for directories */ - ncp_add_word(conn, desired_acc_rights); + ncp_add_word_lh(conn, desired_acc_rights); ncp_add_handle_path(conn, dir->volNumber, dir->DosDirNum, 1, name); - if ((result = ncp_request(conn, 87)) != 0) { + if ((result = ncp_request(conn, 87)) != 0) + { ncp_unlock_conn(conn); return result; } - target->opened = 1; - target->server_file_handle = ncp_reply_dword(conn, 0); + target->server_file_handle = ncp_reply_dword_lh(conn, 0); target->open_create_action = ncp_reply_byte(conn, 4); ncp_extract_file_info(ncp_reply_data(conn, 5), &(target->i)); ConvertToNWfromDWORD(target->server_file_handle, target->file_handle); @@ -2919,28 +2858,27 @@ ncp_initialize_search(struct ncp_conn *conn, { return EINVAL; } - memzero(*target); ncp_init_request(conn); - ncp_add_byte(conn, 2); /* subfunction */ + ncp_add_byte(conn, 2); /* subfunction */ ncp_add_byte(conn, namespace); - ncp_add_byte(conn, 0); /* reserved */ + ncp_add_byte(conn, 0); /* reserved */ ncp_add_handle_path(conn, dir->volNumber, dir->DosDirNum, 1, NULL); - - if ((result = ncp_request(conn, 87)) != 0) { + + if ((result = ncp_request(conn, 87)) != 0) + { ncp_unlock_conn(conn); return result; } - memcpy(&(target->s), ncp_reply_data(conn, 0), 9); target->namespace = namespace; ncp_unlock_conn(conn); return 0; } - + /* Search for everything */ long ncp_search_for_file_or_subdir(struct ncp_conn *conn, @@ -2950,21 +2888,21 @@ ncp_search_for_file_or_subdir(struct ncp_conn *conn, long result; ncp_init_request(conn); - ncp_add_byte(conn, 3); /* subfunction */ - ncp_add_byte(conn, seq->namespace); - ncp_add_byte(conn, 0); /* data stream (???) */ - ncp_add_word(conn, 0xffff); /* Search attribs */ - ncp_add_dword(conn, RIM_ALL); /* return info mask */ + ncp_add_byte(conn, 3); /* subfunction */ + ncp_add_byte(conn, seq->namespace); + ncp_add_byte(conn, 0); /* data stream (???) */ + ncp_add_word_lh(conn, 0xffff); /* Search attribs */ + ncp_add_dword_lh(conn, RIM_ALL); /* return info mask */ ncp_add_mem(conn, &(seq->s), 9); - ncp_add_byte(conn, 2); /* 2 byte pattern */ - ncp_add_byte(conn, 0xff); /* following is a wildcard */ + ncp_add_byte(conn, 2); /* 2 byte pattern */ + ncp_add_byte(conn, 0xff); /* following is a wildcard */ ncp_add_byte(conn, '*'); - - if ((result = ncp_request(conn, 87)) != 0) { + + if ((result = ncp_request(conn, 87)) != 0) + { ncp_unlock_conn(conn); return result; } - memcpy(seq, ncp_reply_data(conn, 0), sizeof(*seq)); ncp_extract_file_info(ncp_reply_data(conn, 10), target); @@ -2979,27 +2917,27 @@ ncp_ren_or_mov_file_or_subdir(struct ncp_conn *conn, { long result; - if ( (old_dir == NULL) || (old_name == NULL) + if ((old_dir == NULL) || (old_name == NULL) || (new_dir == NULL) || (new_name == NULL)) return -EINVAL; - + ncp_init_request(conn); - ncp_add_byte(conn, 4); /* subfunction */ - ncp_add_byte(conn, 0); /* dos name space */ - ncp_add_byte(conn, 1); /* rename flag */ - ncp_add_word(conn, 0x8006); /* search attributes */ + ncp_add_byte(conn, 4); /* subfunction */ + ncp_add_byte(conn, 0); /* dos name space */ + ncp_add_byte(conn, 1); /* rename flag */ + ncp_add_word_lh(conn, 0x8006); /* search attributes */ /* source Handle Path */ ncp_add_byte(conn, old_dir->volNumber); - ncp_add_dword(conn, old_dir->DosDirNum); + ncp_add_dword_lh(conn, old_dir->DosDirNum); ncp_add_byte(conn, 1); - ncp_add_byte(conn, 1); /* 1 source component */ + ncp_add_byte(conn, 1); /* 1 source component */ /* dest Handle Path */ ncp_add_byte(conn, new_dir->volNumber); - ncp_add_dword(conn, new_dir->DosDirNum); + ncp_add_dword_lh(conn, new_dir->DosDirNum); ncp_add_byte(conn, 1); - ncp_add_byte(conn, 1); /* 1 destination component */ + ncp_add_byte(conn, 1); /* 1 destination component */ /* source path string */ ncp_add_pstring(conn, old_name); @@ -3010,7 +2948,7 @@ ncp_ren_or_mov_file_or_subdir(struct ncp_conn *conn, ncp_unlock_conn(conn); return result; } - + /* Create a new job entry */ long @@ -3021,14 +2959,14 @@ ncp_create_queue_job_and_file(struct ncp_conn *conn, long result; ncp_init_request_s(conn, 121); - ncp_add_dword(conn, htonl(queue_id)); + ncp_add_dword_hl(conn, queue_id); ncp_add_mem(conn, &(job->j), sizeof(job->j)); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } - memcpy(&(job->j), ncp_reply_data(conn, 0), 78); ConvertToNWfromDWORD(job->j.JobFileHandle, job->file_handle); @@ -3044,8 +2982,8 @@ ncp_close_file_and_start_job(struct ncp_conn *conn, long result; ncp_init_request_s(conn, 127); - ncp_add_dword(conn, htonl(queue_id)); - ncp_add_dword(conn, job->j.JobNumber); + ncp_add_dword_hl(conn, queue_id); + ncp_add_dword_lh(conn, job->j.JobNumber); result = ncp_request(conn, 23); ncp_unlock_conn(conn); @@ -3059,7 +2997,7 @@ ncp_attach_to_queue(struct ncp_conn *conn, long result; ncp_init_request_s(conn, 111); - ncp_add_dword(conn, htonl(queue_id)); + ncp_add_dword_hl(conn, queue_id); result = ncp_request(conn, 23); ncp_unlock_conn(conn); @@ -3073,7 +3011,7 @@ ncp_detach_from_queue(struct ncp_conn *conn, long result; ncp_init_request_s(conn, 112); - ncp_add_dword(conn, htonl(queue_id)); + ncp_add_dword_hl(conn, queue_id); result = ncp_request(conn, 23); ncp_unlock_conn(conn); @@ -3087,14 +3025,14 @@ ncp_service_queue_job(struct ncp_conn *conn, __u32 queue_id, __u16 job_type, long result; ncp_init_request_s(conn, 124); - ncp_add_dword(conn, htonl(queue_id)); - ncp_add_word(conn, htons(job_type)); + ncp_add_dword_hl(conn, queue_id); + ncp_add_word_hl(conn, job_type); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } - memcpy(&(job->j), ncp_reply_data(conn, 0), 78); ConvertToNWfromDWORD(job->j.JobFileHandle, job->file_handle); @@ -3109,9 +3047,9 @@ ncp_finish_servicing_job(struct ncp_conn *conn, __u32 queue_id, long result; ncp_init_request_s(conn, 131); - ncp_add_dword(conn, htonl(queue_id)); - ncp_add_dword(conn, job_number); - ncp_add_dword(conn, htonl(charge_info)); + ncp_add_dword_hl(conn, queue_id); + ncp_add_dword_lh(conn, job_number); + ncp_add_dword_hl(conn, charge_info); result = ncp_request(conn, 23); ncp_unlock_conn(conn); @@ -3125,8 +3063,8 @@ ncp_abort_servicing_job(struct ncp_conn *conn, __u32 queue_id, long result; ncp_init_request_s(conn, 132); - ncp_add_dword(conn, htonl(queue_id)); - ncp_add_dword(conn, job_number); + ncp_add_dword_hl(conn, queue_id); + ncp_add_dword_lh(conn, job_number); result = ncp_request(conn, 23); ncp_unlock_conn(conn); @@ -3143,22 +3081,22 @@ ncp_do_read(struct ncp_conn *conn, const char *file_id, ncp_init_request(conn); ncp_add_byte(conn, 0); ncp_add_mem(conn, file_id, 6); - ncp_add_dword(conn, htonl(offset)); - ncp_add_word(conn, htons(to_read)); + ncp_add_dword_hl(conn, offset); + ncp_add_word_hl(conn, to_read); - if ((result = ncp_request(conn, 72)) != 0) { + if ((result = ncp_request(conn, 72)) != 0) + { ncp_unlock_conn(conn); return result; } - - *bytes_read = ntohs(ncp_reply_word(conn, 0)); + *bytes_read = ncp_reply_word_hl(conn, 0); memcpy(target, ncp_reply_data(conn, 2), *bytes_read); ncp_unlock_conn(conn); return 0; } - + long ncp_read(struct ncp_conn *conn, const char *file_id, off_t offset, size_t count, char *target) @@ -3177,7 +3115,6 @@ ncp_read(struct ncp_conn *conn, const char *file_id, { return -1; } - offset += read_this_time; target += read_this_time; already_read += read_this_time; @@ -3200,21 +3137,21 @@ ncp_do_write(struct ncp_conn *conn, const char *file_id, ncp_init_request(conn); ncp_add_byte(conn, 0); ncp_add_mem(conn, file_id, 6); - ncp_add_dword(conn, htonl(offset)); - ncp_add_word(conn, htons(to_write)); + ncp_add_dword_hl(conn, offset); + ncp_add_word_hl(conn, to_write); ncp_add_mem(conn, source, to_write); - if ((result = ncp_request(conn, 73)) != 0) { + if ((result = ncp_request(conn, 73)) != 0) + { ncp_unlock_conn(conn); return result; } - *bytes_written = to_write; ncp_unlock_conn(conn); return 0; } - + long ncp_write(struct ncp_conn *conn, const char *file_id, off_t offset, size_t count, const char *source) @@ -3229,11 +3166,10 @@ ncp_write(struct ncp_conn *conn, const char *file_id, count - already_written); if (ncp_do_write(conn, file_id, offset, to_write, - source, &written_this_time) != 0) + source, &written_this_time) != 0) { return -1; } - offset += written_this_time; source += written_this_time; already_written += written_this_time; @@ -3253,7 +3189,7 @@ ncp_copy_file(struct ncp_conn *conn, __u32 source_offset, __u32 target_offset, __u32 count, - __u32 *copied_count) + __u32 * copied_count) { long result; @@ -3262,17 +3198,16 @@ ncp_copy_file(struct ncp_conn *conn, ncp_add_byte(conn, 0); /* reserved */ ncp_add_mem(conn, source_file, 6); ncp_add_mem(conn, target_file, 6); - ncp_add_dword(conn, htonl(source_offset)); - ncp_add_dword(conn, htonl(target_offset)); - ncp_add_dword(conn, htonl(count)); + ncp_add_dword_hl(conn, source_offset); + ncp_add_dword_hl(conn, target_offset); + ncp_add_dword_hl(conn, count); if ((result = ncp_request(conn, 74)) != 0) { ncp_unlock_conn(conn); return result; } - - *copied_count = ntohl(ncp_reply_dword(conn, 0)); + *copied_count = ncp_reply_dword_hl(conn, 0); ncp_unlock_conn(conn); return 0; } @@ -3290,7 +3225,6 @@ ncp_get_broadcast_message(struct ncp_conn *conn, char message[256]) ncp_unlock_conn(conn); return result; } - length = ncp_reply_byte(conn, 0); message[length] = 0; memcpy(message, ncp_reply_data(conn, 1), length); @@ -3314,8 +3248,8 @@ ncp_dealloc_dir_handle(struct ncp_conn *conn, __u8 dir_handle) long ncp_alloc_short_dir_handle(struct ncp_conn *conn, struct nw_info_struct *dir, - word alloc_mode, - byte *target) + word alloc_mode, + byte * target) { long result; @@ -3323,7 +3257,7 @@ ncp_alloc_short_dir_handle(struct ncp_conn *conn, ncp_add_byte(conn, 12); /* subfunction */ ncp_add_byte(conn, 0); /* dos name space */ ncp_add_byte(conn, 0); /* reserved */ - ncp_add_word(conn, htons(alloc_mode)); + ncp_add_word_hl(conn, alloc_mode); ncp_add_handle_path(conn, dir->volNumber, dir->DosDirNum, 1, NULL); @@ -3332,7 +3266,6 @@ ncp_alloc_short_dir_handle(struct ncp_conn *conn, ncp_unlock_conn(conn); return result; } - *target = ncp_reply_byte(conn, 0); ncp_unlock_conn(conn); return result; @@ -3347,18 +3280,18 @@ ncp_add_trustee_set(struct ncp_conn *conn, long result = 0; ncp_init_request(conn); - ncp_add_byte(conn, 10); /* subfunction */ - ncp_add_byte(conn, 0); /* dos name space */ + ncp_add_byte(conn, 10); /* subfunction */ + ncp_add_byte(conn, 0); /* dos name space */ ncp_add_byte(conn, 0); /* reserved */ - ncp_add_word(conn, 0x8006); - ncp_add_word(conn, rights_mask); - ncp_add_word(conn, object_count); + ncp_add_word_lh(conn, 0x8006); + ncp_add_word_lh(conn, rights_mask); + ncp_add_word_lh(conn, object_count); ncp_add_handle_path(conn, volume_number, dir_entry, 1, NULL); while (object_count > 0) { - ncp_add_dword(conn, htonl(rights->object_id)); - ncp_add_word(conn, rights->rights); + ncp_add_dword_hl(conn, rights->object_id); + ncp_add_word_lh(conn, rights->rights); object_count -= 1; rights += 1; } diff --git a/lib/nwcrypt.c b/lib/nwcrypt.c index de9d955..645cfdf 100644 --- a/lib/nwcrypt.c +++ b/lib/nwcrypt.c @@ -1,17 +1,17 @@ /*$********************************************************* -$* -$* This code has been taken from DDJ 11/93, from an -$* article by Pawel Szczerbina. -$* -$* Password encryption routines follow. -$* Converted to C from Barry Nance's Pascal -$* prog published in the March -93 issue of Byte. -$* -$* Adapted to be useable for ncpfs by -$* Volker Lendecke in -$* October 1995. -$* -$**********************************************************/ + $* + $* This code has been taken from DDJ 11/93, from an + $* article by Pawel Szczerbina. + $* + $* Password encryption routines follow. + $* Converted to C from Barry Nance's Pascal + $* prog published in the March -93 issue of Byte. + $* + $* Adapted to be useable for ncpfs by + $* Volker Lendecke in + $* October 1995. + $* + $********************************************************* */ /**************************************************************************** @@ -91,28 +91,28 @@ typedef unsigned char buf8[8]; typedef unsigned char buf4[4]; static unsigned char encrypttable[256] = -{0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8, - 0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9, - 0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6, - 0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0, - 0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD, - 0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE, - 0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7, - 0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1, - 0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4, - 0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2, - 0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3, - 0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0, - 0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8, - 0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3, - 0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0, - 0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD}; +{0x7, 0x8, 0x0, 0x8, 0x6, 0x4, 0xE, 0x4, 0x5, 0xC, 0x1, 0x7, 0xB, 0xF, 0xA, 0x8, +0xF, 0x8, 0xC, 0xC, 0x9, 0x4, 0x1, 0xE, 0x4, 0x6, 0x2, 0x4, 0x0, 0xA, 0xB, 0x9, +0x2, 0xF, 0xB, 0x1, 0xD, 0x2, 0x1, 0x9, 0x5, 0xE, 0x7, 0x0, 0x0, 0x2, 0x6, 0x6, +0x0, 0x7, 0x3, 0x8, 0x2, 0x9, 0x3, 0xF, 0x7, 0xF, 0xC, 0xF, 0x6, 0x4, 0xA, 0x0, +0x2, 0x3, 0xA, 0xB, 0xD, 0x8, 0x3, 0xA, 0x1, 0x7, 0xC, 0xF, 0x1, 0x8, 0x9, 0xD, +0x9, 0x1, 0x9, 0x4, 0xE, 0x4, 0xC, 0x5, 0x5, 0xC, 0x8, 0xB, 0x2, 0x3, 0x9, 0xE, +0x7, 0x7, 0x6, 0x9, 0xE, 0xF, 0xC, 0x8, 0xD, 0x1, 0xA, 0x6, 0xE, 0xD, 0x0, 0x7, +0x7, 0xA, 0x0, 0x1, 0xF, 0x5, 0x4, 0xB, 0x7, 0xB, 0xE, 0xC, 0x9, 0x5, 0xD, 0x1, +0xB, 0xD, 0x1, 0x3, 0x5, 0xD, 0xE, 0x6, 0x3, 0x0, 0xB, 0xB, 0xF, 0x3, 0x6, 0x4, +0x9, 0xD, 0xA, 0x3, 0x1, 0x4, 0x9, 0x4, 0x8, 0x3, 0xB, 0xE, 0x5, 0x0, 0x5, 0x2, +0xC, 0xB, 0xD, 0x5, 0xD, 0x5, 0xD, 0x2, 0xD, 0x9, 0xA, 0xC, 0xA, 0x0, 0xB, 0x3, +0x5, 0x3, 0x6, 0x9, 0x5, 0x1, 0xE, 0xE, 0x0, 0xE, 0x8, 0x2, 0xD, 0x2, 0x2, 0x0, +0x4, 0xF, 0x8, 0x5, 0x9, 0x6, 0x8, 0x6, 0xB, 0xA, 0xB, 0xF, 0x0, 0x7, 0x2, 0x8, +0xC, 0x7, 0x3, 0xA, 0x1, 0x4, 0x2, 0x5, 0xF, 0x7, 0xA, 0xC, 0xE, 0x5, 0x9, 0x3, +0xE, 0x7, 0x1, 0x2, 0xE, 0x1, 0xF, 0x4, 0xA, 0x6, 0xC, 0x6, 0xF, 0x4, 0x3, 0x0, + 0xC, 0x0, 0x3, 0x6, 0xF, 0x8, 0x7, 0xB, 0x2, 0xD, 0xC, 0x6, 0xA, 0xA, 0x8, 0xD}; -static buf32 encryptkeys = -{0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D, - 0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35, - 0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11, - 0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0}; +static buf32 encryptkeys = +{0x48, 0x93, 0x46, 0x67, 0x98, 0x3D, 0xE6, 0x8D, + 0xB7, 0x10, 0x7A, 0x26, 0x5A, 0xB9, 0xB1, 0x35, + 0x6B, 0x0F, 0xD5, 0x70, 0xAE, 0xFB, 0xAD, 0x11, + 0xF4, 0x47, 0xDC, 0xA7, 0xEC, 0xCF, 0x50, 0xC0}; static void @@ -128,15 +128,16 @@ shuffle1(buf32 temp, unsigned char *target) { for (s = 0; s <= 31; ++s) { - b3 = (temp[s]+b4) ^ (temp[(s+b4)&31] - encryptkeys[s]); + b3 = (temp[s] + b4) ^ (temp[(s + b4) & 31] - encryptkeys[s]); b4 = b4 + b3; temp[s] = b3; } } - for (i = 0; i <= 15; ++i) { - target[i] = encrypttable[temp[ 2*i ]] - | (encrypttable[temp[ 2*i + 1]] << 4); + for (i = 0; i <= 15; ++i) + { + target[i] = encrypttable[temp[2 * i]] + | (encrypttable[temp[2 * i + 1]] << 4); } } @@ -148,12 +149,14 @@ shuffle(const unsigned char *lon, const unsigned char *buf, int buflen, int b2, d, s; buf32 temp; - while ( (buflen > 0) - && (buf[buflen - 1] == 0)) { + while ((buflen > 0) + && (buf[buflen - 1] == 0)) + { buflen = buflen - 1; } - for (s = 0; s < 32; s++) { + for (s = 0; s < 32; s++) + { temp[s] = 0; } @@ -176,17 +179,17 @@ shuffle(const unsigned char *lon, const unsigned char *buf, int buflen, { b2 = d; temp[s] = temp[s] ^ encryptkeys[s]; - } else { + } else + { temp[s] = temp[s] ^ buf[b2]; b2 = b2 + 1; } } } - for (s = 0; s <= 31; ++s) temp[s] = temp[s] ^ lon[s & 3]; - shuffle1(temp,target); + shuffle1(temp, target); } @@ -198,7 +201,7 @@ nw_encrypt(const unsigned char *fra, buf32 k; int s; - shuffle(&(fra[0]), buf, 16, &(k[ 0])); + shuffle(&(fra[0]), buf, 16, &(k[0])); shuffle(&(fra[4]), buf, 16, &(k[16])); for (s = 0; s <= 15; ++s) @@ -219,16 +222,17 @@ nw_encrypt(const unsigned char *fra, /* server side (mars etc.) should: * store the *encrypted* password internally (output from shuffle) * verify if nw_encrypt(cryptkey from GetCryptKey, old stored password) - == cryptkey in EncryptedChangePassword request buffer (this means - old password was correct) + == cryptkey in EncryptedChangePassword request buffer (this means + old password was correct) * decrypt new password in request buffer using (yet to write) inverse of - newpassencrypt with old stored password as parameter + newpassencrypt with old stored password as parameter * compute the length of the unencrypted new password as len ^ (first byte of - old internal password) ^ (second byte of old internal password) + old internal password) ^ (second byte of old internal password) */ -static char -newshuffle[256+16] = { +static char + newshuffle[256 + 16] = +{ 0x0f, 0x08, 0x05, 0x07, 0x0c, 0x02, 0x0e, 0x09, 0x00, 0x01, 0x06, 0x0d, 0x03, 0x04, 0x0b, 0x0a, 0x02, 0x0c, 0x0e, 0x06, 0x0f, 0x00, 0x01, 0x08, @@ -279,17 +283,17 @@ newshuffle[256+16] = { * - Shuffle (aus nwcrypt.c) altes passwort nach old (16 bytes) * - shuffle neues passwort nach new (16 bytes) * - nwpassencrypt (diese Funktion) zweimal aufrufen fuer je 8 bytes: - * nwpassencrypt(old+0, new+0, out+0) - * nwpassencrypt(old+8, new+8, out+8) + * nwpassencrypt(old+0, new+0, out+0) + * nwpassencrypt(old+8, new+8, out+8) * - NCP-Buffer aufbauen: - * 2 byte Laenge im Hi-Lo-Format - * 1 byte Funktion (0x4b) - * 8 byte (nwcrypt Ergebnis analog login/verify password) - * 2 byte Objecttype - * 1 byte Objectname-Laenge - * n byte Objectname - * 1 byte (Laenge des eingegebenen neuen Passworts ^ old[0] ^ old[1])&0x7f|0x40 - * 16 byte (Ergebnis dieser Funktion doppelt aufgerufen, s.o.) + * 2 byte Laenge im Hi-Lo-Format + * 1 byte Funktion (0x4b) + * 8 byte (nwcrypt Ergebnis analog login/verify password) + * 2 byte Objecttype + * 1 byte Objectname-Laenge + * n byte Objectname + * 1 byte (Laenge des eingegebenen neuen Passworts ^ old[0] ^ old[1])&0x7f|0x40 + * 16 byte (Ergebnis dieser Funktion doppelt aufgerufen, s.o.) */ /* @@ -308,31 +312,31 @@ newpassencrypt(char *old, char *new, char *out) memcpy(copy, new, 8); - for (i=0; i<16; i++) + for (i = 0; i < 16; i++) { - for (di=0, ax=0, p=old; di<8; di++, ax+=0x20, p++) + for (di = 0, ax = 0, p = old; di < 8; di++, ax += 0x20, p++) { - cl=newshuffle[(((copy[di]^*p)>>4)&0x0f)+ax+0x10]<<4; - dl=newshuffle[((copy[di]^*p)&0xf)+ax]; - copy[di]=cl|dl; + cl = newshuffle[(((copy[di] ^ *p) >> 4) & 0x0f) + ax + 0x10] << 4; + dl = newshuffle[((copy[di] ^ *p) & 0xf) + ax]; + copy[di] = cl | dl; } - ch=old[7]; - for (bx=old+7; bx>old; bx--) + ch = old[7]; + for (bx = old + 7; bx > old; bx--) { - *bx=((bx[-1]>>4)&0x0f)|((*bx)<<4); + *bx = ((bx[-1] >> 4) & 0x0f) | ((*bx) << 4); } - *old=((ch>>4)&0x0f)|(*old)<<4; + *old = ((ch >> 4) & 0x0f) | (*old) << 4; memset(out, '\0', 8); - for (di=0; di<16; di++) + for (di = 0; di < 16; di++) { - if (newshuffle[di+0x100]&1) - ch=((copy[newshuffle[di+0x100]/2]>>4)&0x0f); + if (newshuffle[di + 0x100] & 1) + ch = ((copy[newshuffle[di + 0x100] / 2] >> 4) & 0x0f); else - ch=copy[newshuffle[di+0x100]/2]&0x0f; - out[di/2]|=((di&1) ? ch<<4 : ch); + ch = copy[newshuffle[di + 0x100] / 2] & 0x0f; + out[di / 2] |= ((di & 1) ? ch << 4 : ch); } memcpy(copy, out, 8); } diff --git a/man/nwpasswd.1 b/man/nwpasswd.1 index 17e03d7..b4b088e 100644 --- a/man/nwpasswd.1 +++ b/man/nwpasswd.1 @@ -1,4 +1,4 @@ -.TH NWPASSWD 1 06/22/1996 nwpasswd nwpasswd +.TH NWPASSWD 1 01/16/1997 nwpasswd nwpasswd .SH NAME nwpasswd \- Change a user's password .SH SYNOPSIS @@ -11,6 +11,9 @@ nwpasswd \- Change a user's password ] [ .B -U .I user name +] [ +.B -O +.I object name ] .B -t .I object type @@ -43,6 +46,16 @@ is the name of the server you want to use. is the name of the bindery object whose password is to be changed. .RE +.B -O +.I object name +.RS 3 +If you have supervisor privileges, you can change other users' +passwords. With +.B -O +you can tell nwpasswd the name of the user whose password should be +changed. +.RE + .B -t .I object type .RS 3 diff --git a/man/nwvolinfo.1 b/man/nwvolinfo.1 new file mode 100644 index 0000000..b5e8659 --- /dev/null +++ b/man/nwvolinfo.1 @@ -0,0 +1,100 @@ +.TH NWVOLINFO 8 7/9/1996 nwvolinfo nwvolinfo +.SH NAME +nwvolinfo \- Diplay info on NetWare Volumes +.SH SYNOPSIS +.B nwvolinfo +[ +.B -h +] [ +.B -S +.I server +] [ +.B -U +.I user name +] [ +.B -P +.I password +| +.B -n +] [ +.B -C +] [ +.B -v +.I volume +] [ +.B -N +] + +.SH DESCRIPTION +.B nwvolinfo +displays information on a NetWare Server Volume. + +.B nwvolinfo +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, nwvolinfo +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 -v +.I volume +.RS 3 +The volume name to be used. Defaults to 'SYS'. +.RE + +.B -N +.RS 3 +Display the information in numeric-only format for use in a pipe. +.RE + +.SH AUTHORS +nwvolinfo was written by Jacek Stepniewski based on +utilities by Volker Lendecke. \ No newline at end of file diff --git a/ncpfs-2.0.8.lsm b/ncpfs-2.0.9.lsm similarity index 83% rename from ncpfs-2.0.8.lsm rename to ncpfs-2.0.9.lsm index 62f3ce0..29cb724 100644 --- a/ncpfs-2.0.8.lsm +++ b/ncpfs-2.0.9.lsm @@ -1,7 +1,7 @@ Begin3 Title: ncpfs -Version: 2.0.8 -Entered-date: 10. December 1996 +Version: 2.0.9 +Entered-date: 16. February 1997 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 @@ -13,7 +13,7 @@ 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/Linux/system/Filesystems/ncpfs - ~156k ncpfs-2.0.8.tgz - ~ 1k ncpfs-2.0.8.lsm + ~156k ncpfs-2.0.9.tgz + ~ 1k ncpfs-2.0.9.lsm Copying-policy: GPL End diff --git a/patches/README b/patches/README new file mode 100644 index 0000000..e4edd17 --- /dev/null +++ b/patches/README @@ -0,0 +1,13 @@ +To apply the patches, cd into the appropriate kernel source directory +and do: + + patch -p1 < patch-file + + +lockup-2.0.28.diff: +An *extremely* dirty fix to the lockup bug mentioned in the BUGS +file. Please only apply it if you experience the problem. Should apply +to 2.0.28 and above in the 2.0.x series. NOT TESTED with 2.1.x. + +linux-2.1.26.diff: +Little fix to make ncpfs work with 2.1.26. Sent to Linus. diff --git a/patches/linux-2.1.26.diff b/patches/linux-2.1.26.diff new file mode 100644 index 0000000..3b6e7fb --- /dev/null +++ b/patches/linux-2.1.26.diff @@ -0,0 +1,35 @@ +--- 2.1.26/fs/ncpfs/sock.c Sun Jan 26 11:07:44 1997 ++++ 2.1.26-patched/fs/ncpfs/sock.c Sun Feb 16 17:05:13 1997 +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + + +@@ -343,7 +344,6 @@ + char *start = server->packet; + poll_table wait_table; + struct poll_table_entry entry; +- int (*select) (struct inode *, poll_table *); + int init_timeout, max_timeout; + int timeout; + int retrans; +@@ -362,7 +362,6 @@ + + file = server->ncp_filp; + inode = file->f_inode; +- select = file->f_op->poll; + sock = &inode->u.socket_i; + if (!sock) + { +@@ -418,7 +417,7 @@ + wait_table.nr = 0; + wait_table.entry = &entry; + current->state = TASK_INTERRUPTIBLE; +- if (!select(inode, &wait_table)) ++ if (!(file->f_op->poll(file, &wait_table) & POLLIN)) + { + if (timeout > max_timeout) + { diff --git a/patches/lockup-2.0.28.diff b/patches/lockup-2.0.28.diff new file mode 100644 index 0000000..13d924e --- /dev/null +++ b/patches/lockup-2.0.28.diff @@ -0,0 +1,44 @@ +diff -urN 2.0.11/fs/ncpfs/sock.c linux/fs/ncpfs/sock.c +--- 2.0.28/fs/ncpfs/sock.c Fri Jul 12 08:14:53 1996 ++++ linux/fs/ncpfs/sock.c Thu Aug 8 19:27:26 1996 +@@ -55,7 +55,8 @@ + { + struct iovec iov; + struct msghdr msg; +- ++ int result; ++ + iov.iov_base = (void *)buff; + iov.iov_len = len; + +@@ -65,7 +66,29 @@ + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + +- return sock->ops->sendmsg(sock, &msg, len, nonblock, flags); ++ result = sock->ops->sendmsg(sock, &msg, len, 1, flags); ++ ++ if ((result != -EAGAIN) || (nonblock != 0)) ++ { ++ return result; ++ } ++ ++ /* The following is probably one of the worst sins you can do ++ to a multitasking kernel: active polling. But when you call ++ ipx_sendmsg with nonblock==0, then it will block forever ++ from time to time. I really do not know why. To work around ++ this, I try to send the packet with nonblock=1 and retry ++ it. */ ++ ++ do { ++ /* Before retrying, give others a chance */ ++ current->state = TASK_INTERRUPTIBLE; ++ current->timeout = jiffies + HZ/10; ++ schedule(); ++ result = sock->ops->sendmsg(sock, &msg, len, 1, flags); ++ } while (result == -EAGAIN); ++ ++ return result; + } + + diff --git a/sutil/ncplib.c b/sutil/ncplib.c index 7f09950..a1e8ba3 100644 --- a/sutil/ncplib.c +++ b/sutil/ncplib.c @@ -8,12 +8,8 @@ #include "ncplib.h" #include "ncplib_err.h" -typedef __u8 byte; -typedef __u16 word; -typedef __u32 dword; - #include -/* #include */ /* generates a warning here */ + /* #include *//* generates a warning here */ extern pid_t wait(int *); #include #include @@ -34,21 +30,22 @@ extern pid_t wait(int *); #include static long -ncp_negotiate_buffersize(struct ncp_conn *conn, - int size, int *target); + ncp_negotiate_buffersize(struct ncp_conn *conn, + int size, int *target); static long -ncp_login_object(struct ncp_conn *conn, - const unsigned char *username, - int login_type, - const unsigned char *password); + ncp_login_object(struct ncp_conn *conn, + const unsigned char *username, + int login_type, + const unsigned char *password); static long -ncp_do_close(struct ncp_conn *conn); + ncp_do_close(struct ncp_conn *conn); void str_upper(char *name) { - while (*name) { + while (*name) + { *name = toupper(*name); name = name + 1; } @@ -59,62 +56,62 @@ str_upper(char *name) #include "nwcrypt.c" void -ipx_fprint_node(FILE* file,IPXNode node) +ipx_fprint_node(FILE * file, IPXNode node) { - fprintf(file,"%02X%02X%02X%02X%02X%02X", - (unsigned char)node[0], - (unsigned char)node[1], - (unsigned char)node[2], - (unsigned char)node[3], - (unsigned char)node[4], - (unsigned char)node[5] - ); + fprintf(file, "%02X%02X%02X%02X%02X%02X", + (unsigned char) node[0], + (unsigned char) node[1], + (unsigned char) node[2], + (unsigned char) node[3], + (unsigned char) node[4], + (unsigned char) node[5] + ); } void -ipx_fprint_network(FILE* file,IPXNet net) +ipx_fprint_network(FILE * file, IPXNet net) { - fprintf(file,"%08lX",ntohl(net)); + fprintf(file, "%08lX", ntohl(net)); } void -ipx_fprint_port(FILE* file,IPXPort port) +ipx_fprint_port(FILE * file, IPXPort port) { - fprintf(file,"%04X",ntohs(port)); + fprintf(file, "%04X", ntohs(port)); } void -ipx_fprint_saddr(FILE* file,struct sockaddr_ipx* sipx) +ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx) { - ipx_fprint_network(file,sipx->sipx_network); - fprintf(file,":"); - ipx_fprint_node(file,sipx->sipx_node); - fprintf(file,":"); - ipx_fprint_port(file,sipx->sipx_port); + ipx_fprint_network(file, sipx->sipx_network); + fprintf(file, ":"); + ipx_fprint_node(file, sipx->sipx_node); + fprintf(file, ":"); + ipx_fprint_port(file, sipx->sipx_port); } void ipx_print_node(IPXNode node) { - ipx_fprint_node(stdout,node); + ipx_fprint_node(stdout, node); } void ipx_print_network(IPXNet net) { - ipx_fprint_network(stdout,net); + ipx_fprint_network(stdout, net); } void ipx_print_port(IPXPort port) { - ipx_fprint_port(stdout,port); + ipx_fprint_port(stdout, port); } void -ipx_print_saddr(struct sockaddr_ipx* sipx) +ipx_print_saddr(struct sockaddr_ipx *sipx) { - ipx_fprint_saddr(stdout,sipx); + ipx_fprint_saddr(stdout, sipx); } int @@ -129,8 +126,7 @@ ipx_sscanf_node(char *buf, unsigned char node[6]) { return i; } - - for (i=0; i<6; i++) + for (i = 0; i < 6; i++) { node[i] = n[i]; } @@ -144,9 +140,9 @@ ipx_assign_node(IPXNode dest, IPXNode src) } int -ipx_node_equal(IPXNode n1,IPXNode n2) +ipx_node_equal(IPXNode n1, IPXNode n2) { - return memcmp(n1,n2, IPX_NODE_LEN)==0; + return memcmp(n1, n2, IPX_NODE_LEN) == 0; } static int @@ -158,24 +154,24 @@ ipx_recvfrom(int sock, void *buf, int len, unsigned int flags, struct timeval tv; int result; - FD_ZERO(&rd); FD_ZERO(&wr); FD_ZERO(&ex); + FD_ZERO(&rd); + FD_ZERO(&wr); + FD_ZERO(&ex); FD_SET(sock, &rd); - tv.tv_sec = timeout; + tv.tv_sec = timeout; tv.tv_usec = 0; - - if ((result = select(sock+1, &rd, &wr, &ex, &tv)) == -1) + + if ((result = select(sock + 1, &rd, &wr, &ex, &tv)) == -1) { *err = errno; return -1; } - if (FD_ISSET(sock, &rd)) { result = recvfrom(sock, buf, len, flags, - (struct sockaddr *)sender, addrlen); - } - else + (struct sockaddr *) sender, addrlen); + } else { result = -1; errno = ETIMEDOUT; @@ -211,7 +207,7 @@ ipx_sap_find_nearest(int server_type, struct sockaddr_ipx *result, struct sap_server_ident *ident; - if ((sock = socket(AF_IPX,SOCK_DGRAM,PF_IPX)) < 0) + if ((sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX)) < 0) { if (errno == EINVAL) { @@ -219,21 +215,19 @@ ipx_sap_find_nearest(int server_type, struct sockaddr_ipx *result, } return errno; } - - opt=1; + opt = 1; /* Permit broadcast output */ - if(setsockopt(sock,SOL_SOCKET,SO_BROADCAST, &opt,sizeof(opt))==-1) + if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)) == -1) { goto finished; } - memzero(addr); - addr.sipx_family = AF_IPX; + addr.sipx_family = AF_IPX; addr.sipx_network = htonl(0x0); - addr.sipx_port = htons(0x0); - addr.sipx_type = IPX_SAP_PTYPE; - - if(bind(sock,(struct sockaddr*)&addr,sizeof(addr))==-1) + addr.sipx_port = htons(0x0); + addr.sipx_type = IPX_SAP_PTYPE; + + if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) { if (errno == EADDRNOTAVAIL) { @@ -241,23 +235,21 @@ ipx_sap_find_nearest(int server_type, struct sockaddr_ipx *result, } goto finished; } - - *(unsigned short *)data = htons(IPX_SAP_NEAREST_QUERY); - *(unsigned short *)&(data[2]) = htons(server_type); - + WSET_HL(data, 0, IPX_SAP_NEAREST_QUERY); + WSET_HL(data, 2, server_type); + memzero(addr); - addr.sipx_family = AF_IPX; - addr.sipx_port = htons(IPX_SAP_PORT); - addr.sipx_type = IPX_SAP_PTYPE; + addr.sipx_family = AF_IPX; + addr.sipx_port = htons(IPX_SAP_PORT); + addr.sipx_type = IPX_SAP_PTYPE; addr.sipx_network = htonl(0x0); ipx_assign_node(addr.sipx_node, IPX_BROADCAST_NODE); - + if (sendto(sock, data, 4, 0, - (struct sockaddr *)&addr, sizeof(addr)) < 0) + (struct sockaddr *) &addr, sizeof(addr)) < 0) { goto finished; } - packets = 5; do { @@ -269,7 +261,7 @@ ipx_sap_find_nearest(int server_type, struct sockaddr_ipx *result, continue; } } - while ( (ntohs(*((__u16 *)data)) != IPX_SAP_NEAREST_RESPONSE) + while ((ntohs(*((__u16 *) data)) != IPX_SAP_NEAREST_RESPONSE) && (packets > 0)); if (packets == 0) @@ -277,19 +269,18 @@ ipx_sap_find_nearest(int server_type, struct sockaddr_ipx *result, close(sock); return NCPL_ET_NO_SERVER; } + ident = (struct sap_server_ident *) (data + 2); - ident = (struct sap_server_ident *)(data+2); - - result->sipx_family = AF_IPX; + result->sipx_family = AF_IPX; result->sipx_network = ident->server_network; - result->sipx_port = ident->server_port; + result->sipx_port = ident->server_port; ipx_assign_node(result->sipx_node, ident->server_node); memcpy(server_name, ident->server_name, sizeof(ident->server_name)); - + errno = 0; - - finished: + + finished: close(sock); return errno; } @@ -299,16 +290,16 @@ ipx_make_reachable(IPXNet network) { struct rtentry rt_def; /* Router */ - struct sockaddr_ipx *sr = (struct sockaddr_ipx *)&rt_def.rt_gateway; + struct sockaddr_ipx *sr = (struct sockaddr_ipx *) &rt_def.rt_gateway; /* Target */ - struct sockaddr_ipx *st = (struct sockaddr_ipx *)&rt_def.rt_dst; + struct sockaddr_ipx *st = (struct sockaddr_ipx *) &rt_def.rt_dst; struct ipx_rip_packet rip; struct sockaddr_ipx addr; int addrlen; int sock; int opt; - int res=-1; + int res = -1; int i; int packets; @@ -317,7 +308,6 @@ ipx_make_reachable(IPXNet network) errno = EPERM; return -1; } - memzero(rip); sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX); @@ -330,28 +320,25 @@ ipx_make_reachable(IPXNet network) } return errno; } - - opt=1; + opt = 1; /* Permit broadcast output */ if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)) != 0) { goto finished; } - memzero(addr); - addr.sipx_family = AF_IPX; + addr.sipx_family = AF_IPX; addr.sipx_network = htonl(0x0); - addr.sipx_port = htons(0x0); - addr.sipx_type = IPX_RIP_PTYPE; - - if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) != 0) + addr.sipx_port = htons(0x0); + addr.sipx_type = IPX_RIP_PTYPE; + + if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) != 0) { goto finished; } - - addr.sipx_family = AF_IPX; - addr.sipx_port = htons(IPX_RIP_PORT); - addr.sipx_type = IPX_RIP_PTYPE; + addr.sipx_family = AF_IPX; + addr.sipx_port = htons(IPX_RIP_PORT); + addr.sipx_type = IPX_RIP_PTYPE; addr.sipx_network = htonl(0x0); ipx_assign_node(addr.sipx_node, IPX_BROADCAST_NODE); @@ -359,11 +346,10 @@ ipx_make_reachable(IPXNet network) rip.rt[0].network = htonl(network); if (sendto(sock, &rip, sizeof(rip), 0, - (struct sockaddr *)&addr, sizeof(addr)) < 0) + (struct sockaddr *) &addr, sizeof(addr)) < 0) { goto finished; } - packets = 3; do { @@ -374,10 +360,9 @@ ipx_make_reachable(IPXNet network) { goto finished; } - addrlen = sizeof(struct sockaddr_ipx); - len = ipx_recvfrom(sock, &rip, sizeof(rip),0, sr, &addrlen, 1, + len = ipx_recvfrom(sock, &rip, sizeof(rip), 0, sr, &addrlen, 1, &err); if (len < sizeof(rip)) @@ -392,11 +377,10 @@ ipx_make_reachable(IPXNet network) { goto finished; } - - rt_def.rt_flags = RTF_GATEWAY; + rt_def.rt_flags = RTF_GATEWAY; st->sipx_network = htonl(network); - st->sipx_family = AF_IPX; - sr->sipx_family = AF_IPX; + st->sipx_family = AF_IPX; + sr->sipx_family = AF_IPX; i = 0; do @@ -405,8 +389,8 @@ ipx_make_reachable(IPXNet network) i++; } while ((i < 5) && (res < 0) && (errno == EAGAIN)); - - finished: + + finished: close(sock); if (res != 0) @@ -415,7 +399,7 @@ ipx_make_reachable(IPXNet network) } return res; } - + static int install_wdog(struct ncp_conn *conn) { @@ -433,14 +417,12 @@ install_wdog(struct ncp_conn *conn) { return -1; } - if (pid != 0) { /* Parent, should go on as usual */ conn->wdog_pid = pid; return 0; } - while (1) { long err; @@ -455,24 +437,24 @@ install_wdog(struct ncp_conn *conn) anymore */ exit(0); } - - if ( (pktsize != 2) + if ((pktsize != 2) || (buf[1] != '?')) { continue; } - buf[1] = 'Y'; pktsize = sendto(sock, buf, 2, 0, - (struct sockaddr *)&sender, + (struct sockaddr *) &sender, sizeof(sender)); } } #define ncp_printf printf +#define ncp_printf printf + static void -assert_conn_locked(struct ncp_conn *conn); + assert_conn_locked(struct ncp_conn *conn); static void assert_conn_not_locked(struct ncp_conn *conn) @@ -500,14 +482,15 @@ ncp_unlock_conn(struct ncp_conn *conn) static long do_ncp_call(struct ncp_conn *conn, int request_size) { - struct ncp_request_header request = - *((struct ncp_request_header *)(&(conn->packet))); + struct ncp_request_header request; int result; int retries = 20; int len; long err; + memcpy(&request, conn->packet, sizeof(request)); + while (retries > 0) { struct ncp_reply_header reply; @@ -518,17 +501,16 @@ do_ncp_call(struct ncp_conn *conn, int request_size) result = sendto(conn->ncp_sock, conn->packet, request_size, - 0, (struct sockaddr *)&(conn->i.addr), + 0, (struct sockaddr *) &(conn->i.addr), sizeof(conn->i.addr)); if (result < 0) { return errno; } - - re_select: + re_select: len = ipx_recvfrom(conn->ncp_sock, - (char *)&reply, sizeof(reply), + (char *) &reply, sizeof(reply), MSG_PEEK, &sender, &sizeofaddr, 3, &err); if ((len < 0) && (err == ETIMEDOUT)) @@ -539,30 +521,28 @@ do_ncp_call(struct ncp_conn *conn, int request_size) { return err; } + if ( /* Is the sender wrong? */ + (memcmp(&sender.sipx_node, + &(conn->i.addr.sipx_node), 6) != 0) + || (sender.sipx_port != conn->i.addr.sipx_port) - if ( /* Is the sender wrong? */ - (memcmp(&sender.sipx_node, - &(conn->i.addr.sipx_node), 6) != 0) - || (sender.sipx_port != conn->i.addr.sipx_port) + /* Did the sender send a positive acknowledge? */ + || ((len == sizeof(reply)) + && (reply.type == NCP_POSITIVE_ACK)) - /* Did the sender send a positive acknowledge? */ - || ( (len == sizeof(reply)) - && (reply.type == NCP_POSITIVE_ACK)) - - /* Did we get a bogus answer? */ - || ( (len < sizeof(reply)) - || (reply.type != NCP_REPLY) - || ( (request.type != NCP_ALLOC_SLOT_REQUEST) - && ( (reply.sequence != request.sequence) - || (reply.conn_low != request.conn_low) - || (reply.conn_high != request.conn_high))))) + /* Did we get a bogus answer? */ + || ((len < sizeof(reply)) + || (reply.type != NCP_REPLY) + || ((request.type != NCP_ALLOC_SLOT_REQUEST) + && ((reply.sequence != request.sequence) + || (reply.conn_low != request.conn_low) + || (reply.conn_high != request.conn_high))))) { /* Then throw away the packet */ - ipx_recv(conn->ncp_sock, (char *)&reply, sizeof(reply), + ipx_recv(conn->ncp_sock, (char *) &reply, sizeof(reply), 0, 1, &err); goto re_select; } - ipx_recv(conn->ncp_sock, conn->packet, NCP_PACKET_SIZE, 0, 1, &err); conn->reply_size = len; @@ -574,95 +554,76 @@ do_ncp_call(struct ncp_conn *conn, int request_size) static int ncp_mount_request(struct ncp_conn *conn, int function) { - struct ncp_request_header *h - = (struct ncp_request_header *)(conn->packet); - struct ncp_reply_header *reply - = (struct ncp_reply_header *)(conn->packet); struct ncp_ioctl_request request; - int result; assert_conn_locked(conn); if (conn->has_subfunction != 0) { - *(__u16 *)&(h->data[0]) - = htons(conn->current_size - - sizeof(struct ncp_request_header) - 2); + WSET_HL(conn->packet, 7, conn->current_size + - sizeof(struct ncp_request_header) - 2); } + request.function = function; + request.size = conn->current_size; + request.data = conn->packet; - request.function = function; - request.size = conn->current_size; - request.data = conn->packet; - - if ((result = ioctl(conn->mount_fid,NCP_IOC_NCPREQUEST, &request)) < 0) + if ((result = ioctl(conn->mount_fid, NCP_IOC_NCPREQUEST, &request)) < 0) { return result; } - - conn->completion = reply->completion_code; - conn->conn_status = reply->connection_state; + conn->completion = BVAL(conn->packet, 6); + conn->conn_status = BVAL(conn->packet, 7); conn->ncp_reply_size = result - sizeof(struct ncp_reply_header); - if ((reply->completion_code != 0) && (conn->verbose != 0)) + if ((conn->completion != 0) && (conn->verbose != 0)) { - ncp_printf("ncp_request_error: %d\n", reply->completion_code); + ncp_printf("ncp_request_error: %d\n", conn->completion); } - return reply->completion_code == 0 ? 0 : NCPL_ET_REQUEST_ERROR; + return conn->completion == 0 ? 0 : NCPL_ET_REQUEST_ERROR; } static long ncp_temp_request(struct ncp_conn *conn, int function) { - struct ncp_request_header *h - = (struct ncp_request_header *)&(conn->packet); - struct ncp_reply_header *r - = (struct ncp_reply_header *)&(conn->packet); - long err; assert_conn_locked(conn); + conn->sequence += 1; + + WSET_LH(conn->packet, 0, NCP_REQUEST); + BSET(conn->packet, 2, conn->sequence); + BSET(conn->packet, 3, (conn->i.connection) & 0xff); + BSET(conn->packet, 5, (conn->i.connection) >> 8); + BSET(conn->packet, 4, 1); + BSET(conn->packet, 6, function); + if (conn->has_subfunction != 0) { - *(__u16 *)&(h->data[0]) - = htons(conn->current_size - - sizeof(struct ncp_request_header) - 2); + WSET_HL(conn->packet, 7, conn->current_size + - sizeof(struct ncp_request_header) - 2); } - - h->type = NCP_REQUEST; - - conn->sequence += 1; - h->sequence = conn->sequence; - h->conn_low = (conn->i.connection) & 0xff; - h->conn_high = ((conn->i.connection) & 0xff00) >> 8; - h->task = 1; - h->function = function; - if ((err = do_ncp_call(conn, conn->current_size)) != 0) { return err; } - - conn->completion = r->completion_code; - conn->conn_status = r->connection_state; + conn->completion = BVAL(conn->packet, 6); + conn->conn_status = BVAL(conn->packet, 7); conn->ncp_reply_size = - conn->reply_size - sizeof(struct ncp_reply_header); + conn->reply_size - sizeof(struct ncp_reply_header); - if ((r->completion_code != 0) && (conn->verbose != 0)) + if ((conn->completion != 0) && (conn->verbose != 0)) { - ncp_printf("ncp_completion_code: %d\n", r->completion_code); + ncp_printf("ncp_completion_code: %d\n", conn->completion); } - return r->completion_code == 0 ? 0 : NCPL_ET_REQUEST_ERROR; + return conn->completion == 0 ? 0 : NCPL_ET_REQUEST_ERROR; } static long ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *target, int wdog_needed) { - struct ncp_request_header *h = - (struct ncp_request_header *)&(conn->packet); - struct sockaddr_ipx addr; int addrlen; @@ -671,88 +632,87 @@ ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *target, conn->is_connected = NOT_CONNECTED; conn->verbose = 0; - + if ((ncp_sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX)) == -1) { return errno; } - if ((wdog_sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX)) == -1) { return errno; } - - addr.sipx_family = AF_IPX; - addr.sipx_port = htons(0x0); - addr.sipx_type = NCP_PTYPE; + addr.sipx_family = AF_IPX; + addr.sipx_port = htons(0x0); + addr.sipx_type = NCP_PTYPE; addr.sipx_network = IPX_THIS_NET; ipx_assign_node(addr.sipx_node, IPX_THIS_NODE); addrlen = sizeof(addr); - if ( (bind(ncp_sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) - || (getsockname(ncp_sock, (struct sockaddr *)&addr, &addrlen)==-1)) + if ((bind(ncp_sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) + || (getsockname(ncp_sock, (struct sockaddr *) &addr, &addrlen) == -1)) { int saved_errno = errno; - close(ncp_sock); close(wdog_sock); + close(ncp_sock); + close(wdog_sock); return saved_errno; } - addr.sipx_port = htons(ntohs(addr.sipx_port) + 1); - if (bind(wdog_sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) + if (bind(wdog_sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) { int saved_errno = errno; - close(ncp_sock); close(wdog_sock); + close(ncp_sock); + close(wdog_sock); return saved_errno; } - conn->ncp_sock = ncp_sock; conn->wdog_sock = wdog_sock; - h->type = NCP_ALLOC_SLOT_REQUEST; - conn->sequence = 0; - conn->i.addr = *target; - h->sequence = conn->sequence; - h->conn_low = 0xff; - h->conn_high = 0xff; - h->task = 1; - h->function = 0; + conn->i.addr = *target; - if ((err = do_ncp_call(conn, sizeof(*h))) != 0) + WSET_LH(conn->packet, 0, NCP_ALLOC_SLOT_REQUEST); + BSET(conn->packet, 2, conn->sequence); + BSET(conn->packet, 3, 0xff); + BSET(conn->packet, 4, 1); + BSET(conn->packet, 5, 0xff); + BSET(conn->packet, 6, 0); + + if ((err = do_ncp_call(conn, sizeof(struct ncp_request_header))) != 0) { - if ( (err != ENETUNREACH) + if ((err != ENETUNREACH) || (ipx_make_reachable(htonl(target->sipx_network)) != 0) - || ((err = do_ncp_call(conn, sizeof(*h))) != 0)) + || ((err = + do_ncp_call(conn, + sizeof(struct ncp_request_header))) != 0)) { - close(ncp_sock); close(wdog_sock); + close(ncp_sock); + close(wdog_sock); return err; } } - if (wdog_needed != 0) { install_wdog(conn); - } - else + } else { conn->wdog_pid = 0; } - conn->sequence = 0; - conn->i.connection = h->conn_low + (h->conn_high * 256); + conn->sequence = 0; + conn->i.connection = + BVAL(conn->packet, 3) + (BVAL(conn->packet, 5) << 8); conn->is_connected = CONN_TEMPORARY; - if ( (ncp_negotiate_buffersize(conn, 1024, - &(conn->i.buffer_size)) != 0) + if ((ncp_negotiate_buffersize(conn, 1024, + &(conn->i.buffer_size)) != 0) || (conn->i.buffer_size < 512) || (conn->i.buffer_size > 1024)) { ncp_do_close(conn); return -1; } - return 0; } @@ -768,7 +728,6 @@ ncp_connect_any(struct ncp_conn *conn, int wdog_needed) { return result; } - if ((result = ncp_connect_addr(conn, &addr, wdog_needed)) != 0) { return result; @@ -786,10 +745,10 @@ ncp_find_fileserver(char *server_name, long *err) struct sockaddr_ipx * ncp_find_server(char **server_name, int type, long *err) { - char server[NCP_BINDERY_NAME_LEN+1]; - static char nearest[NCP_BINDERY_NAME_LEN+1]; + char server[NCP_BINDERY_NAME_LEN + 1]; + static char nearest[NCP_BINDERY_NAME_LEN + 1]; struct nw_property prop; - struct prop_net_address *n_addr = (struct prop_net_address *)∝ + struct prop_net_address *n_addr = (struct prop_net_address *) ∝ struct ncp_conn conn; static struct sockaddr_ipx result; @@ -806,16 +765,13 @@ ncp_find_server(char **server_name, int type, long *err) *err = NCPL_ET_NAMETOOLONG; return NULL; } - strcpy(server, *server_name); str_upper(server); } - if ((*err = ipx_sap_find_nearest(type, &result, nearest)) != 0) { return NULL; } - /* We have to ask the nearest server for our wanted server */ memzero(conn); @@ -823,7 +779,6 @@ ncp_find_server(char **server_name, int type, long *err) { return NULL; } - if (*server_name == NULL) { *server_name = nearest; @@ -831,24 +786,22 @@ ncp_find_server(char **server_name, int type, long *err) errno = 0; return &result; } - /* The following optimization should have been done before - ncp_connect_addr. This would be convenient if there was a - simple way to find out whether there is a route to the - server. Parsing /proc/net/ipx_route is not too nice, so we - just connect to the server and immediately disconnect - again. This way we also find out if the server still has - free connection slots. */ + ncp_connect_addr. This would be convenient if there was a + simple way to find out whether there is a route to the + server. Parsing /proc/net/ipx_route is not too nice, so we + just connect to the server and immediately disconnect + again. This way we also find out if the server still has + free connection slots. */ if (strcmp(server, nearest) == 0) { /* Our wanted server answered the SAP GNS request, so - use it */ + use it */ ncp_do_close(&conn); errno = 0; return &result; } - if (ncp_read_property_value(&conn, type, server, 1, "NET_ADDRESS", &prop) != 0) { @@ -856,26 +809,23 @@ ncp_find_server(char **server_name, int type, long *err) *err = NCPL_ET_HOST_UNKNOWN; return NULL; } - if ((*err = ncp_do_close(&conn)) != 0) { return NULL; } - - result.sipx_family = AF_IPX; + result.sipx_family = AF_IPX; result.sipx_network = n_addr->network; - result.sipx_port = n_addr->port; + result.sipx_port = n_addr->port; ipx_assign_node(result.sipx_node, n_addr->node); /* To make the final server reachable, we connect again. See - above. (When can we rely on all users running ipxd??? :-)) */ + above. (When can we rely on all users running ipxd??? :-)) */ memzero(conn); - if ( ((*err = ncp_connect_addr(&conn, &result, 0)) != 0) + if (((*err = ncp_connect_addr(&conn, &result, 0)) != 0) || ((*err = ncp_do_close(&conn)) != 0)) { return NULL; } - return &result; } @@ -890,17 +840,14 @@ ncp_open_temporary(struct ncp_conn *conn, { return ncp_connect_any(conn, 1); } - if ((addr = ncp_find_fileserver(spec->server, &err)) == NULL) { return err; } - if ((err = ncp_connect_addr(conn, addr, 1)) != 0) { return err; } - strcpy(conn->server, spec->server); if (strlen(spec->user) != 0) @@ -913,7 +860,6 @@ ncp_open_temporary(struct ncp_conn *conn, } strcpy(conn->user, spec->user); } - return 0; } @@ -926,35 +872,32 @@ ncp_find_permanent(const struct ncp_conn_spec *spec) int mount_fid; struct ncp_fs_info i; - initialize_NCPL_error_table(); + initialize_NCPL_error_table(); if ((mtab = fopen(MOUNTED, "r")) == NULL) { return NULL; } - while ((conn_ent = ncp_get_conn_ent(mtab)) != NULL) { if (spec != NULL) { - if ( (conn_ent->uid != spec->uid) - || ( (strlen(spec->server) != 0) + if ((conn_ent->uid != spec->uid) + || ((strlen(spec->server) != 0) && (strcasecmp(conn_ent->server, spec->server) != 0)) - || ( (strlen(spec->user) != 0) + || ((strlen(spec->user) != 0) && (strcasecmp(conn_ent->user, spec->user) != 0))) { continue; } } - mount_fid = open(conn_ent->mount_point, O_RDONLY, 0); if (mount_fid < 0) { continue; } - i.version = NCP_GET_FS_INFO_VERSION; if (ioctl(mount_fid, NCP_IOC_GET_FS_INFO, &i) < 0) @@ -962,7 +905,6 @@ ncp_find_permanent(const struct ncp_conn_spec *spec) close(mount_fid); continue; } - close(mount_fid); result = conn_ent->mount_point; break; @@ -972,7 +914,7 @@ ncp_find_permanent(const struct ncp_conn_spec *spec) errno = (result == NULL) ? ENOENT : 0; return result; } - + static int ncp_open_permanent(struct ncp_conn *conn, const struct ncp_conn_spec *spec) @@ -984,18 +926,15 @@ ncp_open_permanent(struct ncp_conn *conn, errno = EBUSY; return -1; } - if ((mount_point = ncp_find_permanent(spec)) == NULL) { return -1; } - if (strlen(mount_point) >= sizeof(conn->mount_point)) { errno = ENAMETOOLONG; return -1; } - /* The rest has already been done in ncp_find_permanent, so we * do not check errors anymore */ conn->mount_fid = open(mount_point, O_RDONLY, 0); @@ -1005,12 +944,11 @@ ncp_open_permanent(struct ncp_conn *conn, { strncpy(conn->server, spec->server, sizeof(conn->server)); strncpy(conn->user, spec->user, sizeof(conn->user)); - } - else + } else { - memset(conn->server, '\0', sizeof(conn->server)); - memset(conn->user, '\0', sizeof(conn->user)); - } + memset(conn->server, '\0', sizeof(conn->server)); + memset(conn->user, '\0', sizeof(conn->user)); + } strcpy(conn->mount_point, mount_point); conn->is_connected = CONN_PERMANENT; return 0; @@ -1021,7 +959,7 @@ ncp_open(struct ncp_conn_spec *spec, long *err) { struct ncp_conn *result; - initialize_NCPL_error_table(); + initialize_NCPL_error_table(); result = malloc(sizeof(struct ncp_conn)); @@ -1030,14 +968,12 @@ ncp_open(struct ncp_conn_spec *spec, long *err) *err = ENOMEM; return NULL; } - memzero(*result); if (ncp_open_permanent(result, spec) == 0) { return result; } - if ((*err = ncp_open_temporary(result, spec)) != 0) { free(result); @@ -1052,14 +988,13 @@ ncp_open_mount(const char *mount_point, long *err) { struct ncp_conn *result; - initialize_NCPL_error_table(); + initialize_NCPL_error_table(); if (strlen(mount_point) >= sizeof(result->mount_point)) { *err = ENAMETOOLONG; return NULL; } - result = malloc(sizeof(struct ncp_conn)); if (result == NULL) @@ -1067,7 +1002,6 @@ ncp_open_mount(const char *mount_point, long *err) *err = ENOMEM; return NULL; } - memzero(*result); result->is_connected = NOT_CONNECTED; @@ -1096,24 +1030,21 @@ ncp_open_mount(const char *mount_point, long *err) static long ncp_user_disconnect(struct ncp_conn *conn) { - struct ncp_request_header *h - = (struct ncp_request_header *)(conn->packet); long result; - h->type = NCP_DEALLOC_SLOT_REQUEST; - conn->sequence += 1; - h->sequence = conn->sequence; - h->conn_low = (conn->i.connection) & 0xff; - h->conn_high = ((conn->i.connection) & 0xff00) >> 8; - h->task = 1; - h->function = 0; - if ((result = do_ncp_call(conn, sizeof(*h))) != 0) + WSET_LH(conn->packet, 0, NCP_DEALLOC_SLOT_REQUEST); + BSET(conn->packet, 2, conn->sequence); + BSET(conn->packet, 3, (conn->i.connection) & 0xff); + BSET(conn->packet, 4, 1); + BSET(conn->packet, 5, (conn->i.connection) >> 8); + BSET(conn->packet, 6, 0); + + if ((result = do_ncp_call(conn, sizeof(struct ncp_request_header))) != 0) { return result; } - close(conn->ncp_sock); close(conn->wdog_sock); @@ -1122,7 +1053,6 @@ ncp_user_disconnect(struct ncp_conn *conn) kill(conn->wdog_pid, SIGTERM); wait(NULL); } - return 0; } @@ -1136,7 +1066,7 @@ ncp_do_close(struct ncp_conn *conn) case CONN_PERMANENT: result = close(conn->mount_fid); break; - + case CONN_TEMPORARY: result = ncp_user_disconnect(conn); break; @@ -1144,7 +1074,7 @@ ncp_do_close(struct ncp_conn *conn) default: break; } - + conn->is_connected = NOT_CONNECTED; return result; @@ -1158,7 +1088,6 @@ ncp_close(struct ncp_conn *conn) { return 0; } - if ((result = ncp_do_close(conn)) != 0) { return result; @@ -1168,10 +1097,10 @@ ncp_close(struct ncp_conn *conn) } struct ncp_conn_ent * -ncp_get_conn_ent(FILE *filep) +ncp_get_conn_ent(FILE * filep) { static struct ncp_conn_ent entry; - char server[2*NCP_BINDERY_NAME_LEN]; + char server[2 * NCP_BINDERY_NAME_LEN]; char *user; struct mntent *mnt_ent; int fid; @@ -1185,12 +1114,10 @@ ncp_get_conn_ent(FILE *filep) { continue; } - if (strlen(mnt_ent->mnt_fsname) >= sizeof(server)) { continue; } - strcpy(server, mnt_ent->mnt_fsname); user = strchr(server, '/'); if (user != NULL) @@ -1203,8 +1130,7 @@ ncp_get_conn_ent(FILE *filep) } strcpy(entry.user, user); } - - if ( (strlen(server) >= sizeof(entry.server)) + if ((strlen(server) >= sizeof(entry.server)) || (strlen(mnt_ent->mnt_dir) >= sizeof(entry.mount_point))) { continue; @@ -1218,12 +1144,11 @@ ncp_get_conn_ent(FILE *filep) { continue; } - - if (ioctl(fid, NCP_IOC_GETMOUNTUID, &entry.uid) != 0) { + if (ioctl(fid, NCP_IOC_GETMOUNTUID, &entry.uid) != 0) + { close(fid); continue; } - close(fid); return &entry; } @@ -1232,7 +1157,7 @@ ncp_get_conn_ent(FILE *filep) } static struct ncp_conn_spec * -ncp_get_nwc_ent(FILE *nwc) +ncp_get_nwc_ent(FILE * nwc) { static struct ncp_conn_spec spec; char line[512]; @@ -1245,18 +1170,16 @@ ncp_get_nwc_ent(FILE *nwc) while (fgets(line, sizeof(line), nwc) != NULL) { - if ( (line[0] == '\n') + if ((line[0] == '\n') || (line[0] == '#')) { continue; } - line_len = strlen(line); - if (line[line_len-1] == '\n') + if (line[line_len - 1] == '\n') { - line[line_len-1] = '\0'; + line[line_len - 1] = '\0'; } - user = strchr(line, '/'); password = strchr(user != NULL ? user : line, ' '); @@ -1265,7 +1188,6 @@ ncp_get_nwc_ent(FILE *nwc) *password = '\0'; password += 1; } - if (user != NULL) { *user = '\0'; @@ -1276,7 +1198,6 @@ ncp_get_nwc_ent(FILE *nwc) } strcpy(spec.user, user); } - if (strlen(line) >= sizeof(spec.server)) { continue; @@ -1312,12 +1233,10 @@ ncp_fopen_nwc(const char *user, const char *mode, long *err) { mode = "r"; } - if (user == NULL) { home = getenv("HOME"); - } - else + } else { struct passwd *pwd; @@ -1327,13 +1246,12 @@ ncp_fopen_nwc(const char *user, const char *mode, long *err) } } - if ( (home == NULL) - || (strlen(home) + sizeof(NWCLIENT) + 2 > sizeof(path))) + if ((home == NULL) + || (strlen(home) + sizeof(NWCLIENT) + 2 > sizeof(path))) { *err = ENAMETOOLONG; return NULL; } - strcpy(path, home); strcat(path, "/"); strcat(path, NWCLIENT); @@ -1343,13 +1261,11 @@ ncp_fopen_nwc(const char *user, const char *mode, long *err) *err = errno; return NULL; } - if ((st.st_mode & (S_IRWXO | S_IRWXG)) != 0) { *err = NCPL_ET_INVALID_MODE; return NULL; } - return fopen(path, mode); } @@ -1364,7 +1280,7 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, FILE *nwc; struct ncp_conn_spec *nwc_ent; - initialize_NCPL_error_table(); + initialize_NCPL_error_table(); *err = 0; memzero(spec); @@ -1378,15 +1294,13 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, return NULL; } strcpy(spec.server, server); - } - else + } else { if ((nwc = ncp_fopen_nwc(NULL, NULL, err)) == NULL) { *err = NCPL_ET_NO_SERVER; return NULL; } - nwc_ent = ncp_get_nwc_ent(nwc); fclose(nwc); @@ -1407,7 +1321,6 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, memset(spec.password, 0, sizeof(spec.password)); return &spec; } - if (user != NULL) { if (strlen(user) >= sizeof(spec.user)) @@ -1417,7 +1330,6 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, } strcpy(spec.user, user); } - str_upper(spec.user); spec.login_type = NCP_BINDERY_USER; @@ -1426,7 +1338,6 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, ncp_do_close(&conn); return &spec; } - if (password != NULL) { if (strlen(password) >= sizeof(spec.password)) @@ -1435,16 +1346,15 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, return NULL; } strcpy(spec.password, password); - } - else + } else { if ((nwc = ncp_fopen_nwc(NULL, NULL, err)) != NULL) { while ((nwc_ent = ncp_get_nwc_ent(nwc)) != NULL) { - if ( (strcasecmp(spec.server, - nwc_ent->server) != 0) - || ( (*spec.user != '\0') + if ((strcasecmp(spec.server, + nwc_ent->server) != 0) + || ((*spec.user != '\0') && (strcasecmp(spec.user, nwc_ent->user) != 0))) { @@ -1463,7 +1373,6 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, *err = NCPL_ET_NO_USER; return NULL; } - if ((strlen(spec.password) == 0) && (password == NULL)) { char *password; @@ -1480,8 +1389,7 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password, return NULL; } strcpy(spec.password, password); - } - else + } else { if (strcmp(spec.password, NWC_NOPASSWORD) == 0) { @@ -1499,8 +1407,8 @@ struct ncp_conn * ncp_initialize_as(int *argc, char **argv, int login_necessary, int login_type, long *err) { - char *server = NULL; - char *user = NULL; + char *server = NULL; + char *user = NULL; char *password = NULL; struct ncp_conn_spec *spec; int i = 1; @@ -1511,40 +1419,38 @@ ncp_initialize_as(int *argc, char **argv, if (target != NULL) { - if (arg_no+1 >= *argc) + if (arg_no + 1 >= *argc) { /* No argument to switch */ errno = EINVAL; return -1; } - *target = argv[arg_no+1]; + *target = argv[arg_no + 1]; count = 2; } - /* Delete the consumed switch from the argument list and decrement the argument count */ - while (count+arg_no < *argc) + while (count + arg_no < *argc) { - argv[arg_no] = argv[arg_no+count]; + argv[arg_no] = argv[arg_no + count]; arg_no += 1; } *argc -= count; return 0; } - initialize_NCPL_error_table(); + initialize_NCPL_error_table(); *err = EINVAL; while (i < *argc) { - if ( (argv[i][0] != '-') + if ((argv[i][0] != '-') || (strlen(argv[i]) != 2)) { i += 1; continue; } - switch (argv[i][1]) { case 'S': @@ -1584,23 +1490,20 @@ ncp_initialize_as(int *argc, char **argv, if (login_necessary != 0) { return NULL; - } - else + } else { return ncp_open(NULL, err); } } - spec->login_type = login_type; if (login_necessary == 0) { spec->user[0] = '\0'; } - return ncp_open(spec, err); } - + struct ncp_conn * ncp_initialize(int *argc, char **argv, int login_necessary, long *err) @@ -1612,7 +1515,8 @@ ncp_initialize(int *argc, char **argv, static long ncp_request(struct ncp_conn *conn, int function) { - switch (conn->is_connected) { + switch (conn->is_connected) + { case CONN_PERMANENT: return ncp_mount_request(conn, function); case CONN_TEMPORARY: @@ -1631,13 +1535,14 @@ ncp_request(struct ncp_conn *conn, int function) static inline int min(int a, int b) { - return (alock == 0) { + if (conn->lock == 0) + { ncp_printf("ncpfs: conn not locked!\n"); } } @@ -1646,20 +1551,47 @@ static void ncp_add_byte(struct ncp_conn *conn, byte x) { assert_conn_locked(conn); - *(byte *)(&(conn->packet[conn->current_size])) = x; + BSET(conn->packet, conn->current_size, x); conn->current_size += 1; return; } static void -ncp_add_word(struct ncp_conn *conn, word x) +ncp_add_word_lh(struct ncp_conn *conn, word x) { assert_conn_locked(conn); - *(word *)(&(conn->packet[conn->current_size])) = x; + WSET_LH(conn->packet, conn->current_size, x); conn->current_size += 2; return; } +static void +ncp_add_dword_lh(struct ncp_conn *conn, dword x) +{ + assert_conn_locked(conn); + DSET_LH(conn->packet, conn->current_size, x); + conn->current_size += 4; + return; +} + +static void +ncp_add_word_hl(struct ncp_conn *conn, word x) +{ + assert_conn_locked(conn); + WSET_HL(conn->packet, conn->current_size, x); + conn->current_size += 2; + return; +} + +static void +ncp_add_dword_hl(struct ncp_conn *conn, dword x) +{ + assert_conn_locked(conn); + DSET_HL(conn->packet, conn->current_size, x); + conn->current_size += 4; + return; +} + static void ncp_add_mem(struct ncp_conn *conn, const void *source, int size) { @@ -1674,7 +1606,8 @@ ncp_add_pstring(struct ncp_conn *conn, const char *s) { int len = strlen(s); assert_conn_locked(conn); - if (len > 255) { + if (len > 255) + { ncp_printf("ncpfs: string too long: %s\n", s); len = 255; } @@ -1696,7 +1629,7 @@ static void ncp_init_request_s(struct ncp_conn *conn, int subfunction) { ncp_init_request(conn); - ncp_add_word(conn, 0); /* preliminary size */ + ncp_add_word_lh(conn, 0); /* preliminary size */ ncp_add_byte(conn, subfunction); @@ -1712,19 +1645,31 @@ ncp_reply_data(struct ncp_conn *conn, int offset) static byte ncp_reply_byte(struct ncp_conn *conn, int offset) { - return *(byte *)(ncp_reply_data(conn, offset)); + return *(byte *) (ncp_reply_data(conn, offset)); } static word -ncp_reply_word(struct ncp_conn *conn, int offset) +ncp_reply_word_hl(struct ncp_conn *conn, int offset) { - return *(word *)(ncp_reply_data(conn, offset)); + return WVAL_HL(ncp_reply_data(conn, offset), 0); +} + +static word +ncp_reply_word_lh(struct ncp_conn *conn, int offset) +{ + return WVAL_LH(ncp_reply_data(conn, offset), 0); } static dword -ncp_reply_dword(struct ncp_conn *conn, int offset) +ncp_reply_dword_hl(struct ncp_conn *conn, int offset) { - return *(dword *)(ncp_reply_data(conn, offset)); + return DVAL_HL(ncp_reply_data(conn, offset), 0); +} + +static dword +ncp_reply_dword_lh(struct ncp_conn *conn, int offset) +{ + return DVAL_LH(ncp_reply_data(conn, offset), 0); } /* Here the ncp calls begin @@ -1737,14 +1682,14 @@ ncp_negotiate_buffersize(struct ncp_conn *conn, long result; ncp_init_request(conn); - ncp_add_word(conn, htons(size)); - - if ((result = ncp_request(conn, 33)) != 0) { + ncp_add_word_hl(conn, size); + + if ((result = ncp_request(conn, 33)) != 0) + { ncp_unlock_conn(conn); return result; } - - *target =min(ntohs(ncp_reply_word(conn, 0)), size); + *target = min(ncp_reply_word_hl(conn, 0), size); ncp_unlock_conn(conn); return 0; @@ -1761,18 +1706,18 @@ ncp_get_encryption_key(struct ncp_conn *conn, ncp_init_request_s(conn, 23); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } - - if (conn->ncp_reply_size < 8) { + if (conn->ncp_reply_size < 8) + { ncp_printf("ncp_reply_size %d < 8\n", - conn->ncp_reply_size); + conn->ncp_reply_size); ncp_unlock_conn(conn); return result; } - memcpy(target, ncp_reply_data(conn, 0), 8); ncp_unlock_conn(conn); return 0; @@ -1786,23 +1731,23 @@ ncp_get_bindery_object_id(struct ncp_conn *conn, { long result; ncp_init_request_s(conn, 53); - ncp_add_word(conn, htons(object_type)); + ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } - - if (conn->ncp_reply_size < 54) { + if (conn->ncp_reply_size < 54) + { ncp_printf("ncp_reply_size %d < 54\n", - conn->ncp_reply_size); + conn->ncp_reply_size); ncp_unlock_conn(conn); return result; } - - target->object_id = ntohl(ncp_reply_dword(conn, 0)); - target->object_type = ntohs(ncp_reply_word (conn, 4)); + target->object_id = ncp_reply_dword_hl(conn, 0); + target->object_type = ncp_reply_word_hl(conn, 4); memcpy(target->object_name, ncp_reply_data(conn, 6), 48); ncp_unlock_conn(conn); return 0; @@ -1816,16 +1761,16 @@ ncp_read_property_value(struct ncp_conn *conn, { long result; ncp_init_request_s(conn, 61); - ncp_add_word(conn, htons(object_type)); + ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); ncp_add_byte(conn, segment); ncp_add_pstring(conn, prop_name); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } - memcpy(&(target->value), ncp_reply_data(conn, 0), 128); target->more_flag = ncp_reply_byte(conn, 128); target->property_flag = ncp_reply_byte(conn, 129); @@ -1844,12 +1789,12 @@ ncp_login_encrypted(struct ncp_conn *conn, unsigned char encrypted[8]; long result; - shuffle((byte *)&tmpID, passwd, strlen(passwd), buf); + shuffle((byte *) & tmpID, passwd, strlen(passwd), buf); nw_encrypt(key, buf, encrypted); ncp_init_request_s(conn, 24); ncp_add_mem(conn, encrypted, 8); - ncp_add_word(conn, htons(object->object_type)); + ncp_add_word_hl(conn, object->object_type); ncp_add_pstring(conn, object->object_name); result = ncp_request(conn, 23); @@ -1864,7 +1809,7 @@ ncp_login_unencrypted(struct ncp_conn *conn, { long result; ncp_init_request_s(conn, 20); - ncp_add_word(conn, htons(object_type)); + ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); ncp_add_pstring(conn, passwd); result = ncp_request(conn, 23); @@ -1879,7 +1824,7 @@ ncp_login_user(struct ncp_conn *conn, { return ncp_login_object(conn, username, NCP_BINDERY_USER, password); } - + static long ncp_login_object(struct ncp_conn *conn, const unsigned char *username, @@ -1890,28 +1835,27 @@ ncp_login_object(struct ncp_conn *conn, unsigned char ncp_key[8]; struct ncp_bindery_object user; - if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0) { + if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0) + { return ncp_login_unencrypted(conn, login_type, username, password); } - if ((result = ncp_get_bindery_object_id(conn, login_type, - username, &user)) != 0) { + username, &user)) != 0) + { return result; } - if ((result = ncp_login_encrypted(conn, &user, ncp_key, password)) != 0) { struct nw_property p; struct ncp_prop_login_control *l - = (struct ncp_prop_login_control *)&p; + = (struct ncp_prop_login_control *) &p; if (conn->completion != NCP_GRACE_PERIOD) { return result; } - fprintf(stderr, "Your password has expired\n"); if ((result = ncp_read_property_value(conn, NCP_BINDERY_USER, diff --git a/sutil/ncplib.h b/sutil/ncplib.h index 7aaaf44..095eed7 100644 --- a/sutil/ncplib.h +++ b/sutil/ncplib.h @@ -24,6 +24,90 @@ #define memzero(object) memset(&(object), 0, sizeof(object)) #endif +typedef __u8 byte; +typedef __u16 word; +typedef __u32 dword; + +#define BVAL(buf,pos) (((__u8 *)(buf))[pos]) +#define PVAL(buf,pos) ((unsigned)BVAL(buf,pos)) +#define BSET(buf,pos,val) (BVAL(buf,pos) = (val)) + +static inline word +WVAL_HL(__u8 *buf, int pos) +{ + return PVAL(buf,pos)<<8 | PVAL(buf, pos+1); +} +static inline dword +DVAL_HL(__u8 *buf, int pos) +{ + return WVAL_HL(buf, pos)<<16 | WVAL_HL(buf, pos+2); +} +static inline void +WSET_HL(__u8 *buf, int pos, word val) +{ + BSET(buf,pos,val>>8); + BSET(buf,pos+1, val & 0xff); +} +static inline void +DSET_HL(__u8 *buf, int pos, dword val) +{ + WSET_HL(buf, pos, val >>16); + WSET_HL(buf, pos+2, val & 0xffff); +} + + +/* we know that the 386 can handle misalignment and has the "right" + byteorder */ +#if defined(__i386__) + +static inline word +WVAL_LH(__u8 *buf, int pos) +{ + return *((word *)(buf+pos)); +} +static inline dword +DVAL_LH(__u8 *buf, int pos) +{ + return *((dword *)(buf+pos)); +} +static inline void +WSET_LH(__u8 *buf, int pos, word val) +{ + *((word *)(buf+pos)) = val; +} +static inline void +DSET_LH(__u8 *buf, int pos, dword val) +{ + *((dword *)(buf+pos)) = val; +} + +#else + +static inline word +WVAL_LH(__u8 *buf, int pos) +{ + return PVAL(buf,pos) | PVAL(buf, pos+1)<<8; +} +static inline dword +DVAL_LH(__u8 *buf, int pos) +{ + return WVAL_LH(buf, pos) | WVAL_LH(buf, pos+2) << 16; +} +static inline void +WSET_LH(__u8 *buf, int pos, word val) +{ + BSET(buf,pos,val & 0xff); + BSET(buf,pos+1, val >> 8); +} +static inline void +DSET_LH(__u8 *buf, int pos, dword val) +{ + WSET_LH(buf, pos, val & 0xffff); + WSET_LH(buf, pos+2, val >> 16); +} + +#endif + void str_upper(char *name); diff --git a/sutil/ncpmount.c b/sutil/ncpmount.c index b05b1a9..e61ad84 100644 --- a/sutil/ncpmount.c +++ b/sutil/ncpmount.c @@ -26,7 +26,7 @@ #include #include #include -/* #include */ /* generates a warning here */ + /* #include *//* generates a warning here */ extern pid_t waitpid(pid_t, int *, int); #include #include @@ -61,8 +61,8 @@ load_ncpfs(void) FILE *ffs; char s[1024]; char *p, *p1; - pid_t pid; - int status; + pid_t pid; + int status; /* Check if ncpfs is in the kernel */ ffs = fopen("/proc/filesystems", "r"); @@ -72,9 +72,8 @@ load_ncpfs(void) perror("Error: \"/proc/filesystems\" could not be read:"); return -1; } - p = NULL; - while (! feof(ffs)) + while (!feof(ffs)) { p1 = fgets(s, sizeof(s), ffs); if (p1) @@ -92,84 +91,79 @@ load_ncpfs(void) { return 0; } + /* system() function without signal handling, from Stevens */ - /* system() function without signal handling, from Stevens */ - - if ((pid = fork()) < 0) + if ((pid = fork()) < 0) { - return 1; - } - else if (pid == 0) + return 1; + } else if (pid == 0) { - /* child */ - execl("/sbin/modprobe", "modprobe", "ncpfs", NULL); - _exit(127); /* execl error */ - } - else + /* child */ + execl("/sbin/modprobe", "modprobe", "ncpfs", NULL); + _exit(127); /* execl error */ + } else { - /* parent */ - while (waitpid(pid, &status, 0) < 0) + /* parent */ + while (waitpid(pid, &status, 0) < 0) { - if (errno != EINTR) + if (errno != EINTR) { - status = -1; - break; - } - } - } - return status; + status = -1; + break; + } + } + } + return status; } -#endif /* HAVE_KERNELD */ +#endif /* HAVE_KERNELD */ /* Check whether user is allowed to mount on the specified mount point */ static int mount_ok(struct stat *st) { - if (!S_ISDIR(st->st_mode)) - { - errno = ENOTDIR; - return -1; - } - - if ( (getuid() != 0) - && ( (getuid() != st->st_uid) - || ((st->st_mode & S_IRWXU) != S_IRWXU))) - { - errno = EPERM; - return -1; - } - - return 0; + if (!S_ISDIR(st->st_mode)) + { + errno = ENOTDIR; + return -1; + } + if ((getuid() != 0) + && ((getuid() != st->st_uid) + || ((st->st_mode & S_IRWXU) != S_IRWXU))) + { + errno = EPERM; + return -1; + } + return 0; } -int +int main(int argc, char *argv[]) { - struct ncp_mount_data data; - struct stat st; + struct ncp_mount_data data; + struct stat st; char mount_name[256]; - int fd, result; + int fd, result; struct sockaddr_ipx addr; struct sockaddr_ipx *server_addr; int addrlen; - int upcase_password; + int upcase_password; long err; - int um; + int um; unsigned int flags; - char mount_point[MAXPATHLEN]; - struct mntent ment; - FILE *mtab; + char mount_point[MAXPATHLEN]; + struct mntent ment; + FILE *mtab; char *tmp_mount; - char *server = NULL; - char *user = NULL; + char *server = NULL; + char *user = NULL; char *password = NULL; struct ncp_conn_spec *spec; @@ -179,36 +173,36 @@ main(int argc, char *argv[]) int opt; - progname = argv[0]; + progname = argv[0]; - memzero(data); memzero(spec); + memzero(data); + memzero(spec); if (geteuid() != 0) { - fprintf(stderr, "%s must be installed suid root\n", progname); - exit(1); - } - - data.uid = getuid(); - data.gid = getgid(); - um = umask(0); - umask(um); - data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & ~um; - data.dir_mode = 0; - data.flags |= NCP_MOUNT_SOFT; + fprintf(stderr, "%s must be installed suid root\n", progname); + exit(1); + } + data.uid = getuid(); + data.gid = getgid(); + um = umask(0); + umask(um); + data.file_mode = (S_IRWXU | S_IRWXG | S_IRWXO) & ~um; + data.dir_mode = 0; + data.flags |= NCP_MOUNT_SOFT; data.time_out = 60; data.retry_count = 5; upcase_password = 1; - while ((opt = getopt (argc, argv, "CS:U:c:u:g:f:d:P:nh?vV:t:r:")) + while ((opt = getopt(argc, argv, "CS:U:c:u:g:f:d:P:nh?vV:t:r:")) != EOF) { - switch (opt) + switch (opt) { - case 'C': - upcase_password = 0; - break; + case 'C': + upcase_password = 0; + break; case 'S': if (strlen(optarg) >= sizeof(spec->server)) { @@ -218,80 +212,77 @@ main(int argc, char *argv[]) } server = optarg; break; - case 'U': - if (strlen(optarg) >= sizeof(spec->user)) + case 'U': + if (strlen(optarg) >= sizeof(spec->user)) { - fprintf(stderr, "Username too long: %s\n", - optarg); - return 1; - } + fprintf(stderr, "Username too long: %s\n", + optarg); + return 1; + } user = optarg; break; - case 'c': - if (isdigit(optarg[0])) + case 'c': + if (isdigit(optarg[0])) { conn_uid = atoi(optarg); - } - else + } else { - struct passwd *pwd = getpwnam(optarg); - if (pwd == NULL) + struct passwd *pwd = getpwnam(optarg); + if (pwd == NULL) { - fprintf(stderr, "Unknown user: %s\n", - optarg); - return 1; - } - conn_uid = pwd->pw_uid; - } - break; - case 'u': - if (isdigit(optarg[0])) + fprintf(stderr, "Unknown user: %s\n", + optarg); + return 1; + } + conn_uid = pwd->pw_uid; + } + break; + case 'u': + if (isdigit(optarg[0])) { data.uid = atoi(optarg); - } - else + } else { - struct passwd *pwd = getpwnam(optarg); - if (pwd == NULL) + struct passwd *pwd = getpwnam(optarg); + if (pwd == NULL) { - fprintf(stderr, "Unknown user: %s\n", - optarg); - return 1; - } - data.uid = pwd->pw_uid; - } - break; - case 'g': - if (isdigit(optarg[0])) + fprintf(stderr, "Unknown user: %s\n", + optarg); + return 1; + } + data.uid = pwd->pw_uid; + } + break; + case 'g': + if (isdigit(optarg[0])) { - data.gid = atoi(optarg); - } - else + data.gid = atoi(optarg); + } else { - struct group *grp = getgrnam(optarg); - if (grp == NULL) + struct group *grp = getgrnam(optarg); + if (grp == NULL) { - fprintf(stderr, "Unknown group: %s\n", - optarg); - return 1; - } - data.gid = grp->gr_gid; - } - break; - case 'f': - data.file_mode = strtol(optarg, NULL, 8); - break; - case 'd': - data.dir_mode = strtol(optarg, NULL, 8); - break; - case 'P': + fprintf(stderr, "Unknown group: %s\n", + optarg); + return 1; + } + data.gid = grp->gr_gid; + } + break; + case 'f': + data.file_mode = strtol(optarg, NULL, 8); + break; + case 'd': + data.dir_mode = strtol(optarg, NULL, 8); + break; + case 'P': if (strlen(optarg) >= sizeof(spec->password)) { printf("password too long\n"); exit(1); } password = optarg; - break; + break; case 'V': if (strlen(optarg) >= sizeof(data.mounted_vol)) { @@ -300,9 +291,9 @@ main(int argc, char *argv[]) } strcpy(data.mounted_vol, optarg); break; - case 'n': + case 'n': password = ""; - break; + break; case 't': data.time_out = atoi(optarg); break; @@ -316,46 +307,41 @@ main(int argc, char *argv[]) case 'v': fprintf(stderr, "ncpfs version %s\n", NCPFS_VERSION); exit(1); - default: + default: usage(); - return -1; - } - } + return -1; + } + } - if ((spec = ncp_find_conn_spec(server,user,password,1, data.uid, &err)) + if ((spec = ncp_find_conn_spec(server, user, password, 1, data.uid, &err)) == NULL) { com_err(progname, err, "in find_conn_spec"); exit(1); } - if (upcase_password != 0) { str_upper(spec->password); } - - if (optind != argc-1) + if (optind != argc - 1) { usage(); return -1; } - realpath(argv[optind], mount_point); - if (stat(mount_point, &st) == -1) + if (stat(mount_point, &st) == -1) { - fprintf(stderr, "could not find mount point %s: %s\n", - mount_point, strerror(errno)); - exit(1); - } - - if (mount_ok(&st) != 0) + fprintf(stderr, "could not find mount point %s: %s\n", + mount_point, strerror(errno)); + exit(1); + } + if (mount_ok(&st) != 0) { - fprintf(stderr, "cannot to mount on %s: %s\n", - mount_point, strerror(errno)); - exit(1); - } - + fprintf(stderr, "cannot to mount on %s: %s\n", + mount_point, strerror(errno)); + exit(1); + } #ifndef HAVE_KERNELD /* Check if the ncpfs filesystem is in the kernel. If not, attempt * to load the ncpfs module */ @@ -366,21 +352,20 @@ main(int argc, char *argv[]) } #endif - data.version = NCP_MOUNT_VERSION; - data.mounted_uid = conn_uid; + data.version = NCP_MOUNT_VERSION; + data.mounted_uid = conn_uid; memcpy(data.server_name, spec->server, sizeof(data.server_name)); - if (data.dir_mode == 0) + if (data.dir_mode == 0) { - data.dir_mode = data.file_mode; - if ((data.dir_mode & S_IRUSR) != 0) - data.dir_mode |= S_IXUSR; - if ((data.dir_mode & S_IRGRP) != 0) - data.dir_mode |= S_IXGRP; - if ((data.dir_mode & S_IROTH) != 0) - data.dir_mode |= S_IXOTH; - } - + data.dir_mode = data.file_mode; + if ((data.dir_mode & S_IRUSR) != 0) + data.dir_mode |= S_IXUSR; + if ((data.dir_mode & S_IRGRP) != 0) + data.dir_mode |= S_IXGRP; + if ((data.dir_mode & S_IROTH) != 0) + data.dir_mode |= S_IXOTH; + } if ((tmp_mount = ncp_find_permanent(spec)) != NULL) { @@ -390,7 +375,6 @@ main(int argc, char *argv[]) tmp_mount); exit(1); } - if ((server_addr = ncp_find_fileserver(spec->server, &err)) == NULL) { com_err("ncpmount", err, "when trying to find %s", @@ -399,13 +383,12 @@ main(int argc, char *argv[]) } data.serv_addr = *server_addr; - data.ncp_fd = socket(AF_IPX, SOCK_DGRAM, PF_IPX); + data.ncp_fd = socket(AF_IPX, SOCK_DGRAM, PF_IPX); if (data.ncp_fd == -1) { com_err("ncpmount", err, "opening ncp_socket"); exit(1); } - data.wdog_fd = socket(AF_IPX, SOCK_DGRAM, PF_IPX); if (data.wdog_fd == -1) { @@ -413,11 +396,10 @@ main(int argc, char *argv[]) strerror(errno)); exit(1); } - memzero(addr); addr.sipx_type = NCP_PTYPE; - if (bind(data.ncp_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) + if (bind(data.ncp_fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) { fprintf(stderr, "\nbind: %s\n", strerror(errno)); @@ -427,25 +409,23 @@ main(int argc, char *argv[]) "and try again after waiting a minute.\n\n"); exit(1); } - addrlen = sizeof(addr); - if (getsockname(data.ncp_fd, (struct sockaddr *)&addr, &addrlen)==-1) + if (getsockname(data.ncp_fd, (struct sockaddr *) &addr, &addrlen) == -1) { perror("getsockname ncp socket"); - close(data.ncp_fd); close(data.wdog_fd); + close(data.ncp_fd); + close(data.wdog_fd); exit(1); } - addr.sipx_port = htons(ntohs(addr.sipx_port) + 1); - if (bind(data.wdog_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) + if (bind(data.wdog_fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) { fprintf(stderr, "bind(wdog_sock, ): %s\n", strerror(errno)); exit(1); } - #if NCP_MOUNT_VERSION>1 data.message_fd = socket(AF_IPX, SOCK_DGRAM, PF_IPX); @@ -455,16 +435,14 @@ main(int argc, char *argv[]) strerror(errno)); exit(1); } - addr.sipx_port = htons(ntohs(addr.sipx_port) + 1); - if (bind(data.message_fd, (struct sockaddr *)&addr,sizeof(addr)) == -1) + if (bind(data.message_fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) { fprintf(stderr, "bind(message_sock, ): %s\n", strerror(errno)); exit(1); } - if (strlen(mount_point) < sizeof(data.mount_point)) { strcpy(data.mount_point, mount_point); @@ -477,26 +455,24 @@ main(int argc, char *argv[]) strcat(mount_name, "/"); strcat(mount_name, spec->user); - result = mount(mount_name, mount_point, "ncpfs", flags, (char *)&data); + result = mount(mount_name, mount_point, "ncpfs", flags, (char *) &data); if (result < 0) { printf("mount failed\n"); exit(1); } - if ((conn = ncp_open_mount(mount_point, &err)) == NULL) { com_err("ncpmount", err, "attempt to open mount point"); umount(mount_point); exit(1); } - if ((err = ncp_login_user(conn, spec->user, spec->password)) != 0) { struct nw_property p; struct ncp_prop_login_control *l - = (struct ncp_prop_login_control *)&p; + = (struct ncp_prop_login_control *) &p; if (conn->completion != NCP_GRACE_PERIOD) { @@ -506,7 +482,6 @@ main(int argc, char *argv[]) umount(mount_point); exit(1); } - fprintf(stderr, "Your password has expired\n"); if ((err = ncp_read_property_value(conn, NCP_BINDERY_USER, @@ -517,7 +492,6 @@ main(int argc, char *argv[]) l->GraceLogins); } } - if ((err = ioctl(conn->mount_fid, NCP_IOC_CONN_LOGGED_IN, NULL)) != 0) { com_err("ncpmount", err, "in logged_indication"); @@ -527,78 +501,76 @@ main(int argc, char *argv[]) } ncp_close(conn); - ment.mnt_fsname = mount_name; - ment.mnt_dir = mount_point; - ment.mnt_type = "ncpfs"; - ment.mnt_opts = "rw"; - ment.mnt_freq = 0; - ment.mnt_passno= 0; + ment.mnt_fsname = mount_name; + ment.mnt_dir = mount_point; + ment.mnt_type = "ncpfs"; + ment.mnt_opts = "rw"; + ment.mnt_freq = 0; + ment.mnt_passno = 0; - if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) - { - fprintf(stderr, "Can't get "MOUNTED"~ lock file"); - exit(1); - } - close(fd); - - if ((mtab = setmntent(MOUNTED, "a+")) == NULL) - { - fprintf(stderr, "Can't open " MOUNTED); - exit(1); - } + if ((fd = open(MOUNTED "~", O_RDWR | O_CREAT | O_EXCL, 0600)) == -1) + { + fprintf(stderr, "Can't get " MOUNTED "~ lock file"); + exit(1); + } + close(fd); - if (addmntent(mtab, &ment) == 1) - { - fprintf(stderr, "Can't write mount entry"); - exit(1); - } - if (fchmod(fileno(mtab), 0644) == -1) - { - fprintf(stderr, "Can't set perms on "MOUNTED); - exit(1); - } - endmntent(mtab); - - if (unlink(MOUNTED"~") == -1) - { - fprintf(stderr, "Can't remove "MOUNTED"~"); - exit(1); - } + if ((mtab = setmntent(MOUNTED, "a+")) == NULL) + { + fprintf(stderr, "Can't open " MOUNTED); + exit(1); + } + if (addmntent(mtab, &ment) == 1) + { + fprintf(stderr, "Can't write mount entry"); + exit(1); + } + if (fchmod(fileno(mtab), 0644) == -1) + { + fprintf(stderr, "Can't set perms on " MOUNTED); + exit(1); + } + endmntent(mtab); + if (unlink(MOUNTED "~") == -1) + { + fprintf(stderr, "Can't remove " MOUNTED "~"); + exit(1); + } return 0; -} +} static void usage(void) { printf("usage: %s [options] mount-point\n", progname); - printf("Try `%s -h' for more information\n", progname); + printf("Try `%s -h' for more information\n", progname); } static void help(void) { - printf("\n"); - printf("usage: %s [options] mount-point\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options] mount-point\n", progname); + printf("\n" "-S server Server name to be used\n" - "-U username Username sent to server\n" + "-U username Username sent to server\n" "-V volume Volume to mount, for NFS re-export\n" - "-u uid uid the mounted files get\n" - "-g gid gid the mounted files get\n" - "-f mode permission the files get (octal notation)\n" - "-d mode permission the dirs get (octal notation)\n" + "-u uid uid the mounted files get\n" + "-g gid gid the mounted files get\n" + "-f mode permission the files get (octal notation)\n" + "-d mode permission the dirs get (octal notation)\n" "-c uid uid to identify the connection to mount on\n" " Only makes sense for root\n" "-t time_out Waiting time (in 1/100s) to wait for\n" " an answer from the server. Default: 60\n" "-r retry_count Number of retry attempts. Default: 5\n" - "-C Don't convert password to uppercase\n" - "-P password Use this password\n" - "-n Do not use any password\n" - " If neither -P nor -n are given, you are\n" - " asked for a password.\n" - "-h print this help text\n" + "-C Don't convert password to uppercase\n" + "-P password Use this password\n" + "-n Do not use any password\n" + " If neither -P nor -n are given, you are\n" + " asked for a password.\n" + "-h print this help text\n" "-v print ncpfs version number\n" - "\n"); + "\n"); } diff --git a/sutil/ncpumount.c b/sutil/ncpumount.c index 521776e..15a7e96 100644 --- a/sutil/ncpumount.c +++ b/sutil/ncpumount.c @@ -16,7 +16,7 @@ #include #include #include -/* #include */ /* generates a warning here */ + /* #include *//* generates a warning here */ extern pid_t waitpid(pid_t, int *, int); #include #include @@ -38,36 +38,36 @@ static char *progname; static void usage(void) { - printf("usage: %s mount-point\n", progname); + printf("usage: %s mount-point\n", progname); } static int umount_ok(const char *mount_point) { - int fid = open(mount_point, O_RDONLY, 0); - uid_t mount_uid; + int fid = open(mount_point, O_RDONLY, 0); + uid_t mount_uid; - if (fid == -1) { - fprintf(stderr, "Could not open %s: %s\n", - mount_point, strerror(errno)); - return -1; - } - - if (ioctl(fid, NCP_IOC_GETMOUNTUID, &mount_uid) != 0) { - fprintf(stderr, "%s probably not ncp-filesystem\n", - mount_point); - return -1; - } - - if ( (getuid() != 0) - && (mount_uid != getuid())) { - fprintf(stderr, "You are not allowed to umount %s\n", - mount_point); - return -1; - } - - close(fid); - return 0; + if (fid == -1) + { + fprintf(stderr, "Could not open %s: %s\n", + mount_point, strerror(errno)); + return -1; + } + if (ioctl(fid, NCP_IOC_GETMOUNTUID, &mount_uid) != 0) + { + fprintf(stderr, "%s probably not ncp-filesystem\n", + mount_point); + return -1; + } + if ((getuid() != 0) + && (mount_uid != getuid())) + { + fprintf(stderr, "You are not allowed to umount %s\n", + mount_point); + return -1; + } + close(fid); + return 0; } /* Make a canonical pathname from PATH. Returns a freshly malloced string. @@ -76,118 +76,117 @@ umount_ok(const char *mount_point) is not a legal pathname for ``/dev/fd0.'' Anything we cannot parse we return unmodified. */ char * -canonicalize (const char *path) +canonicalize(const char *path) { - char *canonical = malloc (PATH_MAX + 1); - - if (path == NULL) - return NULL; - - if (realpath (path, canonical)) - return canonical; + char *canonical = malloc(PATH_MAX + 1); - if (strlen(path) > PATH_MAX) - { - return NULL; - } + if (path == NULL) + return NULL; - strcpy (canonical, path); - return canonical; + if (realpath(path, canonical)) + return canonical; + + if (strlen(path) > PATH_MAX) + { + return NULL; + } + strcpy(canonical, path); + return canonical; } -int +int main(int argc, char *argv[]) { - int fd; + int fd; - char* mount_point; + char *mount_point; - struct mntent *mnt; - FILE* mtab; - FILE* new_mtab; + struct mntent *mnt; + FILE *mtab; + FILE *new_mtab; - progname = argv[0]; + progname = argv[0]; - if (geteuid() != 0) { - fprintf(stderr, "%s must be installed suid root\n", progname); - exit(1); - } - - if (argc != 2) { - usage(); - exit(1); - } - - mount_point = canonicalize(argv[1]); + if (geteuid() != 0) + { + fprintf(stderr, "%s must be installed suid root\n", progname); + exit(1); + } + if (argc != 2) + { + usage(); + exit(1); + } + mount_point = canonicalize(argv[1]); if (mount_point == NULL) { fprintf(stderr, "Invalid mount point: %s\n", argv[1]); exit(1); } - - if (umount_ok(mount_point) != 0) { + if (umount_ok(mount_point) != 0) + { fprintf(stderr, "You are not allowed to umount %s\n", mount_point); - exit(1); - } - - if (umount(mount_point) != 0) { - fprintf(stderr, "Could not umount %s: %s\n", - mount_point, strerror(errno)); - exit(1); - } - - if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) - { - fprintf(stderr, "Can't get "MOUNTED"~ lock file"); - return 1; - } - close(fd); - - if ((mtab = setmntent(MOUNTED, "r")) == NULL) { - fprintf(stderr, "Can't open " MOUNTED ": %s\n", - strerror(errno)); - return 1; - } + exit(1); + } + if (umount(mount_point) != 0) + { + fprintf(stderr, "Could not umount %s: %s\n", + mount_point, strerror(errno)); + exit(1); + } + if ((fd = open(MOUNTED "~", O_RDWR | O_CREAT | O_EXCL, 0600)) == -1) + { + fprintf(stderr, "Can't get " MOUNTED "~ lock file"); + return 1; + } + close(fd); + if ((mtab = setmntent(MOUNTED, "r")) == NULL) + { + fprintf(stderr, "Can't open " MOUNTED ": %s\n", + strerror(errno)); + return 1; + } #define MOUNTED_TMP MOUNTED".tmp" - if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) { - fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n", - strerror(errno)); - endmntent(mtab); - return 1; - } + if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) + { + fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n", + strerror(errno)); + endmntent(mtab); + return 1; + } + while ((mnt = getmntent(mtab)) != NULL) + { + if (strcmp(mnt->mnt_dir, mount_point) != 0) + { + addmntent(new_mtab, mnt); + } + } - while ((mnt = getmntent(mtab)) != NULL) { - if (strcmp(mnt->mnt_dir, mount_point) != 0) { - addmntent(new_mtab, mnt); - } - } + endmntent(mtab); - endmntent(mtab); - - if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { - fprintf(stderr, "Error changing mode of %s: %s\n", - MOUNTED_TMP, strerror(errno)); - exit(1); - } - - endmntent(new_mtab); - - if (rename(MOUNTED_TMP, MOUNTED) < 0) { - fprintf(stderr, "Cannot rename %s to %s: %s\n", - MOUNTED, MOUNTED_TMP, strerror(errno)); - exit(1); - } - - if (unlink(MOUNTED"~") == -1) - { - fprintf(stderr, "Can't remove "MOUNTED"~"); - return 1; - } + if (fchmod(fileno(new_mtab), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) + { + fprintf(stderr, "Error changing mode of %s: %s\n", + MOUNTED_TMP, strerror(errno)); + exit(1); + } + endmntent(new_mtab); + if (rename(MOUNTED_TMP, MOUNTED) < 0) + { + fprintf(stderr, "Cannot rename %s to %s: %s\n", + MOUNTED, MOUNTED_TMP, strerror(errno)); + exit(1); + } + if (unlink(MOUNTED "~") == -1) + { + fprintf(stderr, "Can't remove " MOUNTED "~"); + return 1; + } return 0; -} +} diff --git a/sutil/nwcrypt.c b/sutil/nwcrypt.c index 4c028da..be33914 100644 --- a/sutil/nwcrypt.c +++ b/sutil/nwcrypt.c @@ -1,17 +1,17 @@ /*$********************************************************* -$* -$* This code has been taken from DDJ 11/93, from an -$* article by Pawel Szczerbina. -$* -$* Password encryption routines follow. -$* Converted to C from Barry Nance's Pascal -$* prog published in the March -93 issue of Byte. -$* -$* Adapted to be useable for ncpfs by -$* Volker Lendecke in -$* October 1995. -$* -$**********************************************************/ + $* + $* This code has been taken from DDJ 11/93, from an + $* article by Pawel Szczerbina. + $* + $* Password encryption routines follow. + $* Converted to C from Barry Nance's Pascal + $* prog published in the March -93 issue of Byte. + $* + $* Adapted to be useable for ncpfs by + $* Volker Lendecke in + $* October 1995. + $* + $********************************************************* */ /**************************************************************************** @@ -91,28 +91,28 @@ typedef unsigned char buf8[8]; typedef unsigned char buf4[4]; static unsigned char encrypttable[256] = -{0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8, - 0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9, - 0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6, - 0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0, - 0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD, - 0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE, - 0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7, - 0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1, - 0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4, - 0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2, - 0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3, - 0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0, - 0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8, - 0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3, - 0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0, - 0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD}; +{0x7, 0x8, 0x0, 0x8, 0x6, 0x4, 0xE, 0x4, 0x5, 0xC, 0x1, 0x7, 0xB, 0xF, 0xA, 0x8, +0xF, 0x8, 0xC, 0xC, 0x9, 0x4, 0x1, 0xE, 0x4, 0x6, 0x2, 0x4, 0x0, 0xA, 0xB, 0x9, +0x2, 0xF, 0xB, 0x1, 0xD, 0x2, 0x1, 0x9, 0x5, 0xE, 0x7, 0x0, 0x0, 0x2, 0x6, 0x6, +0x0, 0x7, 0x3, 0x8, 0x2, 0x9, 0x3, 0xF, 0x7, 0xF, 0xC, 0xF, 0x6, 0x4, 0xA, 0x0, +0x2, 0x3, 0xA, 0xB, 0xD, 0x8, 0x3, 0xA, 0x1, 0x7, 0xC, 0xF, 0x1, 0x8, 0x9, 0xD, +0x9, 0x1, 0x9, 0x4, 0xE, 0x4, 0xC, 0x5, 0x5, 0xC, 0x8, 0xB, 0x2, 0x3, 0x9, 0xE, +0x7, 0x7, 0x6, 0x9, 0xE, 0xF, 0xC, 0x8, 0xD, 0x1, 0xA, 0x6, 0xE, 0xD, 0x0, 0x7, +0x7, 0xA, 0x0, 0x1, 0xF, 0x5, 0x4, 0xB, 0x7, 0xB, 0xE, 0xC, 0x9, 0x5, 0xD, 0x1, +0xB, 0xD, 0x1, 0x3, 0x5, 0xD, 0xE, 0x6, 0x3, 0x0, 0xB, 0xB, 0xF, 0x3, 0x6, 0x4, +0x9, 0xD, 0xA, 0x3, 0x1, 0x4, 0x9, 0x4, 0x8, 0x3, 0xB, 0xE, 0x5, 0x0, 0x5, 0x2, +0xC, 0xB, 0xD, 0x5, 0xD, 0x5, 0xD, 0x2, 0xD, 0x9, 0xA, 0xC, 0xA, 0x0, 0xB, 0x3, +0x5, 0x3, 0x6, 0x9, 0x5, 0x1, 0xE, 0xE, 0x0, 0xE, 0x8, 0x2, 0xD, 0x2, 0x2, 0x0, +0x4, 0xF, 0x8, 0x5, 0x9, 0x6, 0x8, 0x6, 0xB, 0xA, 0xB, 0xF, 0x0, 0x7, 0x2, 0x8, +0xC, 0x7, 0x3, 0xA, 0x1, 0x4, 0x2, 0x5, 0xF, 0x7, 0xA, 0xC, 0xE, 0x5, 0x9, 0x3, +0xE, 0x7, 0x1, 0x2, 0xE, 0x1, 0xF, 0x4, 0xA, 0x6, 0xC, 0x6, 0xF, 0x4, 0x3, 0x0, + 0xC, 0x0, 0x3, 0x6, 0xF, 0x8, 0x7, 0xB, 0x2, 0xD, 0xC, 0x6, 0xA, 0xA, 0x8, 0xD}; -static buf32 encryptkeys = -{0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D, - 0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35, - 0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11, - 0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0}; +static buf32 encryptkeys = +{0x48, 0x93, 0x46, 0x67, 0x98, 0x3D, 0xE6, 0x8D, + 0xB7, 0x10, 0x7A, 0x26, 0x5A, 0xB9, 0xB1, 0x35, + 0x6B, 0x0F, 0xD5, 0x70, 0xAE, 0xFB, 0xAD, 0x11, + 0xF4, 0x47, 0xDC, 0xA7, 0xEC, 0xCF, 0x50, 0xC0}; static void @@ -128,15 +128,16 @@ shuffle1(buf32 temp, unsigned char *target) { for (s = 0; s <= 31; ++s) { - b3 = (temp[s]+b4) ^ (temp[(s+b4)&31] - encryptkeys[s]); + b3 = (temp[s] + b4) ^ (temp[(s + b4) & 31] - encryptkeys[s]); b4 = b4 + b3; temp[s] = b3; } } - for (i = 0; i <= 15; ++i) { - target[i] = encrypttable[temp[ 2*i ]] - | (encrypttable[temp[ 2*i + 1]] << 4); + for (i = 0; i <= 15; ++i) + { + target[i] = encrypttable[temp[2 * i]] + | (encrypttable[temp[2 * i + 1]] << 4); } } @@ -148,12 +149,14 @@ shuffle(const unsigned char *lon, const unsigned char *buf, int buflen, int b2, d, s; buf32 temp; - while ( (buflen > 0) - && (buf[buflen - 1] == 0)) { + while ((buflen > 0) + && (buf[buflen - 1] == 0)) + { buflen = buflen - 1; } - for (s = 0; s < 32; s++) { + for (s = 0; s < 32; s++) + { temp[s] = 0; } @@ -176,17 +179,17 @@ shuffle(const unsigned char *lon, const unsigned char *buf, int buflen, { b2 = d; temp[s] = temp[s] ^ encryptkeys[s]; - } else { + } else + { temp[s] = temp[s] ^ buf[b2]; b2 = b2 + 1; } } } - for (s = 0; s <= 31; ++s) temp[s] = temp[s] ^ lon[s & 3]; - shuffle1(temp,target); + shuffle1(temp, target); } @@ -198,7 +201,7 @@ nw_encrypt(const unsigned char *fra, buf32 k; int s; - shuffle(&(fra[0]), buf, 16, &(k[ 0])); + shuffle(&(fra[0]), buf, 16, &(k[0])); shuffle(&(fra[4]), buf, 16, &(k[16])); for (s = 0; s <= 15; ++s) diff --git a/sutil/nwsfind.c b/sutil/nwsfind.c index 2220337..62086cd 100644 --- a/sutil/nwsfind.c +++ b/sutil/nwsfind.c @@ -25,16 +25,16 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [server]\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [server]\n", progname); + printf("\n" "-t Server type, default: File server\n" "-h Print this help text\n" "\n"); } static void -swallow_error(const char * name, long code, const char *format, va_list arg) +swallow_error(const char *name, long code, const char *format, va_list arg) { printf("%s ", error_message(code)); vfprintf(stdout, format, arg); @@ -58,7 +58,8 @@ main(int argc, char *argv[]) while ((opt = getopt(argc, argv, "t:")) != EOF) { - switch(opt) { + switch (opt) + { case 't': object_type = atoi(optarg); break; @@ -72,13 +73,12 @@ main(int argc, char *argv[]) } } - if (optind < argc-1) + if (optind < argc - 1) { usage(); exit(1); } - - if (optind == argc-1) + if (optind == argc - 1) { server = argv[optind]; if (strlen(server) >= NCP_BINDERY_NAME_LEN) @@ -86,8 +86,7 @@ main(int argc, char *argv[]) com_err(argv[0], ENAMETOOLONG, "server name too long"); exit(1); } - } - + } result = ncp_find_server(&server, object_type, &err); if (result == NULL) @@ -95,7 +94,6 @@ main(int argc, char *argv[]) com_err(argv[0], err, "when trying to find server"); exit(1); } - ipx_print_saddr(result); printf(" %s\n", server); return 0; diff --git a/util/Makefile b/util/Makefile index 1ef9936..c73f6b7 100644 --- a/util/Makefile +++ b/util/Makefile @@ -6,7 +6,7 @@ USERUTILS = slist pqlist nwfsinfo pserver nprint nsend ncopy nwpasswd USERUTILS += nwbols nwbocreate nwborm nwboprops USERUTILS += nwbpcreate nwbprm nwbpvalues nwbpadd nwbpset USERUTILS += nwgrant nwrevoke nwuserlist nwrights nwauth -USERUTILS += nwfstime +USERUTILS += nwfstime nwvolinfo SBINUTILS = nwmsg UTILS = $(USERUTILS) $(SBINUTILS) ncptest diff --git a/util/ncopy.c b/util/ncopy.c index 918c36d..b59b0f6 100644 --- a/util/ncopy.c +++ b/util/ncopy.c @@ -27,9 +27,9 @@ struct NCPMountRec { - char *mountDir; - char *server; - struct ncp_conn *conn; + char *mountDir; + char *server; + struct ncp_conn *conn; }; /**************************************************************************** @@ -37,30 +37,30 @@ struct NCPMountRec * */ const char *VersionStr = "0.1"; -char * ProgramName; +char *ProgramName; struct NCPMountRec *NcpMountTable = NULL; int ncpCount = 0; /* (initialized) command options */ -int optVersion=0; /* -V TRUE if just want version */ -int optVerbose=0; /* -v TRUE if want verbose output */ -int optNice=0; /* -n TRUE if we are cooperative (nice) */ -int optNiceFactorSel=0; /* -s TRUE if we selected a nice factor */ -int optNiceFactor=10; /* -s arg, number of 100K blocks to copy - before sleeping for a second */ -__u32 CopyBlockSize = 100000; /* Size of the default block copy size */ -unsigned int NiceSleepTime=1; /* Number of seconds to sleep in Nice Mode */ +int optVersion = 0; /* -V TRUE if just want version */ +int optVerbose = 0; /* -v TRUE if want verbose output */ +int optNice = 0; /* -n TRUE if we are cooperative (nice) */ +int optNiceFactorSel = 0; /* -s TRUE if we selected a nice factor */ +int optNiceFactor = 10; /* -s arg, number of 100K blocks to copy + before sleeping for a second */ +__u32 CopyBlockSize = 100000; /* Size of the default block copy size */ +unsigned int NiceSleepTime = 1; /* Number of seconds to sleep in Nice Mode */ -int BlocksCopied=0; /* Number of blocks copied */ -int MaxNcopyRetries=25; /* Maximum number of times to retry a failed - copy before giving up */ +int BlocksCopied = 0; /* Number of blocks copied */ +int MaxNcopyRetries = 25; /* Maximum number of times to retry a failed + copy before giving up */ /* Globals needed for signal handlers */ -int OutputOpen=0; /* True if the ncp output file is open */ -struct ncp_conn *CurrentConn = NULL; /* Connection of output file */ -struct ncp_file_info *CurrentFile = NULL; /* File info of output file */ +int OutputOpen = 0; /* True if the ncp output file is open */ +struct ncp_conn *CurrentConn = NULL; /* Connection of output file */ +struct ncp_file_info *CurrentFile = NULL; /* File info of output file */ /* Signal control structures */ static struct sigaction sHangupSig; @@ -71,11 +71,12 @@ static struct sigaction sTermSig; /**************************************************************************** * */ -static void usage() +static void +usage() { - fprintf(stderr,"usage: %s [-V]\n", ProgramName); - fprintf(stderr," %s [-vn] [-s amt] sourcefile destinationfile|directory\n", ProgramName); - fprintf(stderr," %s [-vn] [-s amt] sourcefile [...] directory\n", ProgramName); + fprintf(stderr, "usage: %s [-V]\n", ProgramName); + fprintf(stderr, " %s [-vn] [-s amt] sourcefile destinationfile|directory\n", ProgramName); + fprintf(stderr, " %s [-vn] [-s amt] sourcefile [...] directory\n", ProgramName); } /**************************************************************************** @@ -84,165 +85,193 @@ static void usage() * ("/" returns pointer to "/", null returns pointer to null) * Return pointer to original string if no "/" in string. (except at end) */ -static const char *myBaseName(const char *path) +static const char * +myBaseName(const char *path) { - const char *p; + const char *p; - for(p = &path[strlen(path)]; p != path; p--) { /* skip ENDING "/" chars */ - if(*p && *p != '/') break; - } - if(p==path) return p; - for( ; p != path || *p == '/'; p--) { - if(*p == '/') return ++p; - } - return p; + for (p = &path[strlen(path)]; p != path; p--) + { /* skip ENDING "/" chars */ + if (*p && *p != '/') + break; + } + if (p == path) + return p; + for (; p != path || *p == '/'; p--) + { + if (*p == '/') + return ++p; + } + return p; } /**************************************************************************** * */ -static const char *notDir(const char *path) +static const char * +notDir(const char *path) { - struct stat buf; - static const char *notDirectory="not a directory"; + struct stat buf; + static const char *notDirectory = "not a directory"; - if(stat(path, &buf)) return strerror(errno); /* no permission? not exist? */ - if(!S_ISDIR(buf.st_mode)) return notDirectory; /* not a directory */ - return (char *) 0; /* OK */ + if (stat(path, &buf)) + return strerror(errno); /* no permission? not exist? */ + if (!S_ISDIR(buf.st_mode)) + return notDirectory; /* not a directory */ + return (char *) 0; /* OK */ } /**************************************************************************** * */ -static int handleOptions(const int argc, char * const argv[]) +static int +handleOptions(const int argc, char *const argv[]) { - int opt; + int opt; - while ((opt = getopt(argc, argv, "vVns:")) != EOF) - { - switch (opt) { + while ((opt = getopt(argc, argv, "vVns:")) != EOF) + { + switch (opt) + { - case 'V': /* Version */ - optVersion=1; - break; + case 'V': /* Version */ + optVersion = 1; + break; - case 'v': /* Verbose output */ - optVerbose=1; - break; + case 'v': /* Verbose output */ + optVerbose = 1; + break; - case 'n': /* Nice, cooperative copy */ - optNice=1; - break; + case 'n': /* Nice, cooperative copy */ + optNice = 1; + break; - case 's': /* Nice Factor */ - optNiceFactorSel=1; - optNiceFactor=atoi(optarg); - if (optNiceFactor < 1) { - fprintf(stderr,"%s: -s option requires positive numeric argument > 0\n", - ProgramName); - return 1; - } - break; + case 's': /* Nice Factor */ + optNiceFactorSel = 1; + optNiceFactor = atoi(optarg); + if (optNiceFactor < 1) + { + fprintf(stderr, "%s: -s option requires positive numeric argument > 0\n", + ProgramName); + return 1; + } + break; - default: /* invalid options or options without required arguments */ - return 1; - } - continue; - } - return 0; + default: /* invalid options or options without required arguments */ + return 1; + } + continue; + } + return 0; } /**************************************************************************** * TODO: if recursive flag last MUST be a directory, even if only 2 args. */ -static int validateFileArgs(const int argc, char * const argv[]) +static int +validateFileArgs(const int argc, char *const argv[]) { - const char *p; - if (argc == 0) { - fprintf(stderr,"%s: No arguments specified.\n", ProgramName); - return 1; - } - if(argc == 1) { - fprintf(stderr,"%s: No destination specified.\n", ProgramName); - return 1; - } - if((argc > 2) && (p=notDir(argv[argc-1]))) { /* last arg MUST be dir */ - fprintf(stderr,"%s: %s: %s\n", ProgramName, argv[argc-1], p); - return 1; - } - return 0; + const char *p; + if (argc == 0) + { + fprintf(stderr, "%s: No arguments specified.\n", ProgramName); + return 1; + } + if (argc == 1) + { + fprintf(stderr, "%s: No destination specified.\n", ProgramName); + return 1; + } + if ((argc > 2) && (p = notDir(argv[argc - 1]))) + { /* last arg MUST be dir */ + fprintf(stderr, "%s: %s: %s\n", ProgramName, argv[argc - 1], p); + return 1; + } + return 0; } /**************************************************************************** * Duplicate a string. */ -char *duplicateStr(const char *InStr) +char * +duplicateStr(const char *InStr) { - char *dup; - if (!InStr) return NULL; - dup = (char*)malloc(strlen(InStr)+1); - if (dup) - strcpy(dup,InStr); - return dup; + char *dup; + if (!InStr) + return NULL; + dup = (char *) malloc(strlen(InStr) + 1); + if (dup) + strcpy(dup, InStr); + return dup; } /**************************************************************************** * load a table of ncpfs mount points. */ -int loadMountTable() +int +loadMountTable() { - FILE *mountedFile; - struct mntent *mountEntry = NULL; - ncpCount = 0; - if ( (mountedFile = fopen(MOUNTED,"r")) == NULL) { - fprintf(stderr,"ncopy: cannot open %s, %s\n",MOUNTED,strerror(errno)); - return 1; - } - - while ( (mountEntry = getmntent(mountedFile)) != NULL) { - if (!strcmp(mountEntry->mnt_type,"ncpfs")) - ncpCount++; - } - if (ncpCount) { - NcpMountTable = (struct NCPMountRec*) - malloc(ncpCount * sizeof(struct NCPMountRec)); - if (!NcpMountTable) { - fprintf(stderr,"Out of memory\n"); - fclose(mountedFile); - return 1; - } - fseek(mountedFile,0,SEEK_SET); - ncpCount = 0; - while ( (mountEntry = getmntent(mountedFile)) != NULL) { - if (!strcmp(mountEntry->mnt_type,"ncpfs")) { - NcpMountTable[ncpCount].mountDir = duplicateStr(mountEntry->mnt_dir); - NcpMountTable[ncpCount].server = - duplicateStr(mountEntry->mnt_fsname); - NcpMountTable[ncpCount].conn = NULL; - ncpCount++; - } - } - } - fclose(mountedFile); - return 0; + FILE *mountedFile; + struct mntent *mountEntry = NULL; + ncpCount = 0; + if ((mountedFile = fopen(MOUNTED, "r")) == NULL) + { + fprintf(stderr, "ncopy: cannot open %s, %s\n", MOUNTED, strerror(errno)); + return 1; + } + while ((mountEntry = getmntent(mountedFile)) != NULL) + { + if (!strcmp(mountEntry->mnt_type, "ncpfs")) + ncpCount++; + } + if (ncpCount) + { + NcpMountTable = (struct NCPMountRec *) + malloc(ncpCount * sizeof(struct NCPMountRec)); + if (!NcpMountTable) + { + fprintf(stderr, "Out of memory\n"); + fclose(mountedFile); + return 1; + } + fseek(mountedFile, 0, SEEK_SET); + ncpCount = 0; + while ((mountEntry = getmntent(mountedFile)) != NULL) + { + if (!strcmp(mountEntry->mnt_type, "ncpfs")) + { + NcpMountTable[ncpCount].mountDir = duplicateStr(mountEntry->mnt_dir); + NcpMountTable[ncpCount].server = + duplicateStr(mountEntry->mnt_fsname); + NcpMountTable[ncpCount].conn = NULL; + ncpCount++; + } + } + } + fclose(mountedFile); + return 0; } /**************************************************************************** * Releases the table of ncpfs mount points. */ -void releaseMountTable() +void +releaseMountTable() { - int loop; - if (!ncpCount) return; - for (loop = ncpCount; loop; loop--,ncpCount--) { - if (NcpMountTable[loop-1].conn) { - ncp_close(NcpMountTable[loop-1].conn); - NcpMountTable[loop-1].conn = NULL; - } - free(NcpMountTable[loop-1].server); - free(NcpMountTable[loop-1].mountDir); - } - free(NcpMountTable); + int loop; + if (!ncpCount) + return; + for (loop = ncpCount; loop; loop--, ncpCount--) + { + if (NcpMountTable[loop - 1].conn) + { + ncp_close(NcpMountTable[loop - 1].conn); + NcpMountTable[loop - 1].conn = NULL; + } + free(NcpMountTable[loop - 1].server); + free(NcpMountTable[loop - 1].mountDir); + } + free(NcpMountTable); } /**************************************************************************** @@ -250,18 +279,22 @@ void releaseMountTable() * the file. * Returns -1 if the files do not reference the same server. */ -int ncpIndex(const char *InputFile, const char *OutputFile) +int +ncpIndex(const char *InputFile, const char *OutputFile) { - int loop; - char *mountDir; - if (!ncpCount) return -1; - - for (loop = 0; loop < ncpCount; loop++) { - mountDir = NcpMountTable[loop].mountDir; - if (!strncmp(mountDir,InputFile,strlen(mountDir)) && - !strncmp(mountDir,OutputFile,strlen(mountDir))) return loop; - } - return -1; + int loop; + char *mountDir; + if (!ncpCount) + return -1; + + for (loop = 0; loop < ncpCount; loop++) + { + mountDir = NcpMountTable[loop].mountDir; + if (!strncmp(mountDir, InputFile, strlen(mountDir)) && + !strncmp(mountDir, OutputFile, strlen(mountDir))) + return loop; + } + return -1; } @@ -269,117 +302,133 @@ int ncpIndex(const char *InputFile, const char *OutputFile) * Does a regular buffered file copy. * This is used if we cannot use the Netware file copy. */ -int normalFileCopy(const char *InputFile, const char *OutputFile, - char *Buffer,int BufferSize, - const char *paramInputFile, - const char *paramOutputFile) +int +normalFileCopy(const char *InputFile, const char *OutputFile, + char *Buffer, int BufferSize, + const char *paramInputFile, + const char *paramOutputFile) { - int fdIn, fdOut; - long fileSize,totalSize; - struct stat statBuf; - fdIn = open(InputFile,O_RDONLY); - if (fdIn == -1) { - fprintf(stderr,"%s: Cannot open %s, %s\n",ProgramName,paramInputFile, - strerror(errno)); - return 1; - } - if (fstat(fdIn,&statBuf)) { - fprintf(stderr,"%s: Cannot stat %s, %s\n",ProgramName,paramInputFile, - strerror(errno)); - close(fdIn); - return 1; - } - if(S_ISDIR(statBuf.st_mode)) { - close(fdIn); - fprintf(stderr,"%s: %s: omitting directory\n",ProgramName,paramInputFile); - return 0; /* At this point, don't consider this a fatal error */ - } - - fdOut = open(OutputFile,O_CREAT | O_TRUNC | O_WRONLY,statBuf.st_mode); - if (fdOut == -1) { - fprintf(stderr,"%s: Cannot create %s, %s\n",ProgramName,paramOutputFile, - strerror(errno)); - close(fdIn); - return 1; - } - fileSize = lseek(fdIn,0,SEEK_END); - if (fileSize < 0) { - fprintf(stderr,"%s: lseek error on %s, %s\n",ProgramName,paramInputFile, - strerror(errno)); - close(fdOut); - close(fdIn); - return 1; - } - lseek(fdIn,0,SEEK_SET); - if (optVerbose) { - printf("Normal copy: %s -> %s 0%%",paramInputFile,paramOutputFile); - fflush(stdout); - } - totalSize = fileSize; - while (fileSize) { - int currentMove; - int writeAmt; - currentMove = (fileSize > BufferSize) ? BufferSize : fileSize; - if (read(fdIn,Buffer,currentMove) != currentMove) { - fprintf(stderr,"%s: Error reading %s, %s\n",ProgramName,paramInputFile, - strerror(errno)); - close(fdIn); - close(fdOut); - return 1; - } - writeAmt = write(fdOut,Buffer,currentMove); - if (writeAmt < 0) { - fprintf(stderr,"%s: Error writing %s, %s\n",ProgramName,paramOutputFile, - strerror(errno)); - close(fdIn); - close(fdOut); - return 1; - } else if (writeAmt == 0) { - fprintf(stderr,"%s: Out of space on destination device writing %s\n", - ProgramName,OutputFile); - close(fdIn); - close(fdOut); - return 1; - } - fileSize -= currentMove; - if (optVerbose) { - printf("\rNormal copy: %s -> %s %ld%%",paramInputFile,paramOutputFile,(100 - (fileSize * 100/totalSize))); - fflush(stdout); - } - } - close(fdOut); - close(fdIn); - if (optVerbose) - printf("\n"); - return 0; + int fdIn, fdOut; + long fileSize, totalSize; + struct stat statBuf; + fdIn = open(InputFile, O_RDONLY); + if (fdIn == -1) + { + fprintf(stderr, "%s: Cannot open %s, %s\n", ProgramName, paramInputFile, + strerror(errno)); + return 1; + } + if (fstat(fdIn, &statBuf)) + { + fprintf(stderr, "%s: Cannot stat %s, %s\n", ProgramName, paramInputFile, + strerror(errno)); + close(fdIn); + return 1; + } + if (S_ISDIR(statBuf.st_mode)) + { + close(fdIn); + fprintf(stderr, "%s: %s: omitting directory\n", ProgramName, paramInputFile); + return 0; /* At this point, don't consider this a fatal error */ + } + fdOut = open(OutputFile, O_CREAT | O_TRUNC | O_WRONLY, statBuf.st_mode); + if (fdOut == -1) + { + fprintf(stderr, "%s: Cannot create %s, %s\n", ProgramName, paramOutputFile, + strerror(errno)); + close(fdIn); + return 1; + } + fileSize = lseek(fdIn, 0, SEEK_END); + if (fileSize < 0) + { + fprintf(stderr, "%s: lseek error on %s, %s\n", ProgramName, paramInputFile, + strerror(errno)); + close(fdOut); + close(fdIn); + return 1; + } + lseek(fdIn, 0, SEEK_SET); + if (optVerbose) + { + printf("Normal copy: %s -> %s 0%%", paramInputFile, paramOutputFile); + fflush(stdout); + } + totalSize = fileSize; + while (fileSize) + { + int currentMove; + int writeAmt; + currentMove = (fileSize > BufferSize) ? BufferSize : fileSize; + if (read(fdIn, Buffer, currentMove) != currentMove) + { + fprintf(stderr, "%s: Error reading %s, %s\n", ProgramName, paramInputFile, + strerror(errno)); + close(fdIn); + close(fdOut); + return 1; + } + writeAmt = write(fdOut, Buffer, currentMove); + if (writeAmt < 0) + { + fprintf(stderr, "%s: Error writing %s, %s\n", ProgramName, paramOutputFile, + strerror(errno)); + close(fdIn); + close(fdOut); + return 1; + } else if (writeAmt == 0) + { + fprintf(stderr, "%s: Out of space on destination device writing %s\n", + ProgramName, OutputFile); + close(fdIn); + close(fdOut); + return 1; + } + fileSize -= currentMove; + if (optVerbose) + { + printf("\rNormal copy: %s -> %s %ld%%", paramInputFile, paramOutputFile, (100 - (fileSize * 100 / totalSize))); + fflush(stdout); + } + } + close(fdOut); + close(fdIn); + if (optVerbose) + printf("\n"); + return 0; } /**************************************************************************** * Converts a string to upper case. * Netware file names need to be all upper case. */ -char *upString(char *str) +char * +upString(char *str) { - char *alias = str; - while (*alias) { - *alias = toupper(*alias); - ++alias; - } - return str; + char *alias = str; + while (*alias) + { + *alias = toupper(*alias); + ++alias; + } + return str; } /**************************************************************************** * Locates the first occurrance of a single character in the input string. * returns -1 if the character is not found. */ -int stringPosition(const char *str,char token) +int +stringPosition(const char *str, char token) { - const char *alias = str; - while (*alias) { - if (*alias == token) return alias - str; - alias++; - } - return -1; + const char *alias = str; + while (*alias) + { + if (*alias == token) + return alias - str; + alias++; + } + return -1; } /**************************************************************************** @@ -388,221 +437,238 @@ int stringPosition(const char *str,char token) * This will mangle the input "FileString", leaving just the file name * component in it when it is finished. */ -int getDirHandle(struct ncp_conn *conn, char *FileString, __u8 *NewDirHandle) +int +getDirHandle(struct ncp_conn *conn, char *FileString, __u8 * NewDirHandle) { - struct nw_info_struct info1,info2; - int currentLevel = 0; - int k; - struct nw_info_struct *parentInfo = NULL; - struct nw_info_struct *currentInfo = NULL; + struct nw_info_struct info1, info2; + int currentLevel = 0; + int k; + struct nw_info_struct *parentInfo = NULL; + struct nw_info_struct *currentInfo = NULL; - while ( (k = stringPosition(FileString,'/')) >= 0) { - FileString[k] = 0; - if (!currentLevel) { - parentInfo = NULL; - currentInfo = &info1; - } else if (currentLevel % 2) { - parentInfo = &info1; - currentInfo = &info2; - } else { - parentInfo = &info2; - currentInfo = &info1; - } - if (ncp_do_lookup(conn, parentInfo, FileString, - currentInfo) != 0) { - fprintf(stderr,"%s: Ncp lookup failed on directory %s--%s\n", - ProgramName,FileString,strerror(errno)); - return 1; - } - ++currentLevel; - memmove(FileString,FileString+k+1,strlen(FileString+k+1)+1); - } - - if (ncp_alloc_short_dir_handle(conn, currentInfo, NCP_ALLOC_TEMPORARY, - NewDirHandle) != 0) { - fprintf(stderr,"%s: Ncp alloc dir handle failed--%s\n", - ProgramName,strerror(errno)); - return 1; - } - return 0; + while ((k = stringPosition(FileString, '/')) >= 0) + { + FileString[k] = 0; + if (!currentLevel) + { + parentInfo = NULL; + currentInfo = &info1; + } else if (currentLevel % 2) + { + parentInfo = &info1; + currentInfo = &info2; + } else + { + parentInfo = &info2; + currentInfo = &info1; + } + if (ncp_do_lookup(conn, parentInfo, FileString, + currentInfo) != 0) + { + fprintf(stderr, "%s: Ncp lookup failed on directory %s--%s\n", + ProgramName, FileString, strerror(errno)); + return 1; + } + ++currentLevel; + memmove(FileString, FileString + k + 1, strlen(FileString + k + 1) + 1); + } + + if (ncp_alloc_short_dir_handle(conn, currentInfo, NCP_ALLOC_TEMPORARY, + NewDirHandle) != 0) + { + fprintf(stderr, "%s: Ncp alloc dir handle failed--%s\n", + ProgramName, strerror(errno)); + return 1; + } + return 0; } /**************************************************************************** * Interfaces with the ncplib to do the netware copy of the file. */ -int netwareCopyFile(int ncpMountIndex, const char *sourcefile, - const char *destfile, - const char *paramInputFile, - const char *paramOutputFile) +int +netwareCopyFile(int ncpMountIndex, const char *sourcefile, + const char *destfile, + const char *paramInputFile, + const char *paramOutputFile) { - __u8 source_dir_handle; - __u8 dest_dir_handle; - struct ncp_file_info source_file; - struct ncp_file_info dest_file; - __u32 amountCopied; - __u32 amtLeft; - __u32 totalSize; - __u32 sourceOff; - __u32 thisMove; - int stroffset; - int retValue; - char *sourceDup; - char *destDup; - struct ncp_conn *sourceconn; - int retryCount; - long err = 0; + __u8 source_dir_handle; + __u8 dest_dir_handle; + struct ncp_file_info source_file; + struct ncp_file_info dest_file; + __u32 amountCopied; + __u32 amtLeft; + __u32 totalSize; + __u32 sourceOff; + __u32 thisMove; + int stroffset; + int retValue; + char *sourceDup; + char *destDup; + struct ncp_conn *sourceconn; + int retryCount; + long err = 0; - /* Establish a connection to a Netware mount point if - one is not already established. */ - if (!NcpMountTable[ncpMountIndex].conn) { - NcpMountTable[ncpMountIndex].conn = - ncp_open_mount(NcpMountTable[ncpMountIndex].mountDir,&err); - if (err) { - com_err(ProgramName,err,"opening ncp connection on mount point %s", - NcpMountTable[ncpMountIndex].mountDir); - return 2; - } - } - sourceconn = NcpMountTable[ncpMountIndex].conn; - - /* Duplicate and upper case the file names so we do not trample - on the input strings */ - stroffset = strlen(NcpMountTable[ncpMountIndex].mountDir) + 1; - sourceDup = duplicateStr(sourcefile+stroffset); - destDup = duplicateStr(destfile+stroffset); - if (!sourceDup || !destDup) { - fprintf(stderr,"%s: Malloc failed duplicating file names\n", - ProgramName); - return 2; - } + /* Establish a connection to a Netware mount point if + one is not already established. */ + if (!NcpMountTable[ncpMountIndex].conn) + { + NcpMountTable[ncpMountIndex].conn = + ncp_open_mount(NcpMountTable[ncpMountIndex].mountDir, &err); + if (err) + { + com_err(ProgramName, err, "opening ncp connection on mount point %s", + NcpMountTable[ncpMountIndex].mountDir); + return 2; + } + } + sourceconn = NcpMountTable[ncpMountIndex].conn; - upString(sourceDup); - upString(destDup); + /* Duplicate and upper case the file names so we do not trample + on the input strings */ + stroffset = strlen(NcpMountTable[ncpMountIndex].mountDir) + 1; + sourceDup = duplicateStr(sourcefile + stroffset); + destDup = duplicateStr(destfile + stroffset); + if (!sourceDup || !destDup) + { + fprintf(stderr, "%s: Malloc failed duplicating file names\n", + ProgramName); + return 2; + } + upString(sourceDup); + upString(destDup); - /* Get Handles to the input and output directories */ - if (getDirHandle(sourceconn,sourceDup,&source_dir_handle) || - getDirHandle(sourceconn,destDup,&dest_dir_handle)) { - free(sourceDup); - free(destDup); - return 1; - } + /* Get Handles to the input and output directories */ + if (getDirHandle(sourceconn, sourceDup, &source_dir_handle) || + getDirHandle(sourceconn, destDup, &dest_dir_handle)) + { + free(sourceDup); + free(destDup); + return 1; + } + /* Open the input and output files. */ + if (ncp_open_file(sourceconn, source_dir_handle, sourceDup, 0, AR_READ, + &source_file) != 0) + { + fprintf(stderr, "%s: Cannot open %s--%s\n", + ProgramName, paramInputFile, strerror(errno)); + free(sourceDup); + free(destDup); + return 1; + } + if (ncp_create_file(sourceconn, dest_dir_handle, destDup, + source_file.file_attributes, &dest_file) != 0) + { + fprintf(stderr, "%s: Cannot create %s--%s\n", ProgramName, paramOutputFile, + strerror(errno)); + ncp_close_file(sourceconn, source_file.file_id); + free(sourceDup); + free(destDup); + return 1; + } + /* Set globals in case a signal happens while copying */ + CurrentConn = sourceconn; + CurrentFile = &dest_file; + OutputOpen = 1; - /* Open the input and output files. */ - if (ncp_open_file(sourceconn, source_dir_handle, sourceDup,0,AR_READ, - &source_file) != 0) { - fprintf(stderr,"%s: Cannot open %s--%s\n", - ProgramName,paramInputFile,strerror(errno)); - free(sourceDup); - free(destDup); - return 1; - } + free(sourceDup); + free(destDup); - if (ncp_create_file(sourceconn, dest_dir_handle, destDup, - source_file.file_attributes, &dest_file) != 0) { - fprintf(stderr,"%s: Cannot create %s--%s\n",ProgramName, paramOutputFile, - strerror(errno)); - ncp_close_file(sourceconn,source_file.file_id); - free(sourceDup); - free(destDup); - return 1; - } - /* Set globals in case a signal happens while copying */ - CurrentConn = sourceconn; - CurrentFile = &dest_file; - OutputOpen = 1; + retValue = 0; + if (optVerbose) + { + printf("NetWare copy: %s -> %s 0%%", paramInputFile, paramOutputFile); + fflush(stdout); + } + /* The main copy loop. */ - free(sourceDup); - free(destDup); + amtLeft = totalSize = source_file.file_length; + sourceOff = 0; + retryCount = 0; - retValue = 0; - if (optVerbose) { - printf("NetWare copy: %s -> %s 0%%",paramInputFile,paramOutputFile); - fflush(stdout); - } - - /* The main copy loop. */ - - amtLeft = totalSize = source_file.file_length; - sourceOff = 0; - retryCount = 0; - - while (amtLeft && retryCount < MaxNcopyRetries) { - int ncopyRetValue; - if (amtLeft > CopyBlockSize) - thisMove = CopyBlockSize; - else - thisMove = amtLeft; - /* If we are being nice and we've copied enough blocks, go to sleep */ - if (optNice) { - if (BlocksCopied == optNiceFactor) { - sleep(NiceSleepTime); - BlocksCopied=0; - } else - ++BlocksCopied; - } - ncopyRetValue = ncp_copy_file(sourceconn, source_file.file_id, - dest_file.file_id, sourceOff,sourceOff, - thisMove,&amountCopied); - if (ncopyRetValue != 0) { - /* In my testing this only happens when you run out of space - on the server. - Netware seems to wait a bit before reporting space recently - free'd. I will just wait a bit before bombin */ - sleep(1); /* Sleep for a second and try again */ - retryCount++; - amountCopied = thisMove = 0; - } - if (amountCopied != thisMove) { - fprintf(stderr,"%s: Warning, amountCopied (%u) != thisMove (%u)\n", - ProgramName,(unsigned int)amountCopied,(unsigned int)thisMove); - } + while (amtLeft && retryCount < MaxNcopyRetries) + { + int ncopyRetValue; + if (amtLeft > CopyBlockSize) + thisMove = CopyBlockSize; + else + thisMove = amtLeft; + /* If we are being nice and we've copied enough blocks, go to sleep */ + if (optNice) + { + if (BlocksCopied == optNiceFactor) + { + sleep(NiceSleepTime); + BlocksCopied = 0; + } else + ++BlocksCopied; + } + ncopyRetValue = ncp_copy_file(sourceconn, source_file.file_id, + dest_file.file_id, sourceOff, sourceOff, + thisMove, &amountCopied); + if (ncopyRetValue != 0) + { + /* In my testing this only happens when you run out of space + on the server. + Netware seems to wait a bit before reporting space recently + free'd. I will just wait a bit before bombin */ + sleep(1); /* Sleep for a second and try again */ + retryCount++; + amountCopied = thisMove = 0; + } + if (amountCopied != thisMove) + { + fprintf(stderr, "%s: Warning, amountCopied (%u) != thisMove (%u)\n", + ProgramName, (unsigned int) amountCopied, (unsigned int) thisMove); + } #ifdef NCOPY_DEBUG - fprintf(stderr,"Copied %u (actual %u)\n",(unsigned int)thisMove, - (unsigned int)amountCopied); + fprintf(stderr, "Copied %u (actual %u)\n", (unsigned int) thisMove, + (unsigned int) amountCopied); #endif - amtLeft -= amountCopied; - sourceOff += amountCopied; - if (optVerbose) { - printf("\rNetWare copy: %s -> %s %ld%%",paramInputFile,paramOutputFile, - (100 - (long)((float)amtLeft /(float)totalSize * 100.0))); - if (retryCount) - printf(" %d retries",retryCount); - fflush(stdout); - } - } - if (retryCount >= MaxNcopyRetries) - retValue = 1; - if (optVerbose) - printf("\n"); - if (ncp_close_file(sourceconn,dest_file.file_id) != 0) { - fprintf(stderr,"%s: Close failed for %s\n",ProgramName,paramOutputFile); - retValue = 1; - } + amtLeft -= amountCopied; + sourceOff += amountCopied; + if (optVerbose) + { + printf("\rNetWare copy: %s -> %s %ld%%", paramInputFile, paramOutputFile, + (100 - (long) ((float) amtLeft / (float) totalSize * 100.0))); + if (retryCount) + printf(" %d retries", retryCount); + fflush(stdout); + } + } + if (retryCount >= MaxNcopyRetries) + retValue = 1; + if (optVerbose) + printf("\n"); + if (ncp_close_file(sourceconn, dest_file.file_id) != 0) + { + fprintf(stderr, "%s: Close failed for %s\n", ProgramName, paramOutputFile); + retValue = 1; + } + /* Clear signal handling globals */ + OutputOpen = 0; + CurrentConn = NULL; + CurrentFile = NULL; - /* Clear signal handling globals */ - OutputOpen = 0; - CurrentConn = NULL; - CurrentFile = NULL; - - if (ncp_close_file(sourceconn,source_file.file_id) != 0) { - fprintf(stderr,"%s: Close failed for %s\n",ProgramName,paramInputFile); - retValue = 1; - } - - if (ncp_dealloc_dir_handle(sourceconn, dest_dir_handle) != 0) - { - fprintf(stderr,"%s: Dealloc dir handle error for %s\n",ProgramName, - paramOutputFile); - retValue = 1; - } - if (ncp_dealloc_dir_handle(sourceconn, source_dir_handle) != 0) - { - fprintf(stderr,"%s: Dealloc dir handle error for %s\n",ProgramName, - paramInputFile); - retValue = 1; - } - return retValue; + if (ncp_close_file(sourceconn, source_file.file_id) != 0) + { + fprintf(stderr, "%s: Close failed for %s\n", ProgramName, paramInputFile); + retValue = 1; + } + if (ncp_dealloc_dir_handle(sourceconn, dest_dir_handle) != 0) + { + fprintf(stderr, "%s: Dealloc dir handle error for %s\n", ProgramName, + paramOutputFile); + retValue = 1; + } + if (ncp_dealloc_dir_handle(sourceconn, source_dir_handle) != 0) + { + fprintf(stderr, "%s: Dealloc dir handle error for %s\n", ProgramName, + paramInputFile); + retValue = 1; + } + return retValue; } @@ -610,31 +676,32 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile, * Decides whether to use the traditional file copy or the netware remote * file copy. */ -int copyFiles(const char *realsource, const char *realdestination, - const char *paraminputfile, const char *paramoutputfile) +int +copyFiles(const char *realsource, const char *realdestination, + const char *paraminputfile, const char *paramoutputfile) { - int oldUMask; - char fileBuffer[24000]; - int retVal = 0; - int ncpMountIndex = ncpIndex(realsource,realdestination); + int oldUMask; + char fileBuffer[24000]; + int retVal = 0; + int ncpMountIndex = ncpIndex(realsource, realdestination); #ifdef NCOPY_DEBUG - printf("Real Source '%s'\n" - "Real Dest '%s'\n" - "Param Src '%s'\n" - "Param Dest '%s'\n",realsource,realdestination,paraminputfile, - paramoutputfile); + printf("Real Source '%s'\n" + "Real Dest '%s'\n" + "Param Src '%s'\n" + "Param Dest '%s'\n", realsource, realdestination, paraminputfile, + paramoutputfile); #endif - oldUMask = umask(0); - if (ncpMountIndex < 0) - retVal = normalFileCopy(realsource,realdestination,fileBuffer, - sizeof(fileBuffer), - paraminputfile,paramoutputfile); - else - retVal = netwareCopyFile(ncpMountIndex,realsource,realdestination, - paraminputfile,paramoutputfile); - umask(oldUMask); - return retVal; + oldUMask = umask(0); + if (ncpMountIndex < 0) + retVal = normalFileCopy(realsource, realdestination, fileBuffer, + sizeof(fileBuffer), + paraminputfile, paramoutputfile); + else + retVal = netwareCopyFile(ncpMountIndex, realsource, realdestination, + paraminputfile, paramoutputfile); + umask(oldUMask); + return retVal; } @@ -655,42 +722,47 @@ int copyFiles(const char *realsource, const char *realdestination, * Is it failure if destination fails? * Do we Stay in the loop? */ -static int copyRealPaths(const char *source, const char *destination) +static int +copyRealPaths(const char *source, const char *destination) { - char realsource[MAXPATHLEN*2]; - char realdestination[MAXPATHLEN*2]; - char dirPart[MAXPATHLEN+1]; - char filePart[MAXPATHLEN+1]; - const char *p; + char realsource[MAXPATHLEN * 2]; + char realdestination[MAXPATHLEN * 2]; + char dirPart[MAXPATHLEN + 1]; + char filePart[MAXPATHLEN + 1]; + const char *p; - if(realpath(source, realsource) == 0) { /* the source must at least exist */ - fprintf(stderr,"%s: %s: %s\n", - ProgramName, source, strerror(errno)); - return 1; /* indicate a "source" problem */ - } - if(realpath(destination, realdestination) == 0) {/* dest file missing? OK */ - strncpy(dirPart, destination, MAXPATHLEN); /* but "dirpart" must work */ - dirPart[MAXPATHLEN] = 0; - p=myBaseName(dirPart); - strcpy(filePart, p); - dirPart[p - dirPart] = 0; /* isolates "directory" part from "file part" */ - if(realpath(dirPart, realdestination) == 0) { - fprintf(stderr,"%s: %s: %s\n", - ProgramName, dirPart, strerror(errno)); - return 2; /* indicate a "destination" problem */ - } - if(*realdestination != '/' || *(realdestination+1)) strcat(realdestination, "/"); - strcat(realdestination, filePart); - } - /* becomes prog exit code */ + if (realpath(source, realsource) == 0) + { /* the source must at least exist */ + fprintf(stderr, "%s: %s: %s\n", + ProgramName, source, strerror(errno)); + return 1; /* indicate a "source" problem */ + } + if (realpath(destination, realdestination) == 0) + { /* dest file missing? OK */ + strncpy(dirPart, destination, MAXPATHLEN); /* but "dirpart" must work */ + dirPart[MAXPATHLEN] = 0; + p = myBaseName(dirPart); + strcpy(filePart, p); + dirPart[p - dirPart] = 0; /* isolates "directory" part from "file part" */ + if (realpath(dirPart, realdestination) == 0) + { + fprintf(stderr, "%s: %s: %s\n", + ProgramName, dirPart, strerror(errno)); + return 2; /* indicate a "destination" problem */ + } + if (*realdestination != '/' || *(realdestination + 1)) + strcat(realdestination, "/"); + strcat(realdestination, filePart); + } + /* becomes prog exit code */ - /* Test Cases: (Where file/dir may or may not exist) - * "", file, file/, dir, dir/ - * /, //, /dir, /dir/, /file, /file/, - * /tmp/file, /tmp/file/, tmp/file, tmp/file/, - * /tmp/dir, /tmp/dir/, tmp/dir, tmp/dir/ - */ - return copyFiles(realsource, realdestination,source,destination); + /* Test Cases: (Where file/dir may or may not exist) + * "", file, file/, dir, dir/ + * /, //, /dir, /dir/, /file, /file/, + * /tmp/file, /tmp/file/, tmp/file, tmp/file/, + * /tmp/dir, /tmp/dir/, tmp/dir, tmp/dir/ + */ + return copyFiles(realsource, realdestination, source, destination); } /**************************************************************************** @@ -698,152 +770,177 @@ static int copyRealPaths(const char *source, const char *destination) * if argc > 2 last parameter is a directory * by validateFileArgs() */ -static int handleFileArgs(int argc, char * const argv[]) +static int +handleFileArgs(int argc, char *const argv[]) { - int loop; - const char *destination; - int copyStatus; - int returnCode=0; /* default program exit code */ - const char *baseNamePtr; - char destinationfile[MAXPATHLEN*2]; + int loop; + const char *destination; + int copyStatus; + int returnCode = 0; /* default program exit code */ + const char *baseNamePtr; + char destinationfile[MAXPATHLEN * 2]; - destination=argv[argc-1]; /* get LAST argument */ - for (loop = 0; loop < (argc-1); loop++) { /* all file arguments, but last */ - strncpy(destinationfile, destination, MAXPATHLEN); - destinationfile[MAXPATHLEN]=0; - if((argc > 2) || (!notDir(argv[argc-1]))) { /* destination is a dir */ - if(*destinationfile != '/' || *(destinationfile+1)) strcat(destinationfile,"/"); - baseNamePtr=myBaseName(argv[loop]); /* get the file name */ - strcat(destinationfile,baseNamePtr); /* add it on end of directory */ - } - copyStatus=copyRealPaths(argv[loop], destinationfile); /* do the copy */ - if(copyStatus > 1) return copyStatus; /* fatal failure? bye */ - if(copyStatus == 1) returnCode=1; /* a partial failure? we can continue */ - } - return returnCode; /* return what will be the program exit code */ + destination = argv[argc - 1]; /* get LAST argument */ + for (loop = 0; loop < (argc - 1); loop++) + { /* all file arguments, but last */ + strncpy(destinationfile, destination, MAXPATHLEN); + destinationfile[MAXPATHLEN] = 0; + if ((argc > 2) || (!notDir(argv[argc - 1]))) + { /* destination is a dir */ + if (*destinationfile != '/' || *(destinationfile + 1)) + strcat(destinationfile, "/"); + baseNamePtr = myBaseName(argv[loop]); /* get the file name */ + strcat(destinationfile, baseNamePtr); /* add it on end of directory */ + } + copyStatus = copyRealPaths(argv[loop], destinationfile); /* do the copy */ + if (copyStatus > 1) + return copyStatus; /* fatal failure? bye */ + if (copyStatus == 1) + returnCode = 1; /* a partial failure? we can continue */ + } + return returnCode; /* return what will be the program exit code */ } /**************************************************************************** * */ -static void handleSignals(int sigNumber) +static void +handleSignals(int sigNumber) { - /* Ignore Signal Handling while cleaning up */ + /* Ignore Signal Handling while cleaning up */ - /* SIGHUP */ - sHangupSig.sa_handler=SIG_IGN; - if(sigaction(SIGHUP, &sHangupSig, NULL) == -1) { - fprintf(stderr,"%s: Reset to ignore SIGHUP signal failed: %s", - ProgramName, strerror(errno)); - } - /* SIGINT */ - sInterruptSig.sa_handler=SIG_IGN; - if(sigaction(SIGINT, &sInterruptSig, NULL) == -1) { - fprintf(stderr,"%s: Reset to ignore SIGINT signal failed: %s", - ProgramName, strerror(errno)); - } - /* SIGQUIT */ - sQuitSig.sa_handler=SIG_IGN; - if(sigaction(SIGQUIT, &sQuitSig, NULL) == -1) { - fprintf(stderr,"%s: Reset to ignore SIGQUIT signal failed: %s", - ProgramName, strerror(errno)); - } - /* SIGTERM */ - sTermSig.sa_handler=SIG_IGN; - if(sigaction(SIGTERM, &sTermSig, NULL) == -1) { - fprintf(stderr,"%s: Reset to ignore SIGTERM signal failed: %s", - ProgramName, strerror(errno)); - } - - /* If we don't close the ncp output file, we have to ncpumount and - ncpmount before we can get rid of it. */ - if (OutputOpen) { - /* Issue a warning if we cannot close the file */ - /* If an error occurs we probably have to umount/mount to - remove the file */ - if (ncp_close_file(CurrentConn,CurrentFile->file_id) != 0) { - fprintf(stderr,"%s: unclean close of output file",ProgramName); - } - OutputOpen = 0; - } - - exit(128 + sigNumber); + /* SIGHUP */ + sHangupSig.sa_handler = SIG_IGN; + if (sigaction(SIGHUP, &sHangupSig, NULL) == -1) + { + fprintf(stderr, "%s: Reset to ignore SIGHUP signal failed: %s", + ProgramName, strerror(errno)); + } + /* SIGINT */ + sInterruptSig.sa_handler = SIG_IGN; + if (sigaction(SIGINT, &sInterruptSig, NULL) == -1) + { + fprintf(stderr, "%s: Reset to ignore SIGINT signal failed: %s", + ProgramName, strerror(errno)); + } + /* SIGQUIT */ + sQuitSig.sa_handler = SIG_IGN; + if (sigaction(SIGQUIT, &sQuitSig, NULL) == -1) + { + fprintf(stderr, "%s: Reset to ignore SIGQUIT signal failed: %s", + ProgramName, strerror(errno)); + } + /* SIGTERM */ + sTermSig.sa_handler = SIG_IGN; + if (sigaction(SIGTERM, &sTermSig, NULL) == -1) + { + fprintf(stderr, "%s: Reset to ignore SIGTERM signal failed: %s", + ProgramName, strerror(errno)); + } + /* If we don't close the ncp output file, we have to ncpumount and + ncpmount before we can get rid of it. */ + if (OutputOpen) + { + /* Issue a warning if we cannot close the file */ + /* If an error occurs we probably have to umount/mount to + remove the file */ + if (ncp_close_file(CurrentConn, CurrentFile->file_id) != 0) + { + fprintf(stderr, "%s: unclean close of output file", ProgramName); + } + OutputOpen = 0; + } + exit(128 + sigNumber); } /**************************************************************************** * We'll trap Hangup, Interrupt, Quit or Terminate */ -static int trapSignals() +static int +trapSignals() { - if(sigaction(SIGHUP, NULL, &sHangupSig)) { /* init structure fields */ - fprintf(stderr,"%s: Get HANGUP signal action failed: %s", - ProgramName, strerror(errno)); - return 1; - } - sHangupSig.sa_handler = handleSignals; - if(sigaction(SIGHUP, &sHangupSig, NULL) == -1) { - fprintf(stderr,"%s: Reset HANGUP signal action failed: %s", - ProgramName, strerror(errno)); - return 1; - } - if(sigaction(SIGINT, NULL, &sInterruptSig)) { /* init structure fields */ - fprintf(stderr,"%s: Get INTERRUPT signal action failed: %s", - ProgramName, strerror(errno)); - return 1; - } - sInterruptSig.sa_handler = handleSignals; - if(sigaction(SIGINT, &sInterruptSig, NULL) == -1) { - fprintf(stderr,"%s: Reset INTERRUPT signal action failed: %s", - ProgramName, strerror(errno)); - return 1; - } - if(sigaction(SIGQUIT, NULL, &sQuitSig)) { /* init structure fields */ - fprintf(stderr,"%s: Get QUIT signal action failed: %s", - ProgramName, strerror(errno)); - return 1; - } - sQuitSig.sa_handler = handleSignals; - if(sigaction(SIGQUIT, &sQuitSig, NULL) == -1) { - fprintf(stderr,"%s: Reset QUIT signal action failed: %s", - ProgramName, strerror(errno)); - return 1; - } - if(sigaction(SIGTERM, NULL, &sTermSig)) { /* init structure fields */ - fprintf(stderr,"%s: Get TERMINATE signal action failed: %s", - ProgramName, strerror(errno)); - return 1; - } - sTermSig.sa_handler = handleSignals; - if(sigaction(SIGTERM, &sTermSig, NULL) == -1) { - fprintf(stderr,"%s: Reset TERMINATE signal action failed: %s", - ProgramName, strerror(errno)); - return 1; - } - return 0; + if (sigaction(SIGHUP, NULL, &sHangupSig)) + { /* init structure fields */ + fprintf(stderr, "%s: Get HANGUP signal action failed: %s", + ProgramName, strerror(errno)); + return 1; + } + sHangupSig.sa_handler = handleSignals; + if (sigaction(SIGHUP, &sHangupSig, NULL) == -1) + { + fprintf(stderr, "%s: Reset HANGUP signal action failed: %s", + ProgramName, strerror(errno)); + return 1; + } + if (sigaction(SIGINT, NULL, &sInterruptSig)) + { /* init structure fields */ + fprintf(stderr, "%s: Get INTERRUPT signal action failed: %s", + ProgramName, strerror(errno)); + return 1; + } + sInterruptSig.sa_handler = handleSignals; + if (sigaction(SIGINT, &sInterruptSig, NULL) == -1) + { + fprintf(stderr, "%s: Reset INTERRUPT signal action failed: %s", + ProgramName, strerror(errno)); + return 1; + } + if (sigaction(SIGQUIT, NULL, &sQuitSig)) + { /* init structure fields */ + fprintf(stderr, "%s: Get QUIT signal action failed: %s", + ProgramName, strerror(errno)); + return 1; + } + sQuitSig.sa_handler = handleSignals; + if (sigaction(SIGQUIT, &sQuitSig, NULL) == -1) + { + fprintf(stderr, "%s: Reset QUIT signal action failed: %s", + ProgramName, strerror(errno)); + return 1; + } + if (sigaction(SIGTERM, NULL, &sTermSig)) + { /* init structure fields */ + fprintf(stderr, "%s: Get TERMINATE signal action failed: %s", + ProgramName, strerror(errno)); + return 1; + } + sTermSig.sa_handler = handleSignals; + if (sigaction(SIGTERM, &sTermSig, NULL) == -1) + { + fprintf(stderr, "%s: Reset TERMINATE signal action failed: %s", + ProgramName, strerror(errno)); + return 1; + } + return 0; } /**************************************************************************** * */ -int main(int argc, char * const argv[]) +int +main(int argc, char *const argv[]) { - int returnCode; - ProgramName=argv[0]; + int returnCode; + ProgramName = argv[0]; - if(handleOptions(argc, argv)) { /* bad option, missing option parameter */ - usage(); - return 1; - } - if(optVersion) { /* only option not requiring any arguments */ - printf("%s version %s\n", ProgramName, VersionStr); - return 0; - } - if(validateFileArgs(argc - optind, argv + optind)) { - usage(); - return 1; - } - if(trapSignals()) return 1; - loadMountTable(); - returnCode = handleFileArgs(argc - optind, argv + optind); - releaseMountTable(); - return returnCode; + if (handleOptions(argc, argv)) + { /* bad option, missing option parameter */ + usage(); + return 1; + } + if (optVersion) + { /* only option not requiring any arguments */ + printf("%s version %s\n", ProgramName, VersionStr); + return 0; + } + if (validateFileArgs(argc - optind, argv + optind)) + { + usage(); + return 1; + } + if (trapSignals()) + return 1; + loadMountTable(); + returnCode = handleFileArgs(argc - optind, argv + optind); + releaseMountTable(); + return returnCode; } diff --git a/util/ncptest.c b/util/ncptest.c index ba64762..4160303 100644 --- a/util/ncptest.c +++ b/util/ncptest.c @@ -19,7 +19,7 @@ #include #include #include -/* #include */ /* generates a warning here */ + /* #include *//* generates a warning here */ extern pid_t waitpid(pid_t, int *, int); #include #include @@ -41,7 +41,8 @@ extern pid_t waitpid(pid_t, int *, int); void test_connlist(struct ncp_conn *conn) { - __u8 conn_list[256] = {0,}; + __u8 conn_list[256] = + {0,}; int no; ncp_get_connlist(conn, NCP_BINDERY_USER, "SUPERVISOR", &no, @@ -52,7 +53,8 @@ test_connlist(struct ncp_conn *conn) void test_send(struct ncp_conn *conn) { - __u8 conn_list[256] = {0,}; + __u8 conn_list[256] = + {0,}; int no; if (ncp_get_connlist(conn, NCP_BINDERY_USER, "ME", &no, @@ -60,7 +62,6 @@ test_send(struct ncp_conn *conn) { no = 0; } - if (no > 0) { ncp_send_broadcast(conn, no, conn_list, "Hallo"); @@ -85,21 +86,18 @@ test_create(struct ncp_conn *conn) printf("lookup public error\n"); return; } - if (ncp_alloc_short_dir_handle(conn, &me, NCP_ALLOC_TEMPORARY, &dir_handle) != 0) { printf("alloc_dir_handle error\n"); return; } - if (ncp_create_file(conn, dir_handle, "BLUB.TXT", 0, &new_file) != 0) { printf("create error\n"); return; } - if (ncp_dealloc_dir_handle(conn, dir_handle) != 0) { printf("dealloc error\n"); @@ -114,15 +112,15 @@ test_change(struct ncp_conn *conn) unsigned char ncp_key[8]; struct ncp_bindery_object user; - if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0) { + if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0) + { return result; } - if ((result = ncp_get_bindery_object_id(conn, 1, - "ME", &user)) != 0) { + "ME", &user)) != 0) + { return result; } - if ((result = ncp_change_login_passwd(conn, &user, ncp_key, "MEE", "ME")) != 0) { @@ -149,16 +147,14 @@ test_readdir(struct ncp_conn *conn) 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; + 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, @@ -168,7 +164,7 @@ test_readdir(struct ncp_conn *conn) &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, @@ -177,7 +173,7 @@ test_readdir(struct ncp_conn *conn) &nfs) == 0) { printf("os2 name: %s\n", nfs.entryName); - } + } } } @@ -199,7 +195,6 @@ test_rights(struct ncp_conn *conn) printf("lookup me error\n"); return; } - if (ncp_get_eff_directory_rights(conn, 0, 0, 0x8006, sys.volNumber, sys.DosDirNum, NULL, &rights) != 0) @@ -231,7 +226,6 @@ main(int argc, char *argv[]) com_err(argv[0], err, "in ncp_initialize"); return 1; } - test_rights(conn); ncp_close(conn); return 0; diff --git a/util/nprint.c b/util/nprint.c index a4ab053..b8fb9ad 100644 --- a/util/nprint.c +++ b/util/nprint.c @@ -19,7 +19,7 @@ static char *progname; static void -usage(void); + usage(void); static void help(void); void @@ -46,25 +46,25 @@ main(int argc, char *argv[]) progname = argv[0]; - memzero(j); memzero(pj); memzero(q); + memzero(j); + memzero(pj); + memzero(q); - if ( (argc == 2) + if ((argc == 2) && (strcmp(argv[1], "-h") == 0)) { help(); exit(0); } - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { com_err(argv[0], err, "when initializing connection"); exit(1); } - /* * Fill in default values for print job */ - j.j.TargetServerID = 0xffffffff; /* any server */ + j.j.TargetServerID = 0xffffffff; /* any server */ /* at once */ memset(&(j.j.TargetExecTime), 0xff, sizeof(j.j.TargetExecTime)); j.j.JobType = htons(0); @@ -78,9 +78,10 @@ main(int argc, char *argv[]) pj.Rows = htons(80); strcpy(pj.FnameHeader, "stdin"); - while ((opt = getopt(argc, argv, "h?q: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) { + switch (opt) + { case 'h': case '?': help(); @@ -93,8 +94,7 @@ main(int argc, char *argv[]) { strncpy(pj.Path, optarg, sizeof(pj.Path)); - } - else + } else { strcpy(pj.Path, optarg); } @@ -106,8 +106,7 @@ main(int argc, char *argv[]) { strncpy(pj.BannerName, optarg, sizeof(pj.BannerName)); - } - else + } else { strcpy(pj.BannerName, optarg); } @@ -119,8 +118,7 @@ main(int argc, char *argv[]) { strncpy(pj.FnameBanner, optarg, sizeof(pj.FnameBanner)); - } - else + } else { strcpy(pj.FnameBanner, optarg); } @@ -205,13 +203,12 @@ main(int argc, char *argv[]) { strncpy(j.j.JobTextDescription, optarg, sizeof(j.j.JobTextDescription)); - } - else + } else { strcpy(j.j.JobTextDescription, optarg); } break; - + default: usage(); ncp_close(conn); @@ -219,20 +216,18 @@ main(int argc, char *argv[]) } } - if (optind != argc-1) + if (optind != argc - 1) { usage(); ncp_close(conn); exit(1); } - file_name = argv[optind]; if (strcmp(file_name, "-") == 0) { file = 0; /* stdin */ - } - else + } else { file = open(file_name, O_RDONLY, 0); if (file < 0) @@ -241,13 +236,11 @@ main(int argc, char *argv[]) ncp_close(conn); exit(1); } - if (strlen(file_name) >= sizeof(pj.FnameHeader)) { strncpy(pj.FnameHeader, file_name, sizeof(pj.FnameHeader)); - } - else + } else { strcpy(pj.FnameHeader, file_name); } @@ -258,8 +251,7 @@ main(int argc, char *argv[]) { strncpy(pj.FnameBanner, file_name, sizeof(pj.FnameBanner)); - } - else + } else { strcpy(pj.FnameBanner, file_name); } @@ -277,38 +269,35 @@ main(int argc, char *argv[]) ncp_close(conn); exit(1); } - if (ncp_create_queue_job_and_file(conn, q.object_id, &j) != 0) { printf("create error\n"); ncp_close(conn); exit(1); } - written = 0; do { - read_this_time = read(file, buf, sizeof(buf)); + read_this_time = read(file, buf, sizeof(buf)); if (read_this_time < 0) { break; } - if (ncp_write(conn, j.file_handle, written, read_this_time, buf) < read_this_time) { break; } - written += read_this_time; - } while (read_this_time > 0); + } + while (read_this_time > 0); close(file); - if (ncp_close_file_and_start_job(conn, q.object_id, &j) != 0) { + if (ncp_close_file_and_start_job(conn, q.object_id, &j) != 0) + { printf("close error\n"); } - ncp_close(conn); return; } @@ -322,25 +311,25 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options] file\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options] file\n", progname); + printf("\n" "-S server Server name to be used\n" - "-U username Username sent to server\n" - "-P password Use this password\n" - "-n Do not use any password\n" - "-C Don't convert password to uppercase\n" - "-q queue name Name of the printing queue to use\n" - "-d job desc Job description\n" - "-p path name Path name to appear on banner\n" - "-b bannername Banner name (up to 12 chars)\n" - "-f filename Filename to appear on banner\n" - "-l lines Number of lines per page\n" - "-r rows Number of rows per page\n" - "-t tab Number of spaces per tab\n" - "-T Print server tab expantion\n" - "-N Surpress print server form feeds\n" - "-F form # Form number to print on\n" - "-h print this help text\n" - "\n"); + "-U username Username sent to server\n" + "-P password Use this password\n" + "-n Do not use any password\n" + "-C Don't convert password to uppercase\n" + "-q queue name Name of the printing queue to use\n" + "-d job desc Job description\n" + "-p path name Path name to appear on banner\n" + "-b bannername Banner name (up to 12 chars)\n" + "-f filename Filename to appear on banner\n" + "-l lines Number of lines per page\n" + "-r rows Number of rows per page\n" + "-t tab Number of spaces per tab\n" + "-T Print server tab expantion\n" + "-N Surpress print server form feeds\n" + "-F form # Form number to print on\n" + "-h print this help text\n" + "\n"); } diff --git a/util/nsend.c b/util/nsend.c index 9a58fd2..da716b2 100644 --- a/util/nsend.c +++ b/util/nsend.c @@ -16,7 +16,8 @@ int main(int argc, char **argv) { struct ncp_conn *conn; - __u8 conn_list[256] = {0,}; + __u8 conn_list[256] = + {0,}; int no_conn; char *message = NULL; @@ -28,14 +29,12 @@ main(int argc, char **argv) com_err(argv[0], err, "when initializing"); exit(1); } - if (argc != 3) { fprintf(stderr, "usage: %s [options] user message\n", argv[0]); ncp_close(conn); exit(1); } - user = argv[1]; message = argv[2]; @@ -46,14 +45,12 @@ main(int argc, char **argv) ncp_close(conn); exit(1); } - if (no_conn == 0) { fprintf(stderr, "No connection found for %s\n", user); ncp_close(conn); exit(1); } - if ((err = ncp_send_broadcast(conn, no_conn, conn_list, message)) != 0) { com_err(argv[0], err, "in send_broadcast"); diff --git a/util/nwauth.c b/util/nwauth.c index a4946ea..c5f8167 100644 --- a/util/nwauth.c +++ b/util/nwauth.c @@ -23,18 +23,18 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options]\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options]\n", progname); + printf("\n" "-h Print this help text\n" "-S server Server name to be used\n" - "-U username Username sent to server\n" + "-U username Username sent to server\n" "-t type Object type (decimal value)\n" "\n"); } static void -swallow_error(const char * s, long x, const char *t, va_list arg) +swallow_error(const char *s, long x, const char *t, va_list arg) { return; } @@ -59,10 +59,10 @@ main(int argc, char *argv[]) { set_com_err_hook(swallow_error); } - while ((opt = getopt(argc, argv, "h?S:U:t:")) != EOF) { - switch(opt) { + switch (opt) + { case 'S': server = optarg; break; @@ -90,13 +90,11 @@ main(int argc, char *argv[]) com_err(argv[0], err, "when trying to find server"); exit(1); } - if (ncp_find_fileserver(spec->server, &err) == NULL) { com_err(argv[0], err, "when trying to find server"); exit(1); } - spec->login_type = object_type; memset(spec->password, 0, sizeof(spec->password)); @@ -109,8 +107,7 @@ main(int argc, char *argv[]) exit(1); } strcpy(spec->password, str); - } - else + } else { fgets(spec->password, sizeof(spec->password), stdin); } diff --git a/util/nwbocreate.c b/util/nwbocreate.c index 8f006b8..794c3ad 100644 --- a/util/nwbocreate.c +++ b/util/nwbocreate.c @@ -22,15 +22,15 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options]\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options]\n", progname); + printf("\n" "-h Print this help text\n" "-S server Server name to be used\n" - "-U username Username sent to server\n" - "-P password Use this password\n" - "-n Do not use any password\n" - "-C Don't convert password to uppercase\n" + "-U username Username sent to server\n" + "-P password Use this password\n" + "-n Do not use any password\n" + "-C Don't convert password to uppercase\n" "\n" "-o object_name Name of created object\n" "-t type Object type (decimal value)\n" @@ -63,8 +63,8 @@ parse_security(const char *security) return 4; } return -1; -} - +} + int main(int argc, char *argv[]) { @@ -76,7 +76,7 @@ main(int argc, char *argv[]) int read_sec = 1; /* logged read */ int write_sec = 3; /* supervisor write */ int result = 1; - + int opt; progname = argv[0]; @@ -86,10 +86,10 @@ main(int argc, char *argv[]) com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:r:w:")) != EOF) { - switch(opt) { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -137,25 +137,22 @@ main(int argc, char *argv[]) argv[0]); goto finished; } - if (object_name == NULL) { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; } - if (ncp_create_bindery_object(conn, object_type, object_name, (write_sec << 4) + read_sec, 0) != 0) { fprintf(stderr, "%s: Could not create the object\n", argv[0]); - } - else + } else { result = 0; } - finished: + finished: ncp_close(conn); return result; } diff --git a/util/nwbols.c b/util/nwbols.c index 7d54580..1ecdcca 100644 --- a/util/nwbols.c +++ b/util/nwbols.c @@ -25,15 +25,15 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options]\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options]\n", progname); + printf("\n" "-h Print this help text\n" "-S server Server name to be used\n" - "-U username Username sent to server\n" - "-P password Use this password\n" - "-n Do not use any password\n" - "-C Don't convert password to uppercase\n" + "-U username Username sent to server\n" + "-P password Use this password\n" + "-n Do not use any password\n" + "-C Don't convert password to uppercase\n" "\n" "-t type Object type to be listed (decimal)\n" "-o object Object pattern\n" @@ -63,10 +63,10 @@ main(int argc, char **argv) com_err(argv[0], err, "when initializing"); return 1; } - while ((opt = getopt(argc, argv, "h?vt:o:")) != EOF) { - switch(opt) { + switch (opt) + { case 'h': case '?': help(); @@ -91,7 +91,6 @@ main(int argc, char **argv) usage(); exit(1); } - for (p = pattern; *p != '\0'; p++) { *p = toupper(*p); @@ -106,17 +105,16 @@ main(int argc, char **argv) if (verbose != 0) { printf("%s %08X %04X %d %02X %d\n", - o.object_name, (unsigned int)o.object_id, - (unsigned int)o.object_type, + o.object_name, (unsigned int) o.object_id, + (unsigned int) o.object_type, o.object_flags, o.object_security, o.object_has_prop); - } - else + } else { printf("%s %08X %04X\n", - o.object_name, (unsigned int)o.object_id, - (unsigned int)o.object_type); - } + o.object_name, (unsigned int) o.object_id, + (unsigned int) o.object_type); + } } ncp_close(conn); diff --git a/util/nwboprops.c b/util/nwboprops.c index c60a9b5..790850a 100644 --- a/util/nwboprops.c +++ b/util/nwboprops.c @@ -22,15 +22,15 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options]\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options]\n", progname); + printf("\n" "-h Print this help text\n" "-S server Server name to be used\n" - "-U username Username sent to server\n" - "-P password Use this password\n" - "-n Do not use any password\n" - "-C Don't convert password to uppercase\n" + "-U username Username sent to server\n" + "-P password Use this password\n" + "-n Do not use any password\n" + "-C Don't convert password to uppercase\n" "\n" "-o object_name Name of object inspected\n" "-t type Object type (decimal value)\n" @@ -47,7 +47,7 @@ main(int argc, char *argv[]) long err; struct ncp_property_info info; - + int result = 1; int verbose = 0; int opt; @@ -59,10 +59,10 @@ main(int argc, char *argv[]) com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:v")) != EOF) { - switch(opt) { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -89,14 +89,12 @@ main(int argc, char *argv[]) argv[0]); goto finished; } - if (object_name == NULL) { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; } - info.search_instance = 0xffffffff; while (ncp_scan_property(conn, object_type, object_name, @@ -108,14 +106,13 @@ main(int argc, char *argv[]) info.property_name, info.property_flags, info.property_security, info.value_available_flag); - } - else + } else { printf("%s\n", info.property_name); } } - finished: + finished: ncp_close(conn); return result; } diff --git a/util/nwborm.c b/util/nwborm.c index 2da2fa0..f0dc321 100644 --- a/util/nwborm.c +++ b/util/nwborm.c @@ -22,15 +22,15 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options]\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options]\n", progname); + printf("\n" "-h Print this help text\n" "-S server Server name to be used\n" - "-U username Username sent to server\n" - "-P password Use this password\n" - "-n Do not use any password\n" - "-C Don't convert password to uppercase\n" + "-U username Username sent to server\n" + "-P password Use this password\n" + "-n Do not use any password\n" + "-C Don't convert password to uppercase\n" "\n" "-o object_name Name of object to be removed\n" "-t type Object type (decimal value)\n" @@ -46,7 +46,7 @@ main(int argc, char *argv[]) long err; int result = 1; - + int opt; progname = argv[0]; @@ -56,10 +56,10 @@ main(int argc, char *argv[]) com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:")) != EOF) { - switch(opt) { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -83,24 +83,21 @@ main(int argc, char *argv[]) argv[0]); goto finished; } - if (object_name == NULL) { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; } - if (ncp_delete_bindery_object(conn, object_type, object_name) != 0) { fprintf(stderr, "%s: Could not delete the object\n", argv[0]); - } - else + } else { result = 0; } - finished: + finished: ncp_close(conn); return result; } diff --git a/util/nwbpadd.c b/util/nwbpadd.c index 70d5ea7..77283fd 100644 --- a/util/nwbpadd.c +++ b/util/nwbpadd.c @@ -22,15 +22,15 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options] [values]\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options] [values]\n", progname); + printf("\n" "-h Print this help text\n" "-S server Server name to be used\n" - "-U username Username sent to server\n" - "-P password Use this password\n" - "-n Do not use any password\n" - "-C Don't convert password to uppercase\n" + "-U username Username sent to server\n" + "-P password Use this password\n" + "-n Do not use any password\n" + "-C Don't convert password to uppercase\n" "\n" "-o object_name Name of accessed object\n" "-t type Object type (decimal value)\n" @@ -66,10 +66,10 @@ main(int argc, char *argv[]) com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:p:v:")) != EOF) { - switch(opt) { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -106,28 +106,24 @@ main(int argc, char *argv[]) argv[0]); goto finished; } - if (object_name == NULL) { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; } - if (property_name == NULL) { fprintf(stderr, "%s: You must specify a property name\n", argv[0]); goto finished; } - - if (optind > argc-1) + if (optind > argc - 1) { fprintf(stderr, "%s: You must specify a property value\n", argv[0]); goto finished; } - value = argv[optind]; optind += 1; @@ -137,7 +133,6 @@ main(int argc, char *argv[]) fprintf(stderr, "%s: Could not find property\n", argv[0]); goto finished; } - if ((info.property_flags & 2) != 0) { /* Property is of type SET */ @@ -150,7 +145,6 @@ main(int argc, char *argv[]) progname, property_name); goto finished; } - if (ncp_get_bindery_object_name(conn, ntohl(strtol(value, NULL, 16)), &o) != 0) @@ -159,7 +153,6 @@ main(int argc, char *argv[]) progname, value); goto finished; } - if (ncp_add_object_to_set(conn, object_type, object_name, property_name, o.object_type, o.object_name) != 0) @@ -167,12 +160,11 @@ main(int argc, char *argv[]) fprintf(stderr, "%s: could not add object %s\n", progname, o.object_name); goto finished; - } - } - else + } + } else { /* Property is of type ITEM */ - char contents[255*128]; + char contents[255 * 128]; int segno = 1; int length; @@ -189,8 +181,7 @@ main(int argc, char *argv[]) goto finished; } strcpy(contents, value); - } - else + } else { /* value is the byte count */ int i; @@ -219,15 +210,15 @@ main(int argc, char *argv[]) for (segno = 1; segno <= 255; segno++) { struct nw_property segment; - int offset = (segno-1)*128; + int offset = (segno - 1) * 128; - if ( offset > length ) + if (offset > length) { /* everything written */ break; } memcpy(segment.value, &(contents[offset]), 128); - segment.more_flag = segno*128 < length; + segment.more_flag = segno * 128 < length; if (ncp_write_property_value(conn, object_type, object_name, property_name, @@ -241,7 +232,7 @@ main(int argc, char *argv[]) } result = 0; - finished: + finished: ncp_close(conn); return result; } diff --git a/util/nwbpcreate.c b/util/nwbpcreate.c index 740cd06..f7394da 100644 --- a/util/nwbpcreate.c +++ b/util/nwbpcreate.c @@ -22,15 +22,15 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options]\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options]\n", progname); + printf("\n" "-h Print this help text\n" "-S server Server name to be used\n" - "-U username Username sent to server\n" - "-P password Use this password\n" - "-n Do not use any password\n" - "-C Don't convert password to uppercase\n" + "-U username Username sent to server\n" + "-P password Use this password\n" + "-n Do not use any password\n" + "-C Don't convert password to uppercase\n" "\n" "-o object_name Name of object\n" "-t type Object type (decimal value)\n" @@ -65,8 +65,8 @@ parse_security(const char *security) return 4; } return -1; -} - +} + int main(int argc, char *argv[]) { @@ -80,7 +80,7 @@ main(int argc, char *argv[]) int read_sec = 1; /* logged read */ int write_sec = 3; /* supervisor write */ int result = 1; - + int opt; progname = argv[0]; @@ -90,10 +90,10 @@ main(int argc, char *argv[]) com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:p:sr:w:")) != EOF) { - switch(opt) { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -154,34 +154,30 @@ main(int argc, char *argv[]) argv[0]); goto finished; } - if (object_name == NULL) { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; } - if (property_name == NULL) { fprintf(stderr, "%s: You must specify a property name\n", argv[0]); goto finished; } - if (ncp_create_property(conn, object_type, object_name, property_name, property_is_set ? 2 : 0, (write_sec << 4) + read_sec) != 0) { - fprintf(stderr, "%s: Could not create the property\n",argv[0]); - } - else + fprintf(stderr, "%s: Could not create the property\n", argv[0]); + } else { result = 0; } - finished: + finished: ncp_close(conn); return result; } diff --git a/util/nwbprm.c b/util/nwbprm.c index 116a0ed..baa37b2 100644 --- a/util/nwbprm.c +++ b/util/nwbprm.c @@ -22,15 +22,15 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options]\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options]\n", progname); + printf("\n" "-h Print this help text\n" "-S server Server name to be used\n" - "-U username Username sent to server\n" - "-P password Use this password\n" - "-n Do not use any password\n" - "-C Don't convert password to uppercase\n" + "-U username Username sent to server\n" + "-P password Use this password\n" + "-n Do not use any password\n" + "-C Don't convert password to uppercase\n" "\n" "-o object_name Name of object\n" "-t type Object type (decimal value)\n" @@ -48,7 +48,7 @@ main(int argc, char *argv[]) long err; int result = 1; - + int opt; progname = argv[0]; @@ -58,10 +58,10 @@ main(int argc, char *argv[]) com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:p:")) != EOF) { - switch(opt) { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -95,32 +95,28 @@ main(int argc, char *argv[]) argv[0]); goto finished; } - if (object_name == NULL) { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; } - if (property_name == NULL) { fprintf(stderr, "%s: You must specify a property name\n", argv[0]); goto finished; } - if (ncp_delete_property(conn, object_type, object_name, property_name) != 0) { - fprintf(stderr, "%s: Could not delete the property\n",argv[0]); - } - else + fprintf(stderr, "%s: Could not delete the property\n", argv[0]); + } else { result = 0; } - finished: + finished: ncp_close(conn); return result; } diff --git a/util/nwbpset.c b/util/nwbpset.c index 20886dc..42a3fa6 100644 --- a/util/nwbpset.c +++ b/util/nwbpset.c @@ -22,25 +22,25 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options] [values]\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options] [values]\n", progname); + printf("\n" "-h Print this help text\n" "-S server Server name to be used\n" - "-U username Username sent to server\n" - "-P password Use this password\n" - "-n Do not use any password\n" - "-C Don't convert password to uppercase\n" + "-U username Username sent to server\n" + "-P password Use this password\n" + "-n Do not use any password\n" + "-C Don't convert password to uppercase\n" "\n"); } static char * -get_line(char *buf, int len, FILE *stream) +get_line(char *buf, int len, FILE * stream) { char *result = fgets(buf, len, stream); if (result != NULL) { - buf[strlen(buf)-1] = '\0'; /* remove newline */ + buf[strlen(buf) - 1] = '\0'; /* remove newline */ } return result; } @@ -66,10 +66,10 @@ main(int argc, char *argv[]) com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?")) != EOF) { - switch(opt) { + switch (opt) + { case 'h': case '?': help(); @@ -100,7 +100,6 @@ main(int argc, char *argv[]) fprintf(stderr, "Illegal format on stdin\n"); goto finished; } - memset(buf, 0, sizeof(buf)); if (get_line(buf, sizeof(buf), stdin) == NULL) { @@ -130,21 +129,19 @@ main(int argc, char *argv[]) "ITEM over existing SET"); goto finished; } - if (info.property_security != property_security) { if (ncp_change_property_security(conn, object_type, object_name, property_name, - property_security)!=0) + property_security) != 0) { fprintf(stderr, "Could not change " "property security\n"); goto finished; } } - } - else + } else { if (ncp_create_property(conn, object_type, object_name, property_name, property_flag, @@ -161,7 +158,7 @@ main(int argc, char *argv[]) int i; int length; int segno; - char property_value[255*128]; + char property_value[255 * 128]; memset(property_value, 0, sizeof(property_value)); @@ -173,20 +170,20 @@ main(int argc, char *argv[]) } property_value[i] = strtoul(buf, NULL, 16); } - length = i-1; + length = i - 1; for (segno = 1; segno <= 255; segno++) { struct nw_property segment; - int offset = (segno-1)*128; + int offset = (segno - 1) * 128; - if ( offset > length ) + if (offset > length) { /* everything written */ break; } memcpy(segment.value, &(property_value[offset]), 128); - segment.more_flag = segno*128 < length; + segment.more_flag = segno * 128 < length; if (ncp_write_property_value(conn, object_type, object_name, property_name, @@ -196,8 +193,7 @@ main(int argc, char *argv[]) goto finished; } } - } - else + } else { /* SET property */ @@ -213,14 +209,13 @@ main(int argc, char *argv[]) fprintf(stderr, "Illegal format on stdin\n"); goto finished; } - if (ncp_add_object_to_set(conn, object_type, object_name, property_name, element_type, element_name) != 0) { - if (conn->completion != 0xE9) /* object already - in set */ + if (conn->completion != 0xE9) /* object already + in set */ { fprintf(stderr, "Could not add object " "to set\n"); @@ -228,11 +223,11 @@ main(int argc, char *argv[]) } } } - } + } result = 0; - finished: + finished: ncp_close(conn); return result; } diff --git a/util/nwbpvalues.c b/util/nwbpvalues.c index aaa5e92..fe1243b 100644 --- a/util/nwbpvalues.c +++ b/util/nwbpvalues.c @@ -15,7 +15,7 @@ static char *progname; static void -print_property(char *prop_name, __u8 *val, int segments); + print_property(char *prop_name, __u8 * val, int segments); static void usage(void) @@ -26,15 +26,15 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options]\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options]\n", progname); + printf("\n" "-h Print this help text\n" "-S server Server name to be used\n" - "-U username Username sent to server\n" - "-P password Use this password\n" - "-n Do not use any password\n" - "-C Don't convert password to uppercase\n" + "-U username Username sent to server\n" + "-P password Use this password\n" + "-n Do not use any password\n" + "-C Don't convert password to uppercase\n" "\n" "-o object_name Name of object\n" "-t type Object type (decimal value)\n" @@ -51,7 +51,7 @@ main(int argc, char *argv[]) char *object_name = NULL; int object_type = -1; char *property_name = NULL; - __u8 property_value[255*128]; + __u8 property_value[255 * 128]; int segno; int verbose = 0; int canonical = 0; @@ -60,7 +60,7 @@ main(int argc, char *argv[]) long err; int result = 1; - + int opt; progname = argv[0]; @@ -70,10 +70,10 @@ main(int argc, char *argv[]) com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:p:vc")) != EOF) { - switch(opt) { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -113,33 +113,29 @@ main(int argc, char *argv[]) argv[0]); goto finished; } - if (object_name == NULL) { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; } - if (property_name == NULL) { fprintf(stderr, "%s: You must specify a property name\n", argv[0]); goto finished; } - if (ncp_scan_property(conn, object_type, object_name, 0xffffffff, property_name, &info) != 0) { fprintf(stderr, "%s: Could not find property\n", argv[0]); goto finished; } - segno = 1; while (ncp_read_property_value(conn, object_type, object_name, segno, property_name, &segment) == 0) { - memcpy(&(property_value[(segno-1)*128]), segment.value, 128); + memcpy(&(property_value[(segno - 1) * 128]), segment.value, 128); if ((segment.more_flag == 0) || (segno == 255)) { break; @@ -154,27 +150,24 @@ main(int argc, char *argv[]) info.property_name, info.property_flags, info.property_security); } - if ((info.property_flags & 2) == 0) { /* ITEM property */ if (canonical != 0) { int i; - for (i = 0; i < segno*128; i++) + for (i = 0; i < segno * 128; i++) { printf("%-2.2x\n", property_value[i]); } - } - else + } else { print_property(property_name, property_value, segno); } - } - else + } else { int objects = 32 * segno; - __u32 *value = (__u32 *)property_value; + __u32 *value = (__u32 *) property_value; int i = 0; while (i < objects) @@ -184,7 +177,7 @@ main(int argc, char *argv[]) if ((value[i] == 0) || (value[i] == 0xffffffff)) { /* Continue with next segment */ - i = ((i/32) + 1) * 32; + i = ((i / 32) + 1) * 32; continue; } if (ncp_get_bindery_object_name(conn, ntohl(value[i]), @@ -195,15 +188,13 @@ main(int argc, char *argv[]) printf("%-4.4x\n%s\n", (unsigned int) o.object_type, o.object_name); - } - else if (verbose != 0) + } else if (verbose != 0) { printf("%s %08X %04X\n", o.object_name, (unsigned int) o.object_id, (unsigned int) o.object_type); - } - else + } else { printf("%s\n", o.object_name); } @@ -212,41 +203,41 @@ main(int argc, char *argv[]) } } result = 0; - - finished: + + finished: ncp_close(conn); return result; } static void -print_unknown(__u8 *val) +print_unknown(__u8 * val) { - int j = (128/16); + int j = (128 / 16); while (1) { int i; - for ( i = 0 ; i < 16 ; i++ ) + for (i = 0; i < 16; i++) { - printf ( "%02X " , val[i] ); + printf("%02X ", val[i]); } - printf ( " [" ); - for ( i = 0 ; i < 16 ; i++ ) + printf(" ["); + for (i = 0; i < 16; i++) { - printf ( "%c" , isprint(val[i]) ? val[i] : '.'); + printf("%c", isprint(val[i]) ? val[i] : '.'); } j -= 1; - if ( j == 0 ) + if (j == 0) { - printf ( "]\n" ); + printf("]\n"); return; } - printf ( "]+\n" ) ; + printf("]+\n"); val += 16; } } static void -print_string(__u8 *val) +print_string(__u8 * val) { puts(val); } @@ -256,65 +247,65 @@ print_station_addr(char *fmt, struct ncp_station_addr *addr, char *buff) { char *ret = buff; - while ( *fmt != 0 ) + while (*fmt != 0) { - switch ( *fmt ) + switch (*fmt) { case '%': - switch ( *(++fmt) ) + switch (*(++fmt)) { - case 'N': /* node */ - { - int i ; - for ( i = 0 ; i < 6 ; buff += 2 , i++ ) + case 'N': /* node */ { - sprintf(buff, "%02X",addr->Node[i]); + int i; + for (i = 0; i < 6; buff += 2, i++) + { + sprintf(buff, "%02X", addr->Node[i]); + } } - } break; - case 'S': /* Socket */ + case 'S': /* Socket */ sprintf(buff, "%04X", htons(addr->Socket)); - buff += 4 ; - break ; - case 'L': /* Lan */ + buff += 4; + break; + case 'L': /* Lan */ sprintf(buff, "%08lX", htonl(addr->NetWork)); - buff += 8 ; - break ; + buff += 8; + break; case '%': *buff++ = '%'; default: - break ; + break; } if (*fmt) { - fmt++ ; + fmt++; } - break ; + break; default: - *buff++ = *fmt++ ; + *buff++ = *fmt++; } } - *buff = 0 ; - return ret ; + *buff = 0; + return ret; } void -print_login_control ( __u8 *val ) +print_login_control(__u8 * val) { - int i , j , mask; - char buff[32]; - struct ncp_prop_login_control *a =(struct ncp_prop_login_control *)val; + int i, j, mask; + char buff[32]; + struct ncp_prop_login_control *a = (struct ncp_prop_login_control *) val; static char *days[] - = { "Sun" , "Mon" , "Tue" , "Wen" , "Thu" , "Fri" , "Sat" } ; + = + {"Sun", "Mon", "Tue", "Wen", "Thu", "Fri", "Sat"}; if (a->LastLogin[2] || a->LastLogin[1] || a->LastLogin[0] || a->LastLogin[3] || a->LastLogin[4] || a->LastLogin[5]) { printf("Last Login: %d.%d.%02d at %2d:%02d:%02d\n", - a->LastLogin[2] , a->LastLogin[1] , a->LastLogin[0] , - a->LastLogin[3] , a->LastLogin[4] , a->LastLogin[5]); - } - else + a->LastLogin[2], a->LastLogin[1], a->LastLogin[0], + a->LastLogin[3], a->LastLogin[4], a->LastLogin[5]); + } else { printf("Never logged in\n"); } @@ -333,7 +324,7 @@ print_login_control ( __u8 *val ) if (a->PasswordExpireDate[2] || a->PasswordExpireDate[1] || a->PasswordExpireDate[0]) { - printf("Password expires on: %d.%d.%d\n" , + printf("Password expires on: %d.%d.%d\n", a->PasswordExpireDate[2], a->PasswordExpireDate[1], a->PasswordExpireDate[0]); @@ -356,8 +347,7 @@ print_login_control ( __u8 *val ) printf("Maximum no of connections: %d\n", ntohs(a->MaxConnections)); } - - if ( a->MaxDiskUsage != 0xFFFFFF7FL ) + if (a->MaxDiskUsage != 0xFFFFFF7FL) { printf("Maximum DiskQuota : %8ld blocks\n", ntohl(a->MaxDiskUsage)); @@ -371,23 +361,22 @@ print_login_control ( __u8 *val ) } if (a->LastIntruder.NetWork != 0L) { - printf("Last \'intruder\' address: %s\n" , - print_station_addr("(%L): %N[%S]" , - &(a->LastIntruder),buff)); + printf("Last \'intruder\' address: %s\n", + print_station_addr("(%L): %N[%S]", + &(a->LastIntruder), buff)); } - if ( a->RestrictionMask & 0xFC ) + if (a->RestrictionMask & 0xFC) { printf("RestrictionMask : %02X\n", a->RestrictionMask); } - - for ( i = 0 ; i < 42 ; i++ ) + for (i = 0; i < 42; i++) { - if ( a->ConnectionTimeMask[i] != 0xFF ) + if (a->ConnectionTimeMask[i] != 0xFF) { i = 101; } } - if ( i < 100 ) + if (i < 100) { return; } @@ -395,50 +384,79 @@ print_login_control ( __u8 *val ) printf("Time restrictions: 1 1 1 1 1 1 1 1 1 1 2 2 2 2 ]\n"); printf(" Day [0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 ]\n"); - for ( i = 0 ; i < 7 ; i++ ) + for (i = 0; i < 7; i++) { - printf (" %s [" , days[i]); - for ( j = 0 ; j < 6 ; j++ ) + printf(" %s [", days[i]); + for (j = 0; j < 6; j++) { - for ( mask = 1 ; mask < 0x100 ; mask <<= 1 ) + for (mask = 1; mask < 0x100; mask <<= 1) { - putchar ( (*val & mask) ? '*' : ' ' ) ; + putchar((*val & mask) ? '*' : ' '); } - val++ ; + val++; } - printf ( "]\n" ) ; + printf("]\n"); } } void -print_addr( __u8 *val) +print_addr(__u8 * val) { char buff[50]; print_station_addr("(%L): %N[%S]", - (struct ncp_station_addr *)val, buff); + (struct ncp_station_addr *) val, buff); printf("%s\n", buff); } -static struct { - char *pname ; - void (*func)(__u8 *) ; -} formats[] = { - { "DESCRIPTION" , print_string } , - { "SURNAME" , print_string } , - { "OBJECT_CLASS" , print_string } , - { "DESCRIPTION" , print_string } , - { "IDENTIFICATION" , print_string } , - { "Q_DIRECTORY" , print_string } , - { "LOGIN_CONTROL" , print_login_control } , - { "NET_ADDRESS" , print_addr } , - { NULL , NULL } +static struct +{ + char *pname; + void (*func) (__u8 *); +} +formats[] = +{ + { + "DESCRIPTION", print_string + } + , + { + "SURNAME", print_string + } + , + { + "OBJECT_CLASS", print_string + } + , + { + "DESCRIPTION", print_string + } + , + { + "IDENTIFICATION", print_string + } + , + { + "Q_DIRECTORY", print_string + } + , + { + "LOGIN_CONTROL", print_login_control + } + , + { + "NET_ADDRESS", print_addr + } + , + { + NULL, NULL + } }; static void -print_property(char *prop_name, __u8 *val, int segments) +print_property(char *prop_name, __u8 * val, int segments) { int i; - void (*f)(__u8 *); + void (*f) (__u8 *); for (i = 0; formats[i].pname != NULL; i++) { @@ -454,12 +472,10 @@ print_property(char *prop_name, __u8 *val, int segments) f(val); return; } - for (i = 0; i < segments; i++) { - printf("Segment: %03d\n", i+1); - print_unknown(&(val[i*128])); + printf("Segment: %03d\n", i + 1); + print_unknown(&(val[i * 128])); printf("\n"); } } - diff --git a/util/nwfsinfo.c b/util/nwfsinfo.c index 1c01685..af0ebec 100644 --- a/util/nwfsinfo.c +++ b/util/nwfsinfo.c @@ -1,3 +1,4 @@ + /* * nwfsinfo.c * @@ -22,9 +23,9 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options]\n", progname); - printf("\n" + 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" @@ -37,34 +38,34 @@ help(void) 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"); + 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; } @@ -83,75 +84,72 @@ main(int argc, char **argv) com_err(argv[0], err, "when initializing"); return 1; } - while ((opt = getopt(argc, argv, "h?dti")) != EOF) { - switch(opt) + switch (opt) { case 'h': case '?': help(); break; case 'd': - { - char strings[512]; - char *s; - - if (ncp_get_file_server_description_strings(conn, - strings) - != 0) { - perror("could not get strings"); - ncp_close(conn); - return 1; - } + char strings[512]; + char *s; - s = strings; - while (s < strings+512) - { - if (strlen(s) == 0) + if (ncp_get_file_server_description_strings(conn, + strings) + != 0) { - break; + perror("could not get strings"); + ncp_close(conn); + return 1; } - puts(s); - s += strlen(s)+1; + s = strings; + while (s < strings + 512) + { + if (strlen(s) == 0) + { + break; + } + puts(s); + s += strlen(s) + 1; + } + break; } - break; - } case 't': - { - time_t t; - - if (ncp_get_file_server_time(conn, &t) != 0) { - perror("could not get server time"); - ncp_close(conn); - return 1; - } + time_t t; - fputs(ctime(&t), stdout); - break; - } + if (ncp_get_file_server_time(conn, &t) != 0) + { + perror("could not get server time"); + ncp_close(conn); + return 1; + } + fputs(ctime(&t), stdout); + break; + } 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; + 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; } - print_info(&info); - break; - } - + default: usage(); goto finished; } } - finished: + finished: ncp_close(conn); return 0; } diff --git a/util/nwfstime.c b/util/nwfstime.c index 1989ce0..eb9f152 100644 --- a/util/nwfstime.c +++ b/util/nwfstime.c @@ -22,15 +22,15 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options]\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options]\n", progname); + printf("\n" "-h Print this help text\n" "-S server Server name to be used\n" - "-U username Username sent to server\n" - "-P password Use this password\n" - "-n Do not use any password\n" - "-C Don't convert password to uppercase\n" + "-U username Username sent to server\n" + "-P password Use this password\n" + "-n Do not use any password\n" + "-C Don't convert password to uppercase\n" "\n" "-s Set file server's time from local time\n" "\n"); @@ -52,10 +52,9 @@ main(int argc, char **argv) com_err(argv[0], err, "when initializing"); return 1; } - while ((opt = getopt(argc, argv, "h?s")) != EOF) { - switch(opt) + switch (opt) { case 'h': case '?': @@ -70,7 +69,7 @@ main(int argc, char **argv) } } -finished: + finished: if (set != 0) { @@ -81,8 +80,7 @@ finished: ncp_close(conn); return 1; } - } - else + } else { if ((err = ncp_get_file_server_time(conn, &t)) != 0) { @@ -92,7 +90,7 @@ finished: } fputs(ctime(&t), stdout); } - + ncp_close(conn); return 0; } diff --git a/util/nwgrant.c b/util/nwgrant.c index 98a0576..1226fed 100644 --- a/util/nwgrant.c +++ b/util/nwgrant.c @@ -22,15 +22,15 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options] file/directory\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options] file/directory\n", progname); + printf("\n" "-h Print this help text\n" "-S server Server name to be used\n" - "-U username Username sent to server\n" - "-P password Use this password\n" - "-n Do not use any password\n" - "-C Don't convert password to uppercase\n" + "-U username Username sent to server\n" + "-P password Use this password\n" + "-n Do not use any password\n" + "-C Don't convert password to uppercase\n" "\n" "-o object_name Name of object added as trustee\n" "-t type Object type (decimal value)\n" @@ -60,10 +60,10 @@ main(int argc, char *argv[]) com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:r:")) != EOF) { - switch(opt) { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -90,22 +90,19 @@ main(int argc, char *argv[]) argv[0]); goto finished; } - if (object_name == NULL) { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; } - if (rights < 0) { fprintf(stderr, "%s: You must specify a rights mask\n", progname); goto finished; } - - if (optind != argc-1) + if (optind != argc - 1) { fprintf(stderr, "%s: You must specify a directory\n", progname); @@ -119,16 +116,14 @@ main(int argc, char *argv[]) progname, object_name); goto finished; } - if (ncp_add_trustee(conn, 0, path, o.object_id, rights) != 0) { - fprintf(stderr, "%s: Could not add trustee rights\n",progname); + fprintf(stderr, "%s: Could not add trustee rights\n", progname); goto finished; } - result = 0; - finished: + finished: ncp_close(conn); return result; } diff --git a/util/nwmsg.c b/util/nwmsg.c index 9572c26..209ea4c 100644 --- a/util/nwmsg.c +++ b/util/nwmsg.c @@ -41,7 +41,7 @@ main(int argc, char *argv[]) FILE *mtab; struct mntent *mnt; long err; - + progname = argv[0]; @@ -53,14 +53,12 @@ main(int argc, char *argv[]) progname); exit(1); } - mount_point = argv[1]; if ((conn = ncp_open_mount(mount_point, &err)) == NULL) { com_err(progname, err, "in ncp_open_mount"); exit(1); } - if (ncp_get_broadcast_message(conn, message) != 0) { fprintf(stderr, "%s: could not get broadcast message\n", @@ -68,13 +66,11 @@ main(int argc, char *argv[]) ncp_close(conn); exit(1); } - if (strlen(message) == 0) { syslog(LOG_DEBUG, "no message"); exit(0); } - #if 0 syslog(LOG_DEBUG, "message: %s", message); #endif @@ -87,7 +83,6 @@ main(int argc, char *argv[]) ncp_close(conn); exit(1); } - ncp_close(conn); if ((pwd = getpwuid(info.mounted_uid)) == NULL) @@ -96,14 +91,12 @@ main(int argc, char *argv[]) progname, info.mounted_uid); exit(1); } - if ((mtab = fopen(MOUNTED, "r")) == NULL) { fprintf(stderr, "%s: can't open %s\n", progname, MOUNTED); exit(1); } - while ((mnt = getmntent(mtab)) != NULL) { if (strcmp(mnt->mnt_dir, mount_point) == 0) @@ -116,12 +109,10 @@ main(int argc, char *argv[]) { syslog(LOG_DEBUG, "cannot find mtab entry\n"); } - if (search_utmp(pwd->pw_name, tty) != 0) { exit(1); } - sprintf(tty_path, "/dev/%s", tty); if ((tty_file = fopen(tty_path, "w")) == NULL) { @@ -129,8 +120,7 @@ main(int argc, char *argv[]) progname, tty_path, strerror(errno)); exit(1); } - - fprintf(tty_file,"\r\n\007\007\007Message from NetWare Server: %s\r\n", + fprintf(tty_file, "\r\n\007\007\007Message from NetWare Server: %s\r\n", mnt->mnt_fsname); fprintf(tty_file, "%s\r\n", message); fclose(tty_file); @@ -145,21 +135,22 @@ main(int argc, char *argv[]) * and the access time */ static int -term_chk(char *tty, int *msgsokP, time_t *atimeP, int *showerror) +term_chk(char *tty, int *msgsokP, time_t * atimeP, int *showerror) { struct stat s; char path[MAXPATHLEN]; - (void)sprintf(path, "/dev/%s", tty); - if (stat(path, &s) < 0) { + (void) sprintf(path, "/dev/%s", tty); + if (stat(path, &s) < 0) + { if (showerror) - (void)fprintf(stderr, - "write: %s: %s\n", path, strerror(errno)); - return(1); + (void) fprintf(stderr, + "write: %s: %s\n", path, strerror(errno)); + return (1); } *msgsokP = (s.st_mode & (S_IWRITE >> 3)) != 0; /* group write bit */ *atimeP = s.st_atime; - return(0); + return (0); } /* @@ -182,19 +173,20 @@ search_utmp(char *user, char *tty) char atty[sizeof(u.ut_line) + 1]; - if ((ufd = open(_PATH_UTMP, O_RDONLY)) < 0) { + if ((ufd = open(_PATH_UTMP, O_RDONLY)) < 0) + { perror("utmp"); return -1; } - nloggedttys = nttys = 0; bestatime = 0; user_is_me = 0; while (read(ufd, (char *) &u, sizeof(u)) == sizeof(u)) - if (strncmp(user, u.ut_name, sizeof(u.ut_name)) == 0) { + if (strncmp(user, u.ut_name, sizeof(u.ut_name)) == 0) + { ++nloggedttys; - (void)strncpy(atty, u.ut_line, sizeof(u.ut_line)); + (void) strncpy(atty, u.ut_line, sizeof(u.ut_line)); atty[sizeof(u.ut_line)] = '\0'; if (term_chk(atty, &msgsok, &atime, 0)) @@ -202,19 +194,20 @@ search_utmp(char *user, char *tty) if (!msgsok) continue; /* skip ttys with msgs off */ - if (u.ut_type != USER_PROCESS) - continue; /* it's not a valid entry */ + if (u.ut_type != USER_PROCESS) + continue; /* it's not a valid entry */ ++nttys; - if (atime > bestatime) { + if (atime > bestatime) + { bestatime = atime; - (void)strcpy(tty, atty); + (void) strcpy(tty, atty); } } - - (void)close(ufd); - if (nloggedttys == 0) { - (void)fprintf(stderr, "write: %s is not logged in\n", user); + (void) close(ufd); + if (nloggedttys == 0) + { + (void) fprintf(stderr, "write: %s is not logged in\n", user); return -1; } return 0; diff --git a/util/nwpasswd.c b/util/nwpasswd.c index faf7f86..2ef6234 100644 --- a/util/nwpasswd.c +++ b/util/nwpasswd.c @@ -22,16 +22,17 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options]\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options]\n", progname); + printf("\n" "-h Print this help text\n" "-S server Server name to be used\n" - "-U username Username sent to server\n" + "-U username Username sent to server\n" + "-O objectname Object name to change, default username\n" "-t type Object type (decimal value)\n" "\n"); } - + int main(int argc, char *argv[]) @@ -39,27 +40,33 @@ main(int argc, char *argv[]) struct ncp_conn_spec *spec; struct ncp_conn *conn; char *server = NULL; + char *user_name = NULL; char *object_name = NULL; int object_type = NCP_BINDERY_USER; unsigned char ncp_key[8]; struct ncp_bindery_object user; + unsigned char buf_obj_name[50]; long err; char *str; char oldpass[200], newpass1[200], newpass2[200]; - + int opt; progname = argv[0]; - while ((opt = getopt(argc, argv, "h?S:U:t:")) != EOF) + while ((opt = getopt(argc, argv, "h?S:U:O:t:")) != EOF) { - switch(opt) { + switch (opt) + { case 'S': server = optarg; break; case 'U': + user_name = optarg; + break; + case 'O': object_name = optarg; break; case 't': @@ -74,8 +81,7 @@ main(int argc, char *argv[]) exit(1); } } - - spec = ncp_find_conn_spec(server, object_name, "", + spec = ncp_find_conn_spec(server, user_name, "", 1, getuid(), &err); if (spec == NULL) @@ -83,13 +89,29 @@ main(int argc, char *argv[]) com_err(argv[0], err, "trying to find server"); exit(1); } - + if (!object_name) + { + object_name = spec->user; + } else + { + strcpy(buf_obj_name, object_name); + object_name = buf_obj_name; + str_upper(object_name); + } spec->login_type = object_type; printf("Changing password for user %s on server %s\n", - spec->user, spec->server); + object_name, spec->server); - str = getpass("Enter old password: "); + if (object_name == spec->user) + { + str = getpass("Enter old password: "); + } else + { + char sx[80]; + sprintf(sx, "Enter password for %s: ", spec->user); + str = getpass(sx); + } if (strlen(str) >= sizeof(oldpass)) { printf("Password too long\n"); @@ -122,7 +144,6 @@ main(int argc, char *argv[]) printf("You mistype the new password, try again\n"); exit(1); } - strcpy(spec->password, oldpass); if ((conn = ncp_open(spec, &err)) == NULL) @@ -130,16 +151,26 @@ main(int argc, char *argv[]) com_err(argv[0], err, "when trying to open connection"); exit(1); } - - if ( ((err = ncp_get_encryption_key(conn, ncp_key)) != 0) - || ((err = ncp_get_bindery_object_id(conn, 1, spec->user, + if (object_name != spec->user) + { + if (!(err = ncp_get_bindery_object_id(conn, 1, spec->user, + &user)) + && !(err = ncp_login_user(conn, spec->user, oldpass))) + { + *oldpass = '\0'; + } else + { + com_err(argv[0], err, "not own password"); + } + } + if (((err = ncp_get_encryption_key(conn, ncp_key)) != 0) + || ((err = ncp_get_bindery_object_id(conn, 1, object_name, &user)) != 0) || ((err = ncp_change_login_passwd(conn, &user, ncp_key, - oldpass, newpass1)) != 0)) + oldpass, newpass1)) != 0)) { com_err(argv[0], err, "trying to change password"); } - ncp_close(conn); return 0; } diff --git a/util/nwrevoke.c b/util/nwrevoke.c index f37a400..e2a5e65 100644 --- a/util/nwrevoke.c +++ b/util/nwrevoke.c @@ -22,15 +22,15 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options] file/directory\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options] file/directory\n", progname); + printf("\n" "-h Print this help text\n" "-S server Server name to be used\n" - "-U username Username sent to server\n" - "-P password Use this password\n" - "-n Do not use any password\n" - "-C Don't convert password to uppercase\n" + "-U username Username sent to server\n" + "-P password Use this password\n" + "-n Do not use any password\n" + "-C Don't convert password to uppercase\n" "\n" "-o object_name Name of object removed as trustee\n" "-t type Object type (decimal value)\n" @@ -58,10 +58,10 @@ main(int argc, char *argv[]) com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:")) != EOF) { - switch(opt) { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -85,15 +85,13 @@ main(int argc, char *argv[]) argv[0]); goto finished; } - if (object_name == NULL) { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; } - - if (optind != argc-1) + if (optind != argc - 1) { fprintf(stderr, "%s: You must specify a directory\n", progname); @@ -107,17 +105,15 @@ main(int argc, char *argv[]) progname, object_name); goto finished; } - if (ncp_delete_trustee(conn, 0, path, o.object_id) != 0) { fprintf(stderr, "%s: Could not remove trustee rights\n", progname); goto finished; } - result = 0; - finished: + finished: ncp_close(conn); return result; } diff --git a/util/nwrights.c b/util/nwrights.c index 9bd3eda..876e4b2 100644 --- a/util/nwrights.c +++ b/util/nwrights.c @@ -22,9 +22,9 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options] file/directory\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options] file/directory\n", progname); + printf("\n" "-h Print this help text\n" "\n" "file/directory\n" @@ -45,7 +45,8 @@ main(int argc, char *argv[]) while ((opt = getopt(argc, argv, "h?")) != EOF) { - switch(opt) { + switch (opt) + { case 'h': case '?': help(); @@ -61,18 +62,15 @@ main(int argc, char *argv[]) usage(); goto finished; } - - if (optind == argc-1) + if (optind == argc - 1) { path = argv[optind]; } - if ((conn = ncp_open_mount(path, &err)) == NULL) { com_err(argv[0], err, "when initializing"); goto finished; } - if ((err = ncp_get_eff_directory_rights(conn, 0, 0, 0x8006, conn->i.volume_number, conn->i.directory_id, NULL, @@ -81,61 +79,52 @@ main(int argc, char *argv[]) com_err(argv[0], err, "when finding rights"); goto finished; } - printf("Your effective rights for %s are: [%c%c%c%c%c%c%c%c]\n", path, - ((rights & NCP_PERM_SUPER ) != 0) ? 'S' : ' ', - ((rights & NCP_PERM_READ ) != 0) ? 'R' : ' ', - ((rights & NCP_PERM_WRITE ) != 0) ? 'W' : ' ', + ((rights & NCP_PERM_SUPER) != 0) ? 'S' : ' ', + ((rights & NCP_PERM_READ) != 0) ? 'R' : ' ', + ((rights & NCP_PERM_WRITE) != 0) ? 'W' : ' ', ((rights & NCP_PERM_CREATE) != 0) ? 'C' : ' ', ((rights & NCP_PERM_DELETE) != 0) ? 'E' : ' ', ((rights & NCP_PERM_MODIFY) != 0) ? 'M' : ' ', ((rights & NCP_PERM_SEARCH) != 0) ? 'F' : ' ', - ((rights & NCP_PERM_OWNER ) != 0) ? 'A' : ' '); + ((rights & NCP_PERM_OWNER) != 0) ? 'A' : ' '); - if ((rights & NCP_PERM_SUPER ) != 0) + if ((rights & NCP_PERM_SUPER) != 0) { printf("(S): You have SUPERVISOR rights\n"); } - - if ((rights & NCP_PERM_READ ) != 0) + if ((rights & NCP_PERM_READ) != 0) { printf("(R): You may READ from files\n"); } - - if ((rights & NCP_PERM_WRITE ) != 0) + if ((rights & NCP_PERM_WRITE) != 0) { printf("(W): You may WRITE to files\n"); } - if ((rights & NCP_PERM_CREATE) != 0) { printf("(C): You may CREATE files\n"); } - if ((rights & NCP_PERM_DELETE) != 0) { printf("(E): You may ERASE files\n"); } - if ((rights & NCP_PERM_MODIFY) != 0) { printf("(M): You may MODIFY directory\n"); } - if ((rights & NCP_PERM_SEARCH) != 0) { printf("(F): You may SCAN for files\n"); } - - if ((rights & NCP_PERM_OWNER ) != 0) + if ((rights & NCP_PERM_OWNER) != 0) { printf("(A): You may change ACCESS control\n"); } - result = 0; - finished: + finished: ncp_close(conn); return result; } diff --git a/util/nwtrustee.c b/util/nwtrustee.c new file mode 100644 index 0000000..08ecab7 --- /dev/null +++ b/util/nwtrustee.c @@ -0,0 +1,159 @@ +/* + * nwtrustee.c + * + * List Trustees + * + * Copyright (C) 1996 by Volker Lendecke + * + */ + +#include +#include +#include +#include +#include "ncplib.h" + +static char *progname; + +static void +usage(void) +{ + fprintf(stderr, "usage: %s [options] pattern\n", progname); + return; +} + +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" + "-U username Username sent to server\n" + "-P password Use this password\n" + "-n Do not use any password\n" + "-C Don't convert password to uppercase\n" + "\n" + "-l volumeid Volume id to be searched\n" + "-L volname Volume name insteed of id\n" + "-o objectid Object id\n" + "-O objname Object name ( type must be specified )\n" + "-t type Object type\n" + "-v Verbose listing\n" + "\n"); +} + +int +fromhex(char c) +{ + c -= '0'; + if (c > 9) + c = toupper(c) + '0' - 'A' + 10; + return c & 15; +} + +int +main(int argc, char **argv) +{ + struct ncp_conn *conn; + struct ncp_bindery_object bobj; + + char ppath[256]; + char *p; + long err; + int opt, vid, type = 1; + int verbose = 0; + __u32 oid = 1; + __u16 nextp, trust; + + progname = argv[0]; + + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { + com_err(argv[0], err, "when initializing"); + return 1; + } + while ((opt = getopt(argc, argv, "h?vl:L:o:O:t:")) != EOF) + { + switch (opt) + { + case 'h': + case '?': + help(); + exit(1); + case 'l': + vid = atoi(optarg); + break; + case 'L': + if (ncp_get_volume_number(conn, optarg, &vid)) + { + ncp_close(conn); + return 1; + } + break; + + case 'o': + oid = 0; + while (*optarg) + { + oid = (oid << 4) | fromhex(*optarg); + optarg++; + } + break; + case 'O': + for (p = optarg; *p != 0; p++) + { + *p = toupper(*p); + } + if (ncp_get_bindery_object_id(conn, type, optarg, &bobj)) + { + ncp_close(conn); + return 1; + } + oid = bobj.object_id; + break; + case 'v': + verbose = 1; + break; + case 't': + type = atoi(optarg); + break; + default: + usage(); + exit(1); + } + } + + if (optind < argc) + { + usage(); + exit(1); + } + nextp = 0; + while (!ncp_get_trustee(conn, oid, vid, ppath, &trust, &nextp)) + { + if (!nextp) + break; + printf("%s ", ppath); + if (verbose) + { + strcpy(ppath, "[ R W O C E A F M ]"); + p = ppath + 2; + for (type = 1; type < 256; type <<= 1) + { + if (!(trust & type)) + *p = ' '; + p += 2; + } + printf("%s\n", ppath); + } else + { + printf("%X\n", trust); + } + } + + + ncp_close(conn); + return 0; +} diff --git a/util/nwuserlist.c b/util/nwuserlist.c index bca22e2..43ad78c 100644 --- a/util/nwuserlist.c +++ b/util/nwuserlist.c @@ -34,9 +34,9 @@ str_trim_right(char *s, char c) static void help(void) { - printf("\n"); - printf("usage: %s [options]\n", progname); - printf("\n" + 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" @@ -62,10 +62,9 @@ main(int argc, char **argv) com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?a")) != EOF) { - switch(opt) + switch (opt) { case 'h': case '?': @@ -86,7 +85,6 @@ main(int argc, char **argv) ncp_close(conn); return 1; } - if (isatty(1)) { if (print_addr == 0) @@ -97,8 +95,7 @@ main(int argc, char **argv) "Conn", "User name", "Login time"); - } - else + } else { printf("\n%-6s%-21s%-27s%-12s\n" "---------------------------------------------" @@ -109,7 +106,6 @@ main(int argc, char **argv) "Login time"); } } - for (i = 1; i <= info.MaximumServiceConnections; i++) { char name[49]; @@ -127,17 +123,16 @@ main(int argc, char **argv) { 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: + finished: ncp_close(conn); return 0; } diff --git a/util/nwvolinfo.c b/util/nwvolinfo.c new file mode 100644 index 0000000..b00de3e --- /dev/null +++ b/util/nwvolinfo.c @@ -0,0 +1,119 @@ +/* + * nwvolinfo.c + * + * Volume Information + * + * Copyright (C) 1996 by Volker Lendecke + * + */ + +#include +#include +#include +#include +#include "ncplib.h" + +static char *progname; + +static void +usage(void) +{ + fprintf(stderr, "usage: %s [options] pattern\n", progname); + return; +} + +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" + "-U username Username sent to server\n" + "-P password Use this password\n" + "-n Do not use any password\n" + "-C Don't convert password to uppercase\n" + "\n" + "-v volume volume name\n" + "-N Numeric format\n" + "\n"); +} + +int +main(int argc, char **argv) +{ + struct ncp_conn *conn; + struct ncp_volume_info o; + + char *volname = "SYS"; + long err; + int opt; + int numk; + __u16 type = 0; + + progname = argv[0]; + + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { + com_err(argv[0], err, "when initializing"); + return 1; + } + while ((opt = getopt(argc, argv, "h?Nv:")) != EOF) + { + switch (opt) + { + case 'h': + case '?': + help(); + exit(1); + case 'N': + type = 1; + break; + case 'v': + volname = optarg; + break; + default: + usage(); + exit(1); + } + } + + if (optind < argc) + { + usage(); + exit(1); + } + if (ncp_get_volume_number(conn, volname, &opt)) + { + exit(1); + } + if (ncp_get_volume_info_with_number(conn, opt, &o)) + { + exit(1); + } + numk = o.sectors_per_block / 2; + o.free_blocks += o.purgeable_blocks; + if (type) + { + printf("%d %d %d %d %d %d\n", + o.total_blocks * numk, + o.free_blocks * numk, + o.purgeable_blocks * numk, + o.not_yet_purgeable_blocks * numk, + o.total_dir_entries, + o.available_dir_entries); + } else + { + printf("Total : %dK\n", o.total_blocks * numk); + printf("Free : %dK\n", o.free_blocks * numk); + printf("Purgable : %dK\n", o.purgeable_blocks * numk); + printf("No Purg. : %dK\n", o.not_yet_purgeable_blocks * numk); + printf("Dirs : %d\n", o.total_dir_entries); + printf("Free dirs: %d\n", o.available_dir_entries); + } + + + ncp_close(conn); + return 0; +} diff --git a/util/pqlist.c b/util/pqlist.c index dd5215c..26ad308 100644 --- a/util/pqlist.c +++ b/util/pqlist.c @@ -29,18 +29,15 @@ main(int argc, char **argv) com_err(argv[0], err, "when initializing"); return 1; } - if (argc > 2) { fprintf(stderr, "usage: %s [options] [pattern]\n", argv[0]); return 1; } - if (argc == 2) { pattern = argv[1]; } - for (p = pattern; *p != '\0'; p++) { *p = toupper(*p); @@ -55,7 +52,6 @@ main(int argc, char **argv) "Print queue name", "Queue ID"); } - q.object_id = 0xffffffff; while (ncp_scan_bindery_object(conn, q.object_id, @@ -63,14 +59,13 @@ main(int argc, char **argv) { found = 1; printf("%-52s", q.object_name); - printf("%08X\n", (unsigned int)q.object_id); + printf("%08X\n", (unsigned int) q.object_id); } if ((found == 0) && (isatty(1))) { printf("No queues found\n"); } - ncp_close(conn); return 0; } diff --git a/util/pserver.c b/util/pserver.c index 203ff38..83f82bf 100644 --- a/util/pserver.c +++ b/util/pserver.c @@ -18,7 +18,8 @@ #include #include "ncplib.h" -struct nw_queue { +struct nw_queue +{ struct ncp_conn *conn; char queue_name[NCP_BINDERY_NAME_LEN]; @@ -34,11 +35,11 @@ static int term_request; static char *progname; static int -init_queue(struct ncp_conn *conn, char *queue_name, - char *command, struct nw_queue *q); + init_queue(struct ncp_conn *conn, char *queue_name, + char *command, struct nw_queue *q); static int -poll_queue(struct nw_queue *q); + poll_queue(struct nw_queue *q); static void usage(void) @@ -50,20 +51,20 @@ usage(void) static void help(void) { - printf("\n"); - printf("usage: %s [options]\n", progname); - printf("\n" + printf("\n"); + printf("usage: %s [options]\n", progname); + printf("\n" "-S server Server name to be used\n" - "-U username Print Server name sent to server\n" - "-P password Use this password\n" - "-n Do not use any password\n" - "-C Don't convert password to uppercase\n" - "-q queue name Name of the printing queue to use\n" + "-U username Print Server name sent to server\n" + "-P password Use this password\n" + "-n Do not use any password\n" + "-C Don't convert password to uppercase\n" + "-q queue name Name of the printing queue to use\n" "-c command Name of print command, default: 'lpr'\n" "-j job type Type of job (Form number) to service\n" "-t timeout Polling interval, default: 30 sec\n" "-d Debug: don't daemonize\n" - "-h print this help text\n" + "-h print this help text\n" "\n"); } @@ -74,9 +75,9 @@ help(void) static void terminate_handler() { - signal(SIGTERM,terminate_handler); + signal(SIGTERM, terminate_handler); signal(SIGINT, terminate_handler); - term_request=1; + term_request = 1; } /* Daemon_init is taken from Stevens, Adv. Unix programming */ @@ -88,12 +89,10 @@ daemon_init(void) if ((pid = fork()) < 0) { return -1; - } - else if (pid != 0) + } else if (pid != 0) { exit(0); /* parent vanishes */ } - /* child process */ setsid(); chdir("/"); @@ -124,7 +123,7 @@ main(int argc, char *argv[]) for (i = 1; i < argc; i += 1) { - if ( (strcmp(argv[i], "-h") == 0) + if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "-?") == 0)) { help(); @@ -146,14 +145,12 @@ main(int argc, char *argv[]) daemon_init(); openlog("pserver", LOG_PID, LOG_LPR); } - if ((conn = ncp_initialize_as(&argc, argv, 1, NCP_BINDERY_PSERVER, &err)) == NULL) { com_err(argv[0], err, "when initializing"); return 1; } - while ((opt = getopt(argc, argv, "q:c:j:t:dh")) != EOF) { switch (opt) @@ -186,7 +183,6 @@ main(int argc, char *argv[]) usage(); return -1; } - memzero(q); if (queue_name == NULL) @@ -194,28 +190,25 @@ main(int argc, char *argv[]) fprintf(stderr, "You must specify a queue\n"); return 1; } - if (init_queue(conn, queue_name, command, &q) != 0) { perror("Could not init queue"); ncp_close(conn); return 1; } - q.job_type = job_type; term_request = 0; - signal(SIGTERM,terminate_handler); + signal(SIGTERM, terminate_handler); signal(SIGINT, terminate_handler); while (1) { - if ( (poll_queue(&q) != 0) + if ((poll_queue(&q) != 0) && (term_request == 0)) { continue; } - if (term_request != 0) { break; @@ -239,14 +232,13 @@ init_queue(struct ncp_conn *conn, char *queue_name, char *command, q->conn = conn; q->command = command; - + if (ncp_get_bindery_object_id(conn, NCP_BINDERY_PQUEUE, queue_name, &obj) != 0) { fprintf(stderr, "Queue %s not found\n", queue_name); return -1; } - q->queue_id = obj.object_id; memcpy(q->queue_name, obj.object_name, sizeof(q->queue_name)); @@ -258,26 +250,26 @@ init_queue(struct ncp_conn *conn, char *queue_name, char *command, } return 0; } - + void build_command(struct nw_queue *q, struct queue_job *j, char *target, int target_size) { char *s = q->command; - char *target_end = target+target_size; + char *target_end = target + target_size; void add_string(char *s) + { + int len = strlen(s); + if (target + len + 1 > target_end) { - int len = strlen(s); - if (target + len + 1 > target_end) - { - len = target_end - target - 1; - } - strncpy(target, s, len); - target += len; + len = target_end - target - 1; } - + strncpy(target, s, len); + target += len; + } + memset(target, 0, target_size); @@ -290,8 +282,7 @@ build_command(struct nw_queue *q, struct queue_job *j, s += 1; continue; } - - switch (*(s+1)) + switch (*(s + 1)) { case '%': *target = '%'; @@ -305,8 +296,7 @@ build_command(struct nw_queue *q, struct queue_job *j, == 0) { user = u.object_name; - } - else + } else { user = "*UNKNOWN USER*"; } @@ -314,7 +304,7 @@ build_command(struct nw_queue *q, struct queue_job *j, } default: *target = '%'; - *(target+1) = *(s+1); + *(target + 1) = *(s + 1); target += 2; } s += 2; @@ -322,7 +312,7 @@ build_command(struct nw_queue *q, struct queue_job *j, } - + static int poll_queue(struct nw_queue *q) @@ -337,19 +327,16 @@ poll_queue(struct nw_queue *q) /* No job for us */ return 0; } - if (pipe(fd) < 0) { syslog(LOG_ERR, "pipe error: %m"); goto fail; } - if ((pid = fork()) < 0) { syslog(LOG_ERR, "fork error: %m"); goto fail; } - if (pid > 0) { /* parent */ @@ -375,8 +362,7 @@ poll_queue(struct nw_queue *q) { syslog(LOG_ERR, "waitpid: %m\n"); } - } - else + } else { /* child */ @@ -394,7 +380,6 @@ poll_queue(struct nw_queue *q) } close(fd[0]); } - build_command(q, &job, command, sizeof(command)); execl("/bin/sh", "sh", "-c", command, NULL); @@ -403,10 +388,10 @@ poll_queue(struct nw_queue *q) exit(1); } - ncp_finish_servicing_job(q->conn, q->queue_id, job.j.JobNumber,0); - return 1; + ncp_finish_servicing_job(q->conn, q->queue_id, job.j.JobNumber, 0); + return 1; - fail: + fail: ncp_abort_servicing_job(q->conn, q->queue_id, job.j.JobNumber); /* We tell that we did not have a job to avoid overloading when something's wrong */ diff --git a/util/slist.c b/util/slist.c index 9c2a773..184578f 100644 --- a/util/slist.c +++ b/util/slist.c @@ -30,12 +30,10 @@ main(int argc, char *argv[]) printf("usage: %s [pattern]\n", argv[0]); exit(1); } - if (argc == 2) { pattern = argv[1]; } - for (p = pattern; *p != '\0'; p++) { *p = toupper(*p); @@ -46,7 +44,6 @@ main(int argc, char *argv[]) com_err(argv[0], err, "in ncp_open"); exit(1); } - if (isatty(1)) { printf("\n%-52s%-10s%-12s\n" @@ -56,7 +53,6 @@ main(int argc, char *argv[]) "Network", "Node Address"); } - obj.object_id = 0xffffffff; while (ncp_scan_bindery_object(conn, obj.object_id, @@ -65,7 +61,7 @@ main(int argc, char *argv[]) { struct nw_property prop; struct prop_net_address *naddr - = (struct prop_net_address *)∝ + = (struct prop_net_address *) ∝ found = 1; @@ -86,7 +82,5 @@ main(int argc, char *argv[]) { printf("No servers found\n"); } - ncp_close(conn); } -