diff --git a/connect.c b/connect.c index b85c201..298a0ee 100644 --- a/connect.c +++ b/connect.c @@ -99,40 +99,40 @@ static int new_dir_handle(ino_t inode, NW_PATH *nwpath) DIR_HANDLE *dh = NULL; time_t akttime = time(NULL); time_t last_time = akttime; - int thandle = 0; + int thandle = 1; int nhandle = 0; for (rethandle=0; rethandle < anz_dirhandles; rethandle++){ dh=&(dir_handles[rethandle]); if (!dh->inode) { - if (!nhandle) nhandle = rethandle+1; + if (!nhandle) + nhandle = rethandle+1; } else if (dh->inode == inode && dh->volume == nwpath->volume){ - /* Dieser hat Vorrang */ - if (dh->f) closedir(dh->f); - dh->f = NULL; - dh->timestamp = akttime; - nhandle = rethandle+1; + nhandle = rethandle+1; break; } else if (dh->timestamp < last_time){ thandle = rethandle+1; last_time = dh->timestamp; } } + if (!nhandle){ - if (anz_dirhandles < MAX_DIRHANDLES) { + if (anz_dirhandles < MAX_DIRHANDLES) { dh=&(dir_handles[anz_dirhandles]); + dh->f=NULL; rethandle = ++anz_dirhandles; } else { dh=&(dir_handles[thandle-1]); - if (dh->f) closedir(dh->f); - dh->f = NULL; rethandle = thandle; } - } else rethandle=nhandle; + } else + rethandle=nhandle; /* init dir_handle */ dh=&(dir_handles[rethandle-1]); strcpy(dh->unixname, build_unix_name(nwpath, 0)); dh->kpath = dh->unixname + strlen(dh->unixname); + if (dh->f) + closedir(dh->f); if ((dh->f = opendir(dh->unixname)) != (DIR*) NULL){ dh->volume = nwpath->volume; dh->vol_options = nw_volumes[dh->volume].options; @@ -145,10 +145,10 @@ static int new_dir_handle(ino_t inode, NW_PATH *nwpath) dh->f = NULL; } } else { - dh->f = (DIR*)NULL; + dh->inode = 0; dh->unixname[0] = '\0'; dh->vol_options = 0; - dh->kpath = (char*)NULL; + dh->kpath = dh->unixname; rethandle = /* -0x9c */ -0xff; } return(rethandle); diff --git a/debmask.h b/debmask.h index 66cb0f0..5137253 100644 --- a/debmask.h +++ b/debmask.h @@ -8,7 +8,8 @@ */ /* NWCONN */ -#define D_FH_OPEN 1 /* file open/close */ +#define D_FH_OPEN 1 /* file open/close */ +#define D_FH_LOCK 2 /* file lock/unlock */ #endif diff --git a/doc/CHANGES b/doc/CHANGES index a20d267..3ef14cb 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -1,6 +1,6 @@ Sorry, this is in German only. User important notes are in the NEWS file. -Aenderungen in mars_nwe bis zum : 15-Dec-96 +Aenderungen in mars_nwe bis zum : 17-Jan-97 -------------------------------- Erste 'oeffentliche' Version ^^^^^^^^^^ VERSION 0.94 ^^^^^^^^ @@ -266,4 +266,11 @@ Erste 'oeffentliche' Version Es konnten nicht alle freigegebenen Filehandles wiederverwendet werden. -> "No more free file handles" <----- ^^^^^^^^^^ pl7 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- Section 6: version-"spoofing" auf default '1' (3.11) gesetzt. +- Fehler in connect.c, new_dir_handle() beseitigt. + Hinweis von: Dmitry +- QUOTA support von Matt Paley eingebaut. +- Print Queue Command Parameter erweitert um '!' + fuer banner_user_name, banner_file_name +<----- ^^^^^^^^^^ pl8 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/CREDITS b/doc/CREDITS index 045a724..c9253ab 100644 --- a/doc/CREDITS +++ b/doc/CREDITS @@ -31,6 +31,9 @@ James B. MacLean Louis Zammit Mangion testings+bugfixes +Matt Paley + adding QUOTA support, login time restrictions + Jiri A. Randus testing bindery code diff --git a/doc/FAQS b/doc/FAQS index 94001fe..2cfbb0a 100644 --- a/doc/FAQS +++ b/doc/FAQS @@ -1,9 +1,8 @@ -last updated: 05-Dec-96 +last updated: 16-Jan-97 Q: I don't exaclty understand the meaning of some ponits in nw.ini: 12,13 What will happen if I will not put PASSWORD here? Will it take it from /etc/passwd? I want it to be so. - A: This passwords will be stored (crypted) into bindery to can handle the crypted login call from a standarrd Novell client. @@ -41,6 +40,16 @@ Q: I have arcnet cards and I dont find the frame-typ TRXNET. A: The correct frame typ is handled by the arcnet driver. You should use the 'dummy frametyp' 802.3. +Q: The CONFIG_IPX_INTERN kernel option is *not* set but + when I start 'nwserv' as root it sais: + !! NWSERV 0:PANIC !! + NWSERV 0:!! configuration error !!: + mars_nwe don't run with kernel 'full internal net'. + Change kernel option CONFIG_IPX_INTERN=NO (nobody needs it) + or use 'ipxd' and change mars_nwe INTERNAL_RIP_SAP=0. +A: Sorry but mars_nwe can recognize this setting only at compile time, + so you must compile mars_nwe again with actual kernel CONFIG_IPX_INTERN=NO + settings. diff --git a/doc/NEWS b/doc/NEWS index 927f33f..3ef5271 100644 --- a/doc/NEWS +++ b/doc/NEWS @@ -1,5 +1,16 @@ # in this files are some notes for user of mars_nwe. -------09-Nov-96--- 0.98.pl7 ---------- +------29-Jan-97--- 0.98.pl8 ---------- +- Section 6: version-"spoofing" now set to '1' (3.11) default. +- New switch in config.h: QUOTA_SUPPORT +- quota support added by Matt Paley + Before the netware quotas will work the linux quota system must be + started up, this is done by: + Ensuring that the current kernel supports quotas. + Adding usrquota to the option field in the appropriate /etc/fstab entry + Running 'quotacheck -a' + Running 'quotaon -a' (must be repeated after a reboot) +- login time restrictions added by Matt Paley +------05-Jan-97--- 0.98.pl7 ---------- - section 8: new flag 0x4 added. (see examples/nw.ini). ------09-Nov-96--- 0.98.pl5 ---------- - now Novell Client32 should works. diff --git a/doc/mars_nwe.lsm b/doc/mars_nwe.lsm index 2040225..f9005a7 100644 --- a/doc/mars_nwe.lsm +++ b/doc/mars_nwe.lsm @@ -1,7 +1,7 @@ Begin3 Title: mars_nwe -Version: 0.98.pl7 -Entered-date: 09-Jan-97 +Version: 0.98.pl8 +Entered-date: 01-Feb-97 Description: Full netware-emulator (src), beta. Supports file-services, bindery-services, printing-services, routing-services. @@ -9,7 +9,7 @@ Keywords: novell, netware, server, ipx, ncp, tli Author: mstover@stover.f.eunet.de (Martin Stover) Maintained-by: mstover@stover.f.eunet.de (Martin Stover) Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs - 200kB mars_nwe-0.98.pl7.tgz + 200kB mars_nwe-0.98.pl8.tgz Alternate-site: sunsite.unc.edu:/pub/Linux/system/Filesystems/ncpfs Platforms: Linux (1.2.xx, 1.3.xx, 2.xx), UnixWare (2.xx) Copying-policy: GNU diff --git a/examples/config.h b/examples/config.h index d70fa4f..5d3f00a 100644 --- a/examples/config.h +++ b/examples/config.h @@ -1,4 +1,4 @@ -/* config.h: 04-Nov-96 */ +/* config.h: 29-Jan-97 */ /* some of this config is needed by make, others by cc */ #define DO_DEBUG 1 /* compile in debug code */ @@ -75,4 +75,5 @@ #define MAX_RIP_ENTRIES 50 /* max. rip responses */ /* -------------------- */ #define SHADOW_PWD 0 /* change to '1' for shadow passwds */ +#define QUOTA_SUPPORT 0 /* change to '1' for quota support */ diff --git a/examples/nw.ini b/examples/nw.ini index 4d715e3..f5d5c12 100644 --- a/examples/nw.ini +++ b/examples/nw.ini @@ -2,7 +2,7 @@ # This is the configuration-file for "mars_nwe", a free netware-emulator # for Linux. # -# last changed: 20-Nov-96 +# last changed: 29-Jan-97 # This file specifies which Linux-resources (printers, users, directories) # should be accessible to the DOS-clients via "mars_nwe". Furthermore @@ -252,24 +252,22 @@ # Some clients work better if the server tells that it is a 3.11 Server, # although many calls (namespace services) of a real 3.11 Server are # missing yet. -# To test the namespace calls, this entry must be set to > 0 and `config.h' -# must be altered before compiling "mars_nwe". -# # ------------------------------------------------------------------------- # Syntax: # 6 SERVER_VERSION # # SERVER_VERSION: the version-number reported to DOS-clients -# 0 Version 2.15 (default) -# 1 Version 3.11 (will be default soon) +# 0 Version 2.15 (was default till version 0.98.pl7) +# 1 Version 3.11 (is default now) # 2 Version 3.12 (burst mode is not implemented yet) # # If you want to use longfilenamesupport and/or namespace routines # you should set this section to '1'. +# And you should read doc/FAQS. # ------------------------------------------------------------------------- # -6 0 +6 1 # ========================================================================= @@ -323,6 +321,8 @@ # normally the rename file call returns an error if this # routine is used for renaming directories. # +# 0x8 ignore station/time restrictions for supervisor. +# # other flags may follow. # value will be interpreted as hex value. @@ -528,6 +528,10 @@ # (_not_ the spooling-directories of the Linux-lpd) # PRINT_COMMAND: command used for serving the print-jobs under Linux # (see "man lpr" and "man magicfilter" for details) +# if the '!' is last parameter of command then +# the queue-packet fields 'banner_user_name' +# and 'banner_file_name' will be added to the +# command as last parameters. # # Examples: # 21 LASER SYS:/PRINT/L lpr -Plaser @@ -603,7 +607,7 @@ # Section 402: station connect restrictions # -# for special handling of the 'creat connection' call. +# for special handling of the 'creat connection' (attach) call. 402 0 # 0 = ignore entry 400, create connection always enabled. # 1 = 400 are excludes, create connection normally enabled. # 2 = 400 are includes, create connection normally disabled. diff --git a/makefile.unx b/makefile.unx index 2f922d4..f7ed842 100644 --- a/makefile.unx +++ b/makefile.unx @@ -1,5 +1,5 @@ #if 0 -#makefile.unx 14-Nov-96 +#makefile.unx 09-Jan-97 #endif VPATH=$(V_VPATH) @@ -9,7 +9,7 @@ C=.c V_H=0 V_L=98 -P_L=7 +P_L=8 #define D_P_L 1 DISTRIB=mars_nwe diff --git a/ncpserv.c b/ncpserv.c index 646fff2..0db91c2 100644 --- a/ncpserv.c +++ b/ncpserv.c @@ -32,7 +32,7 @@ static time_t akttime; static int server_goes_down=0; static int ipx_out_fd=-1; #if 0 -static int tells_server_version=0; +static int tells_server_version=1; #endif static int sock_nwbind=-1; static int sock_echo =-1; diff --git a/net.h b/net.h index 32c0028..7cbdab1 100644 --- a/net.h +++ b/net.h @@ -262,6 +262,14 @@ extern int errno; # define DO_TESTING 0 #endif +#ifdef LINUX +# ifndef QUOTA_SUPPORT +# define QUOTA_SUPPORT 0 +# endif +#else +# undef QUOTA_SUPPORT +# define QUOTA_SUPPORT 0 +#endif #ifdef LINUX # ifdef IN_NWROUTED diff --git a/nwbind.c b/nwbind.c index 789385a..828852c 100644 --- a/nwbind.c +++ b/nwbind.c @@ -1,5 +1,5 @@ /* nwbind.c */ -#define REVISION_DATE "02-Jan-97" +#define REVISION_DATE "20-Jan-97" /* NCP Bindery SUB-SERVER */ /* authentification and some message handling */ @@ -294,6 +294,30 @@ static void handle_fxx(int gelen, int func) case 0xb: /* Get Broadcast Message (new) */ default : completition=0xfb; /* not handled */ } /* switch */ + } else if (0x16 == func) { + switch (ufunc) { + /* QUOTA support from: Matt Paley */ + case 0x21 : /* Change volume restrictions */ + case 0x22 : /* Remove volume restrictions */ + case 0x29 : { /* Read volume restrictions */ + /* Returns 3 integers, uid, gid, 0=OK/1=Permission denied */ + uint32 id = GET_BE32(rdata+1); + if (get_guid((int*) responsedata, (int*)(responsedata+sizeof(int)), + id, (char *) NULL) != 0) { + completition = 0xff; + XDPRINTF((2, 0, "quota id-uid mapping failure %d 0x%x", ufunc, id)); + } + /* OK if supervisor or trying to read (0x29) own limits */ + if (act_c->object_id == 1 || + (act_c->object_id == id && ufunc == 0x29)) + ((int *) responsedata)[2] = 0; /* OK */ + else + ((int *) responsedata)[2] = 1; /* Fail */ + data_len = sizeof(int)*3; + } + break; + default : completition=0xfb; /* not handled */ + } } else if (0x17 == func) { /* Fileserver Enviro */ switch (ufunc) { case 0x01 : { /* Change User Password OLD */ @@ -452,7 +476,7 @@ static void handle_fxx(int gelen, int func) } if (!result) { internal_act = 1; - result = nw_test_adr_access(obj.id, &(act_c->client_adr)); + result = nw_test_adr_time_access(obj.id, &(act_c->client_adr)); internal_act = 0; } if (!result) @@ -547,10 +571,9 @@ static void handle_fxx(int gelen, int func) result=nw_test_passwd(obj.id, act_c->crypt_key, rdata); internal_act = 0; } - if (result > -1) { internal_act = 1; - result = nw_test_adr_access(obj.id, &(act_c->client_adr)); + result = nw_test_adr_time_access(obj.id, &(act_c->client_adr)); internal_act = 0; } if (result > -1) diff --git a/nwconn.c b/nwconn.c index e87a433..6c1c57d 100644 --- a/nwconn.c +++ b/nwconn.c @@ -1,4 +1,4 @@ -/* nwconn.c 06-Nov-96 */ +/* nwconn.c 17-Jan-97 */ /* one process / connection */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany @@ -19,6 +19,11 @@ */ #include "net.h" +#if 1 +# define LOC_RW_BUFFERSIZE RW_BUFFERSIZE +#else +# define LOC_RW_BUFFERSIZE 512 +#endif #include #include "nwvolume.h" #include "nwfile.h" @@ -34,7 +39,7 @@ int act_pid = 0; static int father_pid = -1; static ipxAddr_t from_addr; static ipxAddr_t my_addr; -static struct t_unitdata ud; +static struct t_unitdata ud; static uint8 ipx_pack_typ = PACKT_CORE; static int last_sequence = -9999; @@ -58,13 +63,13 @@ static int sock_echo =-1; static int req_printed=0; static int ncp_response(int sequence, int task, - int completition, int data_len) + int completition, int data_len) { ncpresponse->sequence = (uint8) sequence; ncpresponse->task = (uint8) task; ncpresponse->completition = (uint8) completition; ncpresponse->reserved = (uint8) 0; - last_sequence = sequence; + last_sequence = sequence; if (req_printed) { XDPRINTF((0,0, "NWCONN NCP_RESP seq:%d, conn:%d, compl=0x%x task=%d TO %s", @@ -166,272 +171,272 @@ static int handle_ncp_serv(void) if (ncp_type == 0x2222) { switch (function) { - case 0x12 : { /* Get Volume Info with Number */ - int volume = (int)*requestdata; - struct XDATA { - uint8 sec_per_block[2]; - uint8 total_blocks[2]; - uint8 avail_blocks[2]; - uint8 total_dirs[2]; - uint8 avail_dirs[2]; - uint8 name[16]; - uint8 removable[2]; - } *xdata = (struct XDATA*) responsedata; - int result; + case 0x12 : { /* Get Volume Info with Number */ + int volume = (int)*requestdata; + struct XDATA { + uint8 sec_per_block[2]; + uint8 total_blocks[2]; + uint8 avail_blocks[2]; + uint8 total_dirs[2]; + uint8 avail_dirs[2]; + uint8 name[16]; + uint8 removable[2]; + } *xdata = (struct XDATA*) responsedata; + int result; memset(xdata, 0, sizeof(struct XDATA)); - if ((result = nw_get_volume_name(volume, xdata->name))>-1){ - struct fs_usage fsp; - if (!nw_get_fs_usage(xdata->name, &fsp)) { - int sector_scale=1; - while (fsp.fsu_blocks/sector_scale > 0xffff) + if ((result = nw_get_volume_name(volume, xdata->name))>-1){ + struct fs_usage fsp; + if (!nw_get_fs_usage(xdata->name, &fsp)) { + int sector_scale=1; + while (fsp.fsu_blocks/sector_scale > 0xffff) sector_scale+=2; - U16_TO_BE16(sector_scale, xdata->sec_per_block); - U16_TO_BE16(fsp.fsu_blocks/sector_scale, xdata->total_blocks); - U16_TO_BE16(fsp.fsu_bavail/sector_scale, xdata->avail_blocks); - U16_TO_BE16(fsp.fsu_files, xdata->total_dirs); - U16_TO_BE16(fsp.fsu_ffree, xdata->avail_dirs); + U16_TO_BE16(sector_scale, xdata->sec_per_block); + U16_TO_BE16(fsp.fsu_blocks/sector_scale, xdata->total_blocks); + U16_TO_BE16(fsp.fsu_bavail/sector_scale, xdata->avail_blocks); + U16_TO_BE16(fsp.fsu_files, xdata->total_dirs); + U16_TO_BE16(fsp.fsu_ffree, xdata->avail_dirs); if ( get_volume_options(volume, 1) & VOL_OPTION_REMOUNT) { - U16_TO_BE16(1, xdata->removable); + U16_TO_BE16(1, xdata->removable); } else { - U16_TO_BE16(0, xdata->removable); + U16_TO_BE16(0, xdata->removable); } - } - data_len = sizeof(struct XDATA); - } else completition = (uint8) -result; - } break; + } + data_len = sizeof(struct XDATA); + } else completition = (uint8) -result; + } break; - case 0x14 : { /* GET DATE und TIME */ - struct SERVER_DATE { - uint8 year; - uint8 mon; - uint8 day; - uint8 std; - uint8 min; - uint8 sec; - uint8 day_of_week; - } *mydate = (struct SERVER_DATE*) responsedata; - struct tm *s_tm; - time_t timer; - time(&timer); - s_tm = localtime(&timer); - mydate->year = (uint8) s_tm->tm_year; - mydate->mon = (uint8) s_tm->tm_mon+1; - mydate->day = (uint8) s_tm->tm_mday; + case 0x14 : { /* GET DATE und TIME */ + struct SERVER_DATE { + uint8 year; + uint8 mon; + uint8 day; + uint8 std; + uint8 min; + uint8 sec; + uint8 day_of_week; + } *mydate = (struct SERVER_DATE*) responsedata; + struct tm *s_tm; + time_t timer; + time(&timer); + s_tm = localtime(&timer); + mydate->year = (uint8) s_tm->tm_year; + mydate->mon = (uint8) s_tm->tm_mon+1; + mydate->day = (uint8) s_tm->tm_mday; - mydate->std = (uint8) s_tm->tm_hour; - mydate->min = (uint8) s_tm->tm_min; - mydate->sec = (uint8) s_tm->tm_sec; - mydate->day_of_week = (uint8) s_tm->tm_wday; /* Wochentag */ - data_len = sizeof(struct SERVER_DATE); - } - break; + mydate->std = (uint8) s_tm->tm_hour; + mydate->min = (uint8) s_tm->tm_min; + mydate->sec = (uint8) s_tm->tm_sec; + mydate->day_of_week = (uint8) s_tm->tm_wday; /* Wochentag */ + data_len = sizeof(struct SERVER_DATE); + } + break; - case 0x15 : - return(-1); /* nwbind must do this call */ + case 0x15 : + return(-1); /* nwbind must do this call */ - case 0x16 : { - /* uint8 len = *(requestdata+1); */ - uint8 *p = requestdata +2; - if (0 == *p){ - /******** SetDirektoryHandle *************/ - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, ufunc */ - uint8 target_dir_handle; /* to change */ - uint8 source_dir_handle; - uint8 pathlen; - uint8 path[2]; - } *input = (struct INPUT *) (ncprequest); - completition = - (uint8)-nw_set_dir_handle((int)input->target_dir_handle, - (int)input->source_dir_handle, - input->path, - (int)input->pathlen, - (int)(ncprequest->task)); + case 0x16 : { + /* uint8 len = *(requestdata+1); */ + uint8 *p = requestdata +2; + if (0 == *p){ + /******** SetDirektoryHandle *************/ + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 div[3]; /* 0x0, dlen, ufunc */ + uint8 target_dir_handle; /* to change */ + uint8 source_dir_handle; + uint8 pathlen; + uint8 path[2]; + } *input = (struct INPUT *) (ncprequest); + completition = + (uint8)-nw_set_dir_handle((int)input->target_dir_handle, + (int)input->source_dir_handle, + input->path, + (int)input->pathlen, + (int)(ncprequest->task)); - } else if (1 == *p){ - /******** GetDirektoryPATH ***************/ - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, ufunc */ - uint8 dir_handle; - } *input = (struct INPUT *) (ncprequest); - struct XDATA { - uint8 len; - uint8 name[256]; - } *xdata = (struct XDATA*) responsedata; - int result = nw_get_directory_path((int)input->dir_handle, xdata->name); - if (result > -1){ - xdata->len = (uint8) result; - data_len = result + 1; + } else if (1 == *p){ + /******** GetDirektoryPATH ***************/ + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 div[3]; /* 0x0, dlen, ufunc */ + uint8 dir_handle; + } *input = (struct INPUT *) (ncprequest); + struct XDATA { + uint8 len; + uint8 name[256]; + } *xdata = (struct XDATA*) responsedata; + int result = nw_get_directory_path((int)input->dir_handle, xdata->name); + if (result > -1){ + xdata->len = (uint8) result; + data_len = result + 1; xdata->name[result] = '\0'; - XDPRINTF((5,0, "GetDirektoryPATH=%s", xdata->name)); - } else completition = (uint8)-result; - } else if (2 == *p){ /* Scan Direktory Information */ - /******** Scan Dir Info ****************/ - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, ufunc */ - uint8 dir_handle; /* Verzeichnis Handle */ - uint8 sub_dir_nmbr[2]; /* HI LOW */ + XDPRINTF((5,0, "GetDirektoryPATH=%s", xdata->name)); + } else completition = (uint8)-result; + } else if (2 == *p){ /* Scan Direktory Information */ + /******** Scan Dir Info ****************/ + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 div[3]; /* 0x0, dlen, ufunc */ + uint8 dir_handle; /* Verzeichnis Handle */ + uint8 sub_dir_nmbr[2]; /* HI LOW */ /* firsttime 1 */ - uint8 len; /* kann auch 0 sein */ - uint8 path[2]; - } *input = (struct INPUT *) (ncprequest); - struct XDATA { - uint8 sub_dir_name[16]; - uint8 create_date_time[4]; - uint8 owner_id[4]; /* HI LOW */ - uint8 max_right_mask; - uint8 reserved; /* Reserved by Novell */ - uint8 sub_dir_nmbr[2]; /* HI LOW */ - } *xdata = (struct XDATA*) responsedata; - int result; - memcpy(xdata->sub_dir_nmbr, input->sub_dir_nmbr, 2); - result = nw_scan_dir_info((int)input->dir_handle, - input->path, (int)input->len, - xdata->sub_dir_nmbr, xdata->sub_dir_name, - xdata->create_date_time, xdata->owner_id); - if (result > -1){ - xdata->max_right_mask = (uint8)result; - data_len = sizeof(struct XDATA); - XDPRINTF((5,0,"Scan Dir Info max_right_mask=%d", (int)result)); - } else completition = (uint8)-result; - } else if (*p == 0x3){ /* Get Direktory Rights */ - /******** Get Eff Dir Rights ****************/ - struct XDATA { - uint8 eff_right_mask; /* Effektive Right to Dir, old! */ - } *xdata = (struct XDATA*) responsedata; - int result = nw_get_eff_dir_rights( - (int)*(p+1), - p+3, - (int)*(p+2), 0); - if (result > -1) { - xdata->eff_right_mask = (uint8) result; - data_len = 1; - XDPRINTF((5,0,"Got eff Dir Rights=%d", (int)result)); - } else completition = (uint8) -result; - } else if (*p == 0x4){ /* Modify Max Right MAsk */ - /******** MODIFY MAX RIGHT MASK ****************/ + uint8 len; /* kann auch 0 sein */ + uint8 path[2]; + } *input = (struct INPUT *) (ncprequest); + struct XDATA { + uint8 sub_dir_name[16]; + uint8 create_date_time[4]; + uint8 owner_id[4]; /* HI LOW */ + uint8 max_right_mask; + uint8 reserved; /* Reserved by Novell */ + uint8 sub_dir_nmbr[2]; /* HI LOW */ + } *xdata = (struct XDATA*) responsedata; + int result; + memcpy(xdata->sub_dir_nmbr, input->sub_dir_nmbr, 2); + result = nw_scan_dir_info((int)input->dir_handle, + input->path, (int)input->len, + xdata->sub_dir_nmbr, xdata->sub_dir_name, + xdata->create_date_time, xdata->owner_id); + if (result > -1){ + xdata->max_right_mask = (uint8)result; + data_len = sizeof(struct XDATA); + XDPRINTF((5,0,"Scan Dir Info max_right_mask=%d", (int)result)); + } else completition = (uint8)-result; + } else if (*p == 0x3){ /* Get Direktory Rights */ + /******** Get Eff Dir Rights ****************/ + struct XDATA { + uint8 eff_right_mask; /* Effektive Right to Dir, old! */ + } *xdata = (struct XDATA*) responsedata; + int result = nw_get_eff_dir_rights( + (int)*(p+1), + p+3, + (int)*(p+2), 0); + if (result > -1) { + xdata->eff_right_mask = (uint8) result; + data_len = 1; + XDPRINTF((5,0,"Got eff Dir Rights=%d", (int)result)); + } else completition = (uint8) -result; + } else if (*p == 0x4){ /* Modify Max Right MAsk */ + /******** MODIFY MAX RIGHT MASK ****************/ /* NO REPLY !! */ - completition = 0xfb; /* TODO */ - } else if (*p == 0x5){ /* Get Volume Number 0 .. 31 */ - /******** GetVolume Number ***************/ - /* p+1 = namelen */ - /* p+2 = data z.b 'SYS' */ - struct XDATA { - uint8 volume; /* Nummer */ - } *xdata = (struct XDATA*) responsedata; - int result = nw_get_volume_number(p+2, (int)*(p+1)); - if (result > -1) { - xdata->volume = (uint8) result; - data_len = 1; - } else completition = (uint8) -result; - } else if (*p == 0x6){ /* Get Volume Name from 0 .. 31 */ - /******** Get Volume Name ***************/ - struct XDATA { - uint8 namelen; - uint8 name[16]; - } *xdata = (struct XDATA*) responsedata; - int result = nw_get_volume_name((int)*(p+1), xdata->name); - if (result > -1) { - xdata->namelen = (uint8) result; - data_len = result+1; - } else completition = (uint8) -result; - } else if (*p == 0xa){ /* legt Verzeichnis an */ - /******** Create Dir *********************/ - int dir_handle = (int) *(p+1); + completition = 0xfb; /* TODO */ + } else if (*p == 0x5){ /* Get Volume Number 0 .. 31 */ + /******** GetVolume Number ***************/ + /* p+1 = namelen */ + /* p+2 = data z.b 'SYS' */ + struct XDATA { + uint8 volume; /* Nummer */ + } *xdata = (struct XDATA*) responsedata; + int result = nw_get_volume_number(p+2, (int)*(p+1)); + if (result > -1) { + xdata->volume = (uint8) result; + data_len = 1; + } else completition = (uint8) -result; + } else if (*p == 0x6){ /* Get Volume Name from 0 .. 31 */ + /******** Get Volume Name ***************/ + struct XDATA { + uint8 namelen; + uint8 name[16]; + } *xdata = (struct XDATA*) responsedata; + int result = nw_get_volume_name((int)*(p+1), xdata->name); + if (result > -1) { + xdata->namelen = (uint8) result; + data_len = result+1; + } else completition = (uint8) -result; + } else if (*p == 0xa){ /* legt Verzeichnis an */ + /******** Create Dir *********************/ + int dir_handle = (int) *(p+1); #if 0 - int rightmask = (int) *(p+2); + int rightmask = (int) *(p+2); #endif - int pathlen = (int) *(p+3); - uint8 *path = p+4; - int code = nw_mk_rd_dir(dir_handle, path, pathlen, 1); - if (code) completition = (uint8) -code; - } else if (*p == 0xb){ /* deletes dir */ - /******** Delete DIR *********************/ - int dir_handle = (int) *(p+1); + int pathlen = (int) *(p+3); + uint8 *path = p+4; + int code = nw_mk_rd_dir(dir_handle, path, pathlen, 1); + if (code) completition = (uint8) -code; + } else if (*p == 0xb){ /* deletes dir */ + /******** Delete DIR *********************/ + int dir_handle = (int) *(p+1); #if 0 - int reserved = (int) *(p+2); /* Res. by NOVELL */ + int reserved = (int) *(p+2); /* Res. by NOVELL */ #endif - int pathlen = (int) *(p+3); - uint8 *path = p+4; - int code = nw_mk_rd_dir(dir_handle, path, pathlen, 0); - if (code) completition = (uint8) -code; - } else if (*p == 0xd){ /* Add Trustees to DIR */ - /******** AddTrustesstoDir ***************/ + int pathlen = (int) *(p+3); + uint8 *path = p+4; + int code = nw_mk_rd_dir(dir_handle, path, pathlen, 0); + if (code) completition = (uint8) -code; + } else if (*p == 0xd){ /* Add Trustees to DIR */ + /******** AddTrustesstoDir ***************/ #if 0 - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, ufunc */ - uint8 dir_handle; /* Verzeichnis Handle */ - uint8 trustee_id[4]; /* Trustee Object ID */ - uint8 trustee_right_mask; - uint8 pathlen; - uint8 path; - } *input = (struct INPUT *) (ncprequest); - /* TODO !!!!!!!!!!!!!!!!!!!! */ + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 div[3]; /* 0x0, dlen, ufunc */ + uint8 dir_handle; /* Verzeichnis Handle */ + uint8 trustee_id[4]; /* Trustee Object ID */ + uint8 trustee_right_mask; + uint8 pathlen; + uint8 path; + } *input = (struct INPUT *) (ncprequest); + /* TODO !!!!!!!!!!!!!!!!!!!! */ #endif - do_druck++; - } else if (*p == 0xf){ /* rename dir */ - /******** Rename DIR *********************/ - int dir_handle = (int) *(p+1); - int oldpathlen = (int) *(p+2); + do_druck++; + } else if (*p == 0xf){ /* rename dir */ + /******** Rename DIR *********************/ + int dir_handle = (int) *(p+1); + int oldpathlen = (int) *(p+2); uint8 *oldpath = p+3; - int newpathlen = (int) *(oldpath + oldpathlen); + int newpathlen = (int) *(oldpath + oldpathlen); uint8 *newpath = oldpath + oldpathlen + 1; - int code = mv_dir(dir_handle, - oldpath, oldpathlen, - newpath, newpathlen); - if (code) completition = (uint8) -code; - } else if (*p == 0x12 /* Allocate Permanent Dir Handle */ + int code = mv_dir(dir_handle, + oldpath, oldpathlen, + newpath, newpathlen); + if (code) completition = (uint8) -code; + } else if (*p == 0x12 /* Allocate Permanent Dir Handle */ - /******** Allocate Permanent DIR Handle **/ - || *p == 0x13 /* Allocate Temp Dir Handle */ - /******** Allocate Temp DIR Handle **/ - || *p == 0x16) { /* Allocate Special Temp Dir Handle */ - /******** Allocate spez temp DIR Handle **/ - struct XDATA { - uint8 dirhandle; /* new Dir Handle */ - uint8 right_mask; /* 0xff effektive Right MAsk ? */ - } *xdata = (struct XDATA*) responsedata; - int dirhandle = nw_alloc_dir_handle( - (int) *(p+1), - p+4, - (int)*(p+3), - (int)*(p+2), - (*p==0x12) ? 0 - : ((*p==0x13) ? 1 : 2), - (int)(ncprequest->task)); - if (dirhandle > -1){ - xdata->dirhandle = (uint8) dirhandle; - xdata->right_mask = 0xff; - data_len = sizeof(struct XDATA); - } else completition = (uint8) -dirhandle; + /******** Allocate Permanent DIR Handle **/ + || *p == 0x13 /* Allocate Temp Dir Handle */ + /******** Allocate Temp DIR Handle **/ + || *p == 0x16) { /* Allocate Special Temp Dir Handle */ + /******** Allocate spez temp DIR Handle **/ + struct XDATA { + uint8 dirhandle; /* new Dir Handle */ + uint8 right_mask; /* 0xff effektive Right MAsk ? */ + } *xdata = (struct XDATA*) responsedata; + int dirhandle = nw_alloc_dir_handle( + (int) *(p+1), + p+4, + (int)*(p+3), + (int)*(p+2), + (*p==0x12) ? 0 + : ((*p==0x13) ? 1 : 2), + (int)(ncprequest->task)); + if (dirhandle > -1){ + xdata->dirhandle = (uint8) dirhandle; + xdata->right_mask = 0xff; + data_len = sizeof(struct XDATA); + } else completition = (uint8) -dirhandle; - } else if (*p == 0x14){ /* deallocate Dir Handle */ - /******** Free DIR Handle ****************/ - int err_code = nw_free_dir_handle((int)*(p+1), - (int)(ncprequest->task)); - if (err_code) completition = (uint8) -err_code; - } else if (*p == 0x15){ /* liefert Volume Information */ - /******** Get Volume Info with Handle ****/ - struct XDATA { + } else if (*p == 0x14){ /* deallocate Dir Handle */ + /******** Free DIR Handle ****************/ + int err_code = nw_free_dir_handle((int)*(p+1), + (int)(ncprequest->task)); + if (err_code) completition = (uint8) -err_code; + } else if (*p == 0x15){ /* liefert Volume Information */ + /******** Get Volume Info with Handle ****/ + struct XDATA { uint8 sectors[2]; - uint8 total_blocks[2]; - uint8 avail_blocks[2]; - uint8 total_dirs[2]; /* anz dirs */ - uint8 avail_dirs[2]; /* free dirs */ - uint8 name[16]; /* SYS Name */ - uint8 removable[2]; - } *xdata = (struct XDATA*)responsedata; - int result = nw_get_vol_number((int)*(p+1)); + uint8 total_blocks[2]; + uint8 avail_blocks[2]; + uint8 total_dirs[2]; /* anz dirs */ + uint8 avail_dirs[2]; /* free dirs */ + uint8 name[16]; /* SYS Name */ + uint8 removable[2]; + } *xdata = (struct XDATA*)responsedata; + int result = nw_get_vol_number((int)*(p+1)); memset(xdata, 0, sizeof(struct XDATA)); - if (result > -1) { + if (result > -1) { int volume = result; - result = nw_get_volume_name(volume, xdata->name); - if (result > -1) { + result = nw_get_volume_name(volume, xdata->name); + if (result > -1) { struct fs_usage fsp; if (!nw_get_fs_usage(xdata->name, &fsp)) { int sector_scale=1; @@ -448,51 +453,51 @@ static int handle_ncp_serv(void) U16_TO_BE16(0, xdata->removable); } } - data_len = sizeof(struct XDATA); - XDPRINTF((5,0,"GIVE VOLUME INFO from :%s:", xdata->name)); - result = 0; - } - } - completition = (uint8)-result; - } else if (*p == 0x19){ /* Set Directory Information */ + data_len = sizeof(struct XDATA); + XDPRINTF((5,0,"GIVE VOLUME INFO from :%s:", xdata->name)); + result = 0; + } + } + completition = (uint8)-result; + } else if (*p == 0x19){ /* Set Directory Information */ #if 0 - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, ufunc */ - uint8 dir_handle; /* Verzeichnis Handle */ - uint8 trustee_id[4]; /* Trustee Object ID */ - uint8 trustee_right_mask; - uint8 pathlen; - uint8 path; - } *input = (struct INPUT *) (ncprequest); + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 div[3]; /* 0x0, dlen, ufunc */ + uint8 dir_handle; /* Verzeichnis Handle */ + uint8 trustee_id[4]; /* Trustee Object ID */ + uint8 trustee_right_mask; + uint8 pathlen; + uint8 path; + } *input = (struct INPUT *) (ncprequest); #endif /* No REPLY */ - completition = 0xfb; /* !!!!! TODO !!!! */ - } else if (*p == 0x1a){ /* Get Pathname of A Volume Dir Pair */ + completition = 0xfb; /* !!!!! TODO !!!! */ + } else if (*p == 0x1a){ /* Get Pathname of A Volume Dir Pair */ #if 0 - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, ufunc */ - uint8 volume; - uint8 dir_entry[2]; - } *input = (struct INPUT *) (ncprequest); - struct XDATA { - uint8 pathlen; - uint8 pathname; - } *xdata = (struct XDATA*)responsedata; + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 div[3]; /* 0x0, dlen, ufunc */ + uint8 volume; + uint8 dir_entry[2]; + } *input = (struct INPUT *) (ncprequest); + struct XDATA { + uint8 pathlen; + uint8 pathname; + } *xdata = (struct XDATA*)responsedata; #endif - completition = 0xfb; /* !!!!! TODO !!!! */ - } else if (*p == 0x1e){ + completition = 0xfb; /* !!!!! TODO !!!! */ + } else if (*p == 0x1e){ /* SCAN a Directory */ - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, ufunc */ - uint8 dir_handle; /* Verzeichnis Handle */ - uint8 attrib; /* Search Attrib z.B. 0x6 */ - uint8 searchsequence[4]; /* 32 bit */ - uint8 len; - uint8 data[2]; - } *input = (struct INPUT *) (ncprequest); + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 div[3]; /* 0x0, dlen, ufunc */ + uint8 dir_handle; /* Verzeichnis Handle */ + uint8 attrib; /* Search Attrib z.B. 0x6 */ + uint8 searchsequence[4]; /* 32 bit */ + uint8 len; + uint8 data[2]; + } *input = (struct INPUT *) (ncprequest); int result = nw_scan_a_directory( responsedata, input->dir_handle, @@ -503,69 +508,58 @@ static int handle_ncp_serv(void) if (result > -1) data_len = result; else completition = (uint8) (-result); - } else if (*p == 0x1f){ + } else if (*p == 0x1f){ /* SCAN a root dir ???? */ - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, ufunc */ - uint8 dir_handle; /* Verzeichnis Handle */ - uint8 dont_know1; /* ???? 0xc0 */ - uint8 dont_know2; /* ???? 0xfa */ - } *input = (struct INPUT *) (ncprequest); + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 div[3]; /* 0x0, dlen, ufunc */ + uint8 dir_handle; /* Verzeichnis Handle */ + uint8 dont_know1; /* ???? 0xc0 */ + uint8 dont_know2; /* ???? 0xfa */ + } *input = (struct INPUT *) (ncprequest); int result = nw_scan_a_root_dir( responsedata, input->dir_handle); if (result > -1) data_len = result; else completition = (uint8) (-result); - } else if (*p == 0x20){ - /* scan volume user disk restrictions */ - uint8 volnr = *(p+1); - /* uint32 sequenz = GET_BE32(p+2); */ - struct XDATA { - uint8 entries; /* 0x0 */ + } else if (*p == 0x20){ + /* scan volume user disk restrictions */ + uint8 volnr = *(p+1); + /* uint32 sequenz = GET_BE32(p+2); */ + struct XDATA { + uint8 entries; /* 0x0 */ /*--- per entry (max.entries = 12) ----*/ uint8 id[4]; uint8 restriction[4]; - } *xdata = (struct XDATA*) responsedata; + } *xdata = (struct XDATA*) responsedata; int result = nw_get_volume_name(volnr, NULL); if (result > -1) { - xdata->entries = 0x0; - data_len = (8 * xdata->entries) + 1; + xdata->entries = 0x0; + data_len = (8 * xdata->entries) + 1; } else completition = (uint8) (-result); - } else if (*p == 0x21) { -#if DO_DEBUG - /* change Vol restrictions for Obj */ - uint8 volnr = *(p+1); - uint32 id = GET_BE32(p+2); - uint32 blocks = GET_BE32(p+6); - XDPRINTF((2,0,"TODO:Change vol restriction vol=%d, id=0x%lx, Blocks=0x%lx", - (int)volnr, id, blocks)) -#endif - ; - } else if (*p == 0x22) { -#if DO_DEBUG - /* remove Vol restrictions for Obj */ - uint8 volnr = *(p+1); - uint32 id = GET_BE32(p+2); - XDPRINTF((2,0, "TODO:Remove vol restriction vol=%d, id=0x%lx", - (int)volnr, id)) -#endif - ; - } else if (*p == 0x25){ /* setting FILE INFO ??*/ - /* TODO !!!!!!!!!!!!!!!!!!!! */ - do_druck++; - } else if (*p == 0x26) { /* Scan file or Dir for ext trustees */ + } else if (*p == 0x21) { + /* change Vol restrictions for Obj */ + XDPRINTF((5, 0, "Change vol restrictions")); + return(-2); /* nwbind must do prehandling */ + } else if (*p == 0x22) { + /* remove Vol restrictions for Obj */ + XDPRINTF((5, 0, "Remove vol restrictions")); + return(-2); /* nwbind must do prehandling */ + } else if (*p == 0x25){ /* setting FILE INFO ??*/ + /* TODO !!!!!!!!!!!!!!!!!!!! */ + do_druck++; + } else if (*p == 0x26) { /* Scan file or Dir for ext trustees */ int sequenz = (int)*(p+2); /* trustee sequenz */ - struct XDATA { - uint8 entries; + struct XDATA { + uint8 entries; uint8 ids[80]; /* 20 id's */ uint8 trustees[40]; /* 20 trustees's */ - } *xdata = (struct XDATA*) responsedata; - int result = nw_get_eff_dir_rights( - (int)*(p+1), - p+4, - (int)*(p+3), 1); - if (result > -1){ + } *xdata = (struct XDATA*) responsedata; + int result = nw_get_eff_dir_rights( + (int)*(p+1), + p+4, + (int)*(p+3), 1); + if (result > -1){ if (!sequenz) { memset(xdata, 0, sizeof(struct XDATA)); xdata->entries=1; @@ -580,124 +574,127 @@ static int handle_ncp_serv(void) data_len = sizeof(struct XDATA); } else completition = 0x9c; /* no more trustees */ } else completition = (uint8) (-result); - } else if (*p == 0x27) { /* Add Ext Trustees to DIR */ + } else if (*p == 0x27) { /* Add Ext Trustees to DIR */ #if 0 - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, ufunc */ - uint8 dir_handle; /* Handle */ - uint8 trustee_id[4]; /* Trustee Object ID */ - uint8 trustee_rights[2]; /* low - high */ - uint8 pathlen; - uint8 path; - } *input = (struct INPUT *) (ncprequest); - /* TODO !!!!!!!!!!!!!!!!!!!! */ + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 div[3]; /* 0x0, dlen, ufunc */ + uint8 dir_handle; /* Handle */ + uint8 trustee_id[4]; /* Trustee Object ID */ + uint8 trustee_rights[2]; /* low - high */ + uint8 pathlen; + uint8 path; + } *input = (struct INPUT *) (ncprequest); + /* TODO !!!!!!!!!!!!!!!!!!!! */ #endif - do_druck++; - } else if (*p == 0x29){ - /* read volume restrictions for an object */ + do_druck++; + } else if (*p == 0x29){ + /* read volume restrictions for an object */ +#if QUOTA_SUPPORT + XDPRINTF((5, 0, "Read vol restrictions")); + return(-2); /* nwbind must do prehandling */ +#else #if DO_DEBUG uint8 volnr = *(p+1); uint32 id = GET_BE32(p+2); #endif - struct XDATA { + struct XDATA { uint8 restriction[4]; uint8 inuse[4]; - } *xdata = (struct XDATA*) responsedata; - - XDPRINTF((5,0, "Get vol restriction vol=%d, id=0x%lx", + } *xdata = (struct XDATA*) responsedata; + XDPRINTF((5,0, "Get vol restriction (DUMMY) vol=%d, id=0x%lx", (int)volnr, id)); - U32_TO_32(0x40000000, xdata->restriction); U32_TO_32(0x0, xdata->inuse); data_len=sizeof(struct XDATA); - } else if (*p == 0x2a){ - /* Get Eff. Rights of DIR's and Files ??*/ - struct XDATA { - uint8 eff_rights; /* Effektive Right to Dir */ - uint8 unkwown_data; /* 0x1 */ - } *xdata = (struct XDATA*) responsedata; - int result = nw_get_eff_dir_rights( - (int)*(p+1), - p+3, - (int)*(p+2), 1); - if (result > -1){ - xdata->eff_rights = (uint8)result; - xdata->unkwown_data = 0x1; - data_len = sizeof(struct XDATA); - } else completition = (uint8) (-result); - } else if (*p == 0x2c){ - /* Get Volume and Purge Information */ +#endif + } else if (*p == 0x2a){ + /* Get Eff. Rights of DIR's and Files ??*/ + struct XDATA { + uint8 eff_rights; /* Effektive Right to Dir */ + uint8 unkwown_data; /* 0x1 */ + } *xdata = (struct XDATA*) responsedata; + int result = nw_get_eff_dir_rights( + (int)*(p+1), + p+3, + (int)*(p+2), 1); + if (result > -1){ + xdata->eff_rights = (uint8)result; + xdata->unkwown_data = 0x1; + data_len = sizeof(struct XDATA); + } else completition = (uint8) (-result); + } else if (*p == 0x2c){ + /* Get Volume and Purge Information */ /* new Call since V3.11 */ /* ncpfs need this call */ int volume = (int) *(p+1); - struct XDATA { - uint8 total_blocks[4]; /* LOW-HI !! */ - uint8 avail_blocks[4]; - uint8 purgeable_blocks[4]; - uint8 not_purgeable_blocks[4]; - uint8 total_dirs[4]; - uint8 avail_dirs[4]; - uint8 reserved_by_novell[4]; - uint8 sec_per_block; + struct XDATA { + uint8 total_blocks[4]; /* LOW-HI !! */ + uint8 avail_blocks[4]; + uint8 purgeable_blocks[4]; + uint8 not_purgeable_blocks[4]; + uint8 total_dirs[4]; + uint8 avail_dirs[4]; + uint8 reserved_by_novell[4]; + uint8 sec_per_block; uint8 namlen; - uint8 name[1]; - } *xdata = (struct XDATA*) responsedata; + uint8 name[1]; + } *xdata = (struct XDATA*) responsedata; uint8 name[100]; - int result = nw_get_volume_name(volume, name); - if (result > -1){ + int result = nw_get_volume_name(volume, name); + if (result > -1){ struct fs_usage fsp; memset(xdata, 0, sizeof(struct XDATA)); if (!nw_get_fs_usage(name, &fsp)) { - xdata->sec_per_block = 8; /* hard coded */ - U32_TO_32(fsp.fsu_blocks/8, xdata->total_blocks); - U32_TO_32(fsp.fsu_bavail/8, xdata->avail_blocks); - U32_TO_32(fsp.fsu_files, xdata->total_dirs); - U32_TO_32(fsp.fsu_ffree, xdata->avail_dirs); + xdata->sec_per_block = 8; /* hard coded */ + U32_TO_32(fsp.fsu_blocks/8, xdata->total_blocks); + U32_TO_32(fsp.fsu_bavail/8, xdata->avail_blocks); + U32_TO_32(fsp.fsu_files, xdata->total_dirs); + U32_TO_32(fsp.fsu_ffree, xdata->avail_dirs); } xdata->namlen = strlen((char*)name); strmaxcpy(xdata->name, name, xdata->namlen); - data_len = xdata->namlen + 30; - } else completition = (uint8) -result; - } else if (*p == 0x2d){ - /* Get Direktory Information */ - int dir_handle = (int) *(p+1); - struct XDATA { - uint8 total_blocks[4]; - uint8 avail_blocks[4]; - uint8 total_dirs[4]; - uint8 avail_dirs[4]; - uint8 reserved_by_novell[4]; - uint8 sec_per_block; + data_len = xdata->namlen + 30; + } else completition = (uint8) -result; + } else if (*p == 0x2d){ + /* Get Direktory Information */ + int dir_handle = (int) *(p+1); + struct XDATA { + uint8 total_blocks[4]; + uint8 avail_blocks[4]; + uint8 total_dirs[4]; + uint8 avail_dirs[4]; + uint8 reserved_by_novell[4]; + uint8 sec_per_block; uint8 namlen; uint8 name[1]; /* Volume Name */ - } *xdata = (struct XDATA*) responsedata; - int result = nw_get_vol_number(dir_handle); - uint8 name[100]; - if (result > -1) - result = nw_get_volume_name(result, name); + } *xdata = (struct XDATA*) responsedata; + int result = nw_get_vol_number(dir_handle); + uint8 name[100]; + if (result > -1) + result = nw_get_volume_name(result, name); if (result > -1) { struct fs_usage fsp; memset(xdata, 0, sizeof(struct XDATA)); if (!nw_get_fs_usage(name, &fsp)) { - xdata->sec_per_block = 8; /* hard coded */ - U32_TO_32(fsp.fsu_blocks/8, xdata->total_blocks); - U32_TO_32(fsp.fsu_bavail/8, xdata->avail_blocks); - U32_TO_32(fsp.fsu_files, xdata->total_dirs); - U32_TO_32(fsp.fsu_ffree, xdata->avail_dirs); + xdata->sec_per_block = 8; /* hard coded */ + U32_TO_32(fsp.fsu_blocks/8, xdata->total_blocks); + U32_TO_32(fsp.fsu_bavail/8, xdata->avail_blocks); + U32_TO_32(fsp.fsu_files, xdata->total_dirs); + U32_TO_32(fsp.fsu_ffree, xdata->avail_dirs); } xdata->namlen = strlen((char*)name); strmaxcpy(xdata->name, name, xdata->namlen); - data_len = xdata->namlen + 22; + data_len = xdata->namlen + 22; } else completition = (uint8) -result; - } else if (*p == 0x2e){ /* RENAME DATEI */ - completition = 0xfb; /* TODO: !!! */ - } else if (*p == 0x2f){ /* ?????? */ - completition = 0xfb; /* TODO: !!! */ + } else if (*p == 0x2e){ /* RENAME DATEI */ + completition = 0xfb; /* TODO: !!! */ + } else if (*p == 0x2f){ /* ?????? */ + completition = 0xfb; /* TODO: !!! */ #if WITH_NAME_SPACE_CALLS - } else if (*p == 0x30){ - /* Get Name Space Directory Entry */ + } else if (*p == 0x30){ + /* Get Name Space Directory Entry */ int volume = (int) *(p+1); uint32 basehandle = GET_32(p+2); int namespace = (int) *(p+6); @@ -705,15 +702,15 @@ static int handle_ncp_serv(void) volume, basehandle, namespace, responsedata); if (result > -1) { - data_len = result; + data_len = result; } else completition = (uint8) -result; #endif - } else completition = 0xfb; /* unkwown request */ - } - break; - case 0x17 : { /* FILE SERVER ENVIRONMENT */ - /* uint8 len = *(requestdata+1); */ - uint8 ufunc = *(requestdata+2); + } else completition = 0xfb; /* unkwown request */ + } + break; + case 0x17 : { /* FILE SERVER ENVIRONMENT */ + /* uint8 len = *(requestdata+1); */ + uint8 ufunc = *(requestdata+2); #if DO_DEBUG uint8 *rdata = requestdata+3; #endif @@ -730,7 +727,7 @@ static int handle_ncp_serv(void) nw_debug = org_nw_debug = (int) *(rdata+1); data_len = 1; } else return(-1); - } + } break; #endif @@ -746,7 +743,7 @@ static int handle_ncp_serv(void) uint8 sequence[2]; /* z.B. 0xff, 0xff */ uint8 dir_handle; uint8 search_attrib; /* 0: NONE */ - /* 02: HIDDEN */ + /* 02: HIDDEN */ /* 04: SYSTEM */ /* 06: BOTH */ /* 0x10: DIR */ @@ -758,10 +755,10 @@ static int handle_ncp_serv(void) uint8 sequence[2]; /* next sequence */ /* NW_FILE_INFO f; */ uint8 f[sizeof(NW_FILE_INFO)]; - uint8 owner_id[4]; - uint8 archive_date[2]; - uint8 archive_time[2]; - uint8 reserved[56]; + uint8 owner_id[4]; + uint8 archive_date[2]; + uint8 archive_time[2]; + uint8 reserved[56]; } *xdata = (struct XDATA*)responsedata; int len = input->len; int searchsequence; @@ -795,7 +792,7 @@ static int handle_ncp_serv(void) uint8 reserved[56]; uint8 dir_handle; uint8 search_attrib; /* 0: NONE */ - /* 02: HIDDEN */ + /* 02: HIDDEN */ /* 04: SYSTEM */ /* 06: BOTH */ /* 0x10: DIR */ @@ -838,11 +835,11 @@ static int handle_ncp_serv(void) } /* case 0x17 */ break; - case 0x18 : /* End of Job */ + case 0x18 : /* End of Job */ nw_free_handles(ncprequest->task); break; - case 0x19 : /* logout, some of this call is handled in ncpserv. */ + case 0x19 : /* logout, some of this call is handled in ncpserv. */ nw_free_handles(-1); set_default_guid(); nw_setup_home_vol(-1, NULL); @@ -850,510 +847,510 @@ static int handle_ncp_serv(void) return(-1); /* nwbind must do a little rest */ break; - case 0x1a : /* lock file */ - case 0x1e : /* unlock file */ - { - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 reserve; /* 0x1 */ - uint8 ext_fhandle[2]; /* all zero */ - uint8 fhandle[4]; /* Filehandle */ - uint8 offset[4]; - uint8 size[4]; - uint8 weisnicht[2]; /* lock timeout ??? */ - } *input = (struct INPUT *)ncprequest; - int fhandle = GET_BE32 (input->fhandle); - int offset = GET_BE32(input->offset); - int size = GET_BE32(input->size); - completition = (uint8)(-nw_lock_datei(fhandle, - offset, size, - (int)(function == 0x1a))); - } - break; + case 0x1a : /* lock file */ + case 0x1e : /* unlock file */ + { + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 reserve; /* 0x1 */ + uint8 ext_fhandle[2]; /* all zero */ + uint8 fhandle[4]; /* Filehandle */ + uint8 offset[4]; + uint8 size[4]; + uint8 weisnicht[2]; /* lock timeout ??? */ + } *input = (struct INPUT *)ncprequest; + int fhandle = GET_BE32 (input->fhandle); + int offset = GET_BE32(input->offset); + int size = GET_BE32(input->size); + completition = (uint8)(-nw_lock_datei(fhandle, + offset, size, + (int)(function == 0x1a))); + } + break; - case 0x21 : { /* Negotiate Buffer Size, Packetsize */ - uint8 *getsize=responsedata; - rw_buffer_size = min(RW_BUFFERSIZE, + case 0x21 : { /* Negotiate Buffer Size, Packetsize */ + uint8 *getsize=responsedata; + rw_buffer_size = min(LOC_RW_BUFFERSIZE, (int) (GET_BE16((uint8*)requestdata))); - U16_TO_BE16(rw_buffer_size, getsize); - data_len = 2; + U16_TO_BE16(rw_buffer_size, getsize); + data_len = 2; XDPRINTF((2,0, "Negotiate Buffer size = 0x%04x,(%d)", (int) rw_buffer_size, (int) rw_buffer_size)); - } - break; + } + break; - case 0x22 : { /* div TTS Calls */ + case 0x22 : { /* div TTS Calls */ int ufunc = (int) *requestdata; if (!ufunc) completition=0; /* TTS not availible */ else completition=0xfb; /* request not known */ } break; #if 0 this was wrong, I think - case 0x3d : { /* commit file, flush file buffers */ + case 0x3d : { /* commit file, flush file buffers */ 0x3d seems to be no valid/used NCP call. #endif - case 0x3d : /* looks also like commit file */ + case 0x3d : /* looks also like commit file */ /* I make no errorresult here */ { #if 0 - XDPRINTF((2,0, "don't know function: 0x3d")); + XDPRINTF((2,0, "don't know function: 0x3d")); #else - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 reserve; - uint8 ext_fhandle[2]; /* all zero */ - uint8 fhandle[4]; /* filehandle */ - } *input = (struct INPUT *)ncprequest; + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 reserve; + uint8 ext_fhandle[2]; /* all zero */ + uint8 fhandle[4]; /* filehandle */ + } *input = (struct INPUT *)ncprequest; char fname[200]; - int fd = (int) GET_BE32(input->fhandle); + int fd = (int) GET_BE32(input->fhandle); int result=fd_2_fname(fd, fname, sizeof(fname)); - XDPRINTF((1,0, "0x3d, fd=%d, fn=`%s`, r=%d", - fd, fname, result)); + XDPRINTF((1,0, "0x3d, fd=%d, fn=`%s`, r=%d", + fd, fname, result)); #endif } break; - case 0x3b : + case 0x3b : #if DO_DEBUG - { /* commit file, flush file buffers */ - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 reserve; - uint8 ext_fhandle[2]; /* all zero */ - uint8 fhandle[4]; /* filehandle */ - } *input = (struct INPUT *)ncprequest; - uint32 fhandle = GET_BE32(input->fhandle); + { /* commit file, flush file buffers */ + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 reserve; + uint8 ext_fhandle[2]; /* all zero */ + uint8 fhandle[4]; /* filehandle */ + } *input = (struct INPUT *)ncprequest; + uint32 fhandle = GET_BE32(input->fhandle); XDPRINTF((5,0, "should be done some time: COMMIT FILE:fhandle=%ld", fhandle)); } #endif break; - case 0x3e : { /* FILE SEARCH INIT */ - /* returns dhandle for searchings */ - int dir_handle = (int)*requestdata; - int len = (int)*(requestdata+1); /* pathlen */ - uint8 *p = requestdata+2; /* path */ - struct XDATA { - uint8 volume; /* Volume */ - uint8 dir_id[2]; /* Direktory ID */ - uint8 searchsequenz[2]; - uint8 dir_rights; /* Rights */ - } *xdata= (struct XDATA*) responsedata; + case 0x3e : { /* FILE SEARCH INIT */ + /* returns dhandle for searchings */ + int dir_handle = (int)*requestdata; + int len = (int)*(requestdata+1); /* pathlen */ + uint8 *p = requestdata+2; /* path */ + struct XDATA { + uint8 volume; /* Volume */ + uint8 dir_id[2]; /* Direktory ID */ + uint8 searchsequenz[2]; + uint8 dir_rights; /* Rights */ + } *xdata= (struct XDATA*) responsedata; int volume; int searchsequenz; - int dir_id; - int rights = nw_open_dir_handle(dir_handle, p, len, - &volume, &dir_id, &searchsequenz); - if (rights >-1) { - xdata->volume = (uint8)volume; - U16_TO_BE16((uint16)dir_id, xdata->dir_id); - U16_TO_BE16((uint16)searchsequenz, xdata->searchsequenz); - xdata->dir_rights = (uint8)rights; - data_len = sizeof(struct XDATA); - } else completition = (uint8) -rights; - } break; + int dir_id; + int rights = nw_open_dir_handle(dir_handle, p, len, + &volume, &dir_id, &searchsequenz); + if (rights >-1) { + xdata->volume = (uint8)volume; + U16_TO_BE16((uint16)dir_id, xdata->dir_id); + U16_TO_BE16((uint16)searchsequenz, xdata->searchsequenz); + xdata->dir_rights = (uint8)rights; + data_len = sizeof(struct XDATA); + } else completition = (uint8) -rights; + } break; - case 0x3f : { /* file search continue */ - /* Dir_id is from file search init */ - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 volume; /* Volume ID */ + case 0x3f : { /* file search continue */ + /* Dir_id is from file search init */ + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 volume; /* Volume ID */ uint8 dir_id[2]; /* from File Search Init */ - uint8 searchsequence[2]; /* sequence FFFF = first entry */ - uint8 search_attrib; /* Attribute */ + uint8 searchsequence[2]; /* sequence FFFF = first entry */ + uint8 search_attrib; /* Attribute */ /* 0 none, 2 HIDDEN, * 4 System , 6 Both, * 0x10 Dir */ - uint8 len; /* fnname len */ - uint8 data[2]; /* fnname with wildcards */ - } *input = (struct INPUT *) ncprequest; - int len=input->len ; /* FN Length */ + uint8 len; /* fnname len */ + uint8 data[2]; /* fnname with wildcards */ + } *input = (struct INPUT *) ncprequest; + int len=input->len ; /* FN Length */ - struct XDATA { - uint8 searchsequence[2]; /* same as request sequence */ - uint8 dir_id[2]; /* Direktory ID */ + struct XDATA { + uint8 searchsequence[2]; /* same as request sequence */ + uint8 dir_id[2]; /* Direktory ID */ /* is correct !! */ - union { - NW_DIR_INFO d; - NW_FILE_INFO f; - } u; - } *xdata = (struct XDATA*)responsedata; + union { + NW_DIR_INFO d; + NW_FILE_INFO f; + } u; + } *xdata = (struct XDATA*)responsedata; - int searchsequence = nw_dir_search( - (uint8*) &(xdata->u), - (int) GET_BE16(input->dir_id), - (int) GET_BE16(input->searchsequence), - (int) input->search_attrib, - input->data, len); - if (searchsequence > -1) { - U16_TO_BE16((uint16) searchsequence, xdata->searchsequence); + int searchsequence = nw_dir_search( + (uint8*) &(xdata->u), + (int) GET_BE16(input->dir_id), + (int) GET_BE16(input->searchsequence), + (int) input->search_attrib, + input->data, len); + if (searchsequence > -1) { + U16_TO_BE16((uint16) searchsequence, xdata->searchsequence); memcpy(xdata->dir_id, input->dir_id, 2); - data_len = sizeof(struct XDATA); - } else completition = (uint8) (- searchsequence); - } - break; + data_len = sizeof(struct XDATA); + } else completition = (uint8) (- searchsequence); + } + break; - case 0x40 : /* Search for a File */ - { - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 sequenz[2]; /* z.B. 0xff, 0xff */ - uint8 dir_handle; /* z.B 0x1 */ - uint8 search_attrib; /* z.B. 0x6 */ - uint8 len; - uint8 data[2]; /* Name */ - } *input = (struct INPUT *)ncprequest; - struct XDATA { - uint8 sequenz[2]; /* answer sequence */ - uint8 reserved[2]; /* z.B 0x0 0x0 */ - union { - NW_DIR_INFO d; - NW_FILE_INFO f; - } u; - } *xdata = (struct XDATA*)responsedata; - int len = input->len; - uint8 my_sequenz[2]; - int searchsequence; + case 0x40 : /* Search for a File */ + { + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 sequenz[2]; /* z.B. 0xff, 0xff */ + uint8 dir_handle; /* z.B 0x1 */ + uint8 search_attrib; /* z.B. 0x6 */ + uint8 len; + uint8 data[2]; /* Name */ + } *input = (struct INPUT *)ncprequest; + struct XDATA { + uint8 sequenz[2]; /* answer sequence */ + uint8 reserved[2]; /* z.B 0x0 0x0 */ + union { + NW_DIR_INFO d; + NW_FILE_INFO f; + } u; + } *xdata = (struct XDATA*)responsedata; + int len = input->len; + uint8 my_sequenz[2]; + int searchsequence; uint32 owner; - memcpy(my_sequenz, input->sequenz, 2); - searchsequence = nw_search( (uint8*) &(xdata->u), + memcpy(my_sequenz, input->sequenz, 2); + searchsequence = nw_search( (uint8*) &(xdata->u), &owner, - (int)input->dir_handle, - (int) GET_BE16(my_sequenz), - (int) input->search_attrib, - input->data, len); - if (searchsequence > -1) { - U16_TO_BE16((uint16) searchsequence, xdata->sequenz); - data_len = sizeof(struct XDATA); - } else completition = (uint8) (- searchsequence); - } - break; + (int)input->dir_handle, + (int) GET_BE16(my_sequenz), + (int) input->search_attrib, + input->data, len); + if (searchsequence > -1) { + U16_TO_BE16((uint16) searchsequence, xdata->sequenz); + data_len = sizeof(struct XDATA); + } else completition = (uint8) (- searchsequence); + } + break; - case 0x41 : { /* open file for reading */ - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 dirhandle; /* Dirhandle */ - uint8 attrib; /* z.B. 0x6 od. 0x4e */ - /* O_RDWR|TRUNC 0x6, O_RDONLY 0x6 */ - uint8 len; /* namelaenge */ - uint8 data[2]; /* Name */ - } *input = (struct INPUT *)ncprequest; - struct XDATA { - uint8 ext_fhandle[2]; /* all zero */ - uint8 fhandle[4]; /* Dateihandle */ - uint8 reserve2[2]; /* z.B 0x0 0x0 */ - NW_FILE_INFO fileinfo; - } *xdata= (struct XDATA*)responsedata; - int fhandle=nw_creat_open_file((int)input->dirhandle, - input->data, input->len, - &(xdata->fileinfo), - (int)input->attrib, - 0x1, 0, (int)(ncprequest->task)); + case 0x41 : { /* open file for reading */ + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 dirhandle; /* Dirhandle */ + uint8 attrib; /* z.B. 0x6 od. 0x4e */ + /* O_RDWR|TRUNC 0x6, O_RDONLY 0x6 */ + uint8 len; /* namelaenge */ + uint8 data[2]; /* Name */ + } *input = (struct INPUT *)ncprequest; + struct XDATA { + uint8 ext_fhandle[2]; /* all zero */ + uint8 fhandle[4]; /* Dateihandle */ + uint8 reserve2[2]; /* z.B 0x0 0x0 */ + NW_FILE_INFO fileinfo; + } *xdata= (struct XDATA*)responsedata; + int fhandle=nw_creat_open_file((int)input->dirhandle, + input->data, input->len, + &(xdata->fileinfo), + (int)input->attrib, + 0x1, 0, (int)(ncprequest->task)); - if (fhandle > -1){ - U32_TO_BE32(fhandle, xdata->fhandle); - U16_TO_BE16(0, xdata->ext_fhandle); - U16_TO_BE16(0, xdata->reserve2); - data_len = sizeof(struct XDATA); - } else completition = (uint8) (-fhandle); - } - break; + if (fhandle > -1){ + U32_TO_BE32(fhandle, xdata->fhandle); + U16_TO_BE16(0, xdata->ext_fhandle); + U16_TO_BE16(0, xdata->reserve2); + data_len = sizeof(struct XDATA); + } else completition = (uint8) (-fhandle); + } + break; - case 0x42 : /* close file */ - { - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 reserve; - uint8 ext_fhandle[2]; /* all zero */ - uint8 fhandle[4]; /* filehandle */ - } *input = (struct INPUT *)ncprequest; - uint32 fhandle = GET_BE32(input->fhandle); - completition = (uint8)(-nw_close_datei(fhandle, 0)); - if (!completition && fhandle == test_handle) { - do_druck++; - test_handle = -1; - } - } - break; + case 0x42 : /* close file */ + { + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 reserve; + uint8 ext_fhandle[2]; /* all zero */ + uint8 fhandle[4]; /* filehandle */ + } *input = (struct INPUT *)ncprequest; + uint32 fhandle = GET_BE32(input->fhandle); + completition = (uint8)(-nw_close_datei(fhandle, 0)); + if (!completition && fhandle == test_handle) { + do_druck++; + test_handle = -1; + } + } + break; - case 0x43 : /* creat file, overwrite if exist */ + case 0x43 : /* creat file, overwrite if exist */ case 0x4D : /* create new file */ - { - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 dirhandle; - uint8 attribute; /* creat Attribute */ - uint8 len; - uint8 data[1]; /* Name */ - } *input = (struct INPUT *)ncprequest; - struct XDATA { - uint8 extfhandle[2]; - uint8 fhandle[4]; /* Filehandle */ - uint8 reserved[2]; /* rese. by NOVELL */ - NW_FILE_INFO fileinfo; - } *xdata= (struct XDATA*)responsedata; - int fhandle=nw_creat_open_file( - (int)input->dirhandle, - input->data, - (int)input->len, - &(xdata->fileinfo), - (int)input->attribute, + { + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 dirhandle; + uint8 attribute; /* creat Attribute */ + uint8 len; + uint8 data[1]; /* Name */ + } *input = (struct INPUT *)ncprequest; + struct XDATA { + uint8 extfhandle[2]; + uint8 fhandle[4]; /* Filehandle */ + uint8 reserved[2]; /* rese. by NOVELL */ + NW_FILE_INFO fileinfo; + } *xdata= (struct XDATA*)responsedata; + int fhandle=nw_creat_open_file( + (int)input->dirhandle, + input->data, + (int)input->len, + &(xdata->fileinfo), + (int)input->attribute, 0, (function==0x43) ? 1 : 2, (int)(ncprequest->task)); - if (fhandle > -1){ - data_len = sizeof(struct XDATA); - U32_TO_BE32(fhandle, xdata->fhandle); - U16_TO_BE16(0, xdata->extfhandle); - U16_TO_BE16(0, xdata->reserved); + if (fhandle > -1){ + data_len = sizeof(struct XDATA); + U32_TO_BE32(fhandle, xdata->fhandle); + U16_TO_BE16(0, xdata->extfhandle); + U16_TO_BE16(0, xdata->reserved); #ifdef TEST_FNAME - input->data[input->len] = '\0'; - if (strstr(input->data, TEST_FNAME)){ - test_handle = fhandle; - do_druck++; - } + input->data[input->len] = '\0'; + if (strstr(input->data, TEST_FNAME)){ + test_handle = fhandle; + do_druck++; + } #endif - } else completition = (uint8) (-fhandle); - } - break; + } else completition = (uint8) (-fhandle); + } + break; - case 0x44 : /* file(s) delete */ - { - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 dirhandle; /* 0x0 */ - uint8 searchattributes; + case 0x44 : /* file(s) delete */ + { + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 dirhandle; /* 0x0 */ + uint8 searchattributes; /* 0 none, 2 Hidden, 4 System, 6 Both */ - uint8 len; - uint8 data[2]; /* Name */ - } *input = (struct INPUT *)ncprequest; - int err_code = nw_delete_datei((int)input->dirhandle, - input->data, (int)input->len); - if (err_code < 0) - completition = (uint8) -err_code; - } - break; + uint8 len; + uint8 data[2]; /* Name */ + } *input = (struct INPUT *)ncprequest; + int err_code = nw_delete_datei((int)input->dirhandle, + input->data, (int)input->len); + if (err_code < 0) + completition = (uint8) -err_code; + } + break; - case 0x45 : /* rename file */ - { - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 dir_handle; /* ?? 0x1 */ - uint8 reserve1; /* z.B. 0x2 */ - uint8 len; - uint8 data[2]; /* Name */ - } *input = (struct INPUT *)ncprequest; - uint8 *p = input->data+input->len; /* reserve z.B. 0x1 */ - /* + 1 = len2 */ - /* + 1 = data2 */ - int errcode = mv_file( - (int)input->dir_handle, input->data,(int)input->len, - (int)input->dir_handle, p+2, (int)*(p+1) ); + case 0x45 : /* rename file */ + { + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 dir_handle; /* ?? 0x1 */ + uint8 reserve1; /* z.B. 0x2 */ + uint8 len; + uint8 data[2]; /* Name */ + } *input = (struct INPUT *)ncprequest; + uint8 *p = input->data+input->len; /* reserve z.B. 0x1 */ + /* + 1 = len2 */ + /* + 1 = data2 */ + int errcode = mv_file( + (int)input->dir_handle, input->data,(int)input->len, + (int)input->dir_handle, p+2, (int)*(p+1) ); - if (errcode < 0) completition = (uint8) -errcode; - } - break; + if (errcode < 0) completition = (uint8) -errcode; + } + break; - case 0x46 : /* set file attributes */ - { - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 access; /* 0x80, od 0x0 */ - /* 0x80 for example is shared */ - uint8 dir_handle; - uint8 attrib; /* search attrib */ - uint8 len; - uint8 data[2]; /* filename */ - } *input = (struct INPUT *)ncprequest; - completition = - (uint8) (-nw_chmod_datei((int)input->dir_handle, - input->data, (int)input->len, - (int)input->attrib, - (int)input->access)); - } - break; + case 0x46 : /* set file attributes */ + { + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 access; /* 0x80, od 0x0 */ + /* 0x80 for example is shared */ + uint8 dir_handle; + uint8 attrib; /* search attrib */ + uint8 len; + uint8 data[2]; /* filename */ + } *input = (struct INPUT *)ncprequest; + completition = + (uint8) (-nw_chmod_datei((int)input->dir_handle, + input->data, (int)input->len, + (int)input->attrib, + (int)input->access)); + } + break; - case 0x47 : /* move pointer to end of file ???? */ - /* and return filesize ? */ - { - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 filler; - uint8 ext_filehandle[2]; /* all zero */ - uint8 fhandle[4]; /* Dateihandle */ - } *input = (struct INPUT *)ncprequest; - struct XDATA { - uint8 size[4]; /* Position ??? */ - } *xdata=(struct XDATA*)responsedata; - int fhandle = GET_BE32(input->fhandle); - int size = nw_seek_datei(fhandle, 0); - if (size > -1) { - data_len = sizeof(struct XDATA); - U32_TO_BE32(size, xdata->size); - } - else completition = (uint8) -size; - } - break; + case 0x47 : /* move pointer to end of file ???? */ + /* and return filesize ? */ + { + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 filler; + uint8 ext_filehandle[2]; /* all zero */ + uint8 fhandle[4]; /* Dateihandle */ + } *input = (struct INPUT *)ncprequest; + struct XDATA { + uint8 size[4]; /* Position ??? */ + } *xdata=(struct XDATA*)responsedata; + int fhandle = GET_BE32(input->fhandle); + int size = nw_seek_datei(fhandle, 0); + if (size > -1) { + data_len = sizeof(struct XDATA); + U32_TO_BE32(size, xdata->size); + } + else completition = (uint8) -size; + } + break; - case 0x48 : /* read file */ - { - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 filler; - uint8 ext_fhandle[2]; /* all zero */ - uint8 fhandle[4]; /* filehandle */ - uint8 offset[4]; - uint8 max_size[2]; /* byte to readd */ - } *input = (struct INPUT *)ncprequest; - struct XDATA { - uint8 size[2]; /* read bytes */ - uint8 data[2]; /* read data */ - } *xdata=(struct XDATA*)responsedata; - int fhandle = GET_BE32(input->fhandle); - int max_size = GET_BE16(input->max_size); - off_t offset = GET_BE32(input->offset); - int zusatz = (offset & 1) ? 1 : 0; - int size; - if (max_size > rw_buffer_size) { + case 0x48 : /* read file */ + { + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 filler; + uint8 ext_fhandle[2]; /* all zero */ + uint8 fhandle[4]; /* filehandle */ + uint8 offset[4]; + uint8 max_size[2]; /* byte to readd */ + } *input = (struct INPUT *)ncprequest; + struct XDATA { + uint8 size[2]; /* read bytes */ + uint8 data[2]; /* read data */ + } *xdata=(struct XDATA*)responsedata; + int fhandle = GET_BE32(input->fhandle); + int max_size = GET_BE16(input->max_size); + off_t offset = GET_BE32(input->offset); + int zusatz = (offset & 1) ? 1 : 0; + int size; + if (max_size > rw_buffer_size) { XDPRINTF((1,0, "wanted read=%d byte > %d", max_size, rw_buffer_size)); size = -0x88; /* we say wrong filehandle */ } else - size = nw_read_datei(fhandle, - xdata->data+zusatz, - max_size, - offset); - if (size > -1) { - U16_TO_BE16(size, xdata->size); - data_len=size+zusatz+2; - } else completition = (uint8) -size; - } - break; + size = nw_read_datei(fhandle, + xdata->data+zusatz, + max_size, + offset); + if (size > -1) { + U16_TO_BE16(size, xdata->size); + data_len=size+zusatz+2; + } else completition = (uint8) -size; + } + break; - case 0x49 : { /* write file */ - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 filler; /* 0 Filler ?? */ - uint8 ext_handle[2]; - uint8 fhandle[4]; /* Dateihandle */ - uint8 offset[4]; /* SEEK OFFSET */ - uint8 size[2]; /* Datasize */ - uint8 data[2]; /* Schreibdaten */ - } *input = (struct INPUT *)ncprequest; - off_t offset = GET_BE32(input->offset); - int fhandle = GET_BE32(input->fhandle); - int input_size = GET_BE16(input->size); - int size = nw_write_datei(fhandle, - input->data, - input_size, - offset); - if (size < 0) - completition = (uint8) -size; - } - break; + case 0x49 : { /* write file */ + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 filler; /* 0 Filler ?? */ + uint8 ext_handle[2]; + uint8 fhandle[4]; /* Dateihandle */ + uint8 offset[4]; /* SEEK OFFSET */ + uint8 size[2]; /* Datasize */ + uint8 data[2]; /* Schreibdaten */ + } *input = (struct INPUT *)ncprequest; + off_t offset = GET_BE32(input->offset); + int fhandle = GET_BE32(input->fhandle); + int input_size = GET_BE16(input->size); + int size = nw_write_datei(fhandle, + input->data, + input_size, + offset); + if (size < 0) + completition = (uint8) -size; + } + break; - case 0x4a : { /* File SERVER COPY */ + case 0x4a : { /* File SERVER COPY */ /* should be OK */ - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 reserved; /* Reserved by Novell */ - uint8 qext_fhandle[2]; /* ext Filehandle */ - uint8 qfhandle[4]; /* Quellfile */ - uint8 zext_fhandle[2]; /* ext Filehandle */ - uint8 zfhandle[4]; /* Zielfile */ - uint8 qoffset[4]; /* SourceFile Offset */ - uint8 zoffset[4]; /* DestFile Offset */ - uint8 size[4]; /* copysize */ - } *input = (struct INPUT *)ncprequest; - int qfhandle = GET_BE32(input->qfhandle); - int zfhandle = GET_BE32(input->zfhandle); - off_t qoffset = GET_BE32(input->qoffset); - off_t zoffset = GET_BE32(input->zoffset); - uint32 input_size = GET_BE32(input->size); - int size = nw_server_copy(qfhandle, qoffset, - zfhandle, zoffset, - input_size); - if (size < 0) completition = (uint8) -size; - else { - struct XDATA { - uint8 zsize[4]; /* real transfered Bytes */ - } *xdata= (struct XDATA*)responsedata; - U32_TO_BE32(size, xdata->zsize); - data_len = sizeof(struct XDATA); - } - } - break; + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 reserved; /* Reserved by Novell */ + uint8 qext_fhandle[2]; /* ext Filehandle */ + uint8 qfhandle[4]; /* Quellfile */ + uint8 zext_fhandle[2]; /* ext Filehandle */ + uint8 zfhandle[4]; /* Zielfile */ + uint8 qoffset[4]; /* SourceFile Offset */ + uint8 zoffset[4]; /* DestFile Offset */ + uint8 size[4]; /* copysize */ + } *input = (struct INPUT *)ncprequest; + int qfhandle = GET_BE32(input->qfhandle); + int zfhandle = GET_BE32(input->zfhandle); + off_t qoffset = GET_BE32(input->qoffset); + off_t zoffset = GET_BE32(input->zoffset); + uint32 input_size = GET_BE32(input->size); + int size = nw_server_copy(qfhandle, qoffset, + zfhandle, zoffset, + input_size); + if (size < 0) completition = (uint8) -size; + else { + struct XDATA { + uint8 zsize[4]; /* real transfered Bytes */ + } *xdata= (struct XDATA*)responsedata; + U32_TO_BE32(size, xdata->zsize); + data_len = sizeof(struct XDATA); + } + } + break; - case 0x4b : { /* set date of file, file will be closed later */ - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 filler; - uint8 reserve[2]; /* ext Filehandle */ - uint8 fhandle[4]; /* Dateihandle */ - uint8 zeit[2]; /* time */ - uint8 datum[2]; /* date */ - } *input = (struct INPUT *)ncprequest; - int result = nw_set_fdate_time(GET_BE32(input->fhandle), - input->datum, input->zeit); - if (result <0) completition = (uint8) -result; - } - break; + case 0x4b : { /* set date of file, file will be closed later */ + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 filler; + uint8 reserve[2]; /* ext Filehandle */ + uint8 fhandle[4]; /* Dateihandle */ + uint8 zeit[2]; /* time */ + uint8 datum[2]; /* date */ + } *input = (struct INPUT *)ncprequest; + int result = nw_set_fdate_time(GET_BE32(input->fhandle), + input->datum, input->zeit); + if (result <0) completition = (uint8) -result; + } + break; - case 0x4c : { /* open file */ - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 dirhandle; /* Dirhandle */ - uint8 attrib; /* z.B. 0x6 od. 0x4e */ - /* O_RDWR|TRUNC 0x6, O_RDONLY 0x6 */ + case 0x4c : { /* open file */ + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 dirhandle; /* Dirhandle */ + uint8 attrib; /* z.B. 0x6 od. 0x4e */ + /* O_RDWR|TRUNC 0x6, O_RDONLY 0x6 */ - uint8 access; /* z.B. 0x9 od 0x11 od. 0x13 */ - /* O_RDWR|TRUNC 0x13, O_RDONLY 0x11 */ - /* O_RDWR|TRUNC|O_DENYNONE 0x3 */ - /* 0x10 BINAERMODUS ?? */ - /* 0x02 do write */ - uint8 len; /* namelaenge */ - uint8 data[2]; /* Name */ - } *input = (struct INPUT *)ncprequest; - struct XDATA { - uint8 ext_fhandle[2]; /* all zero */ - uint8 fhandle[4]; /* Dateihandle */ - uint8 reserve2[2]; /* z.B 0x0 0x0 */ - NW_FILE_INFO fileinfo; - } *xdata= (struct XDATA*)responsedata; - int fhandle=nw_creat_open_file((int)input->dirhandle, - input->data, input->len, - &(xdata->fileinfo), - (int)input->attrib, - (int)input->access, 0, - (int)(ncprequest->task)); + uint8 access; /* z.B. 0x9 od 0x11 od. 0x13 */ + /* O_RDWR|TRUNC 0x13, O_RDONLY 0x11 */ + /* O_RDWR|TRUNC|O_DENYNONE 0x3 */ + /* 0x10 BINAERMODUS ?? */ + /* 0x02 do write */ + uint8 len; /* namelaenge */ + uint8 data[2]; /* Name */ + } *input = (struct INPUT *)ncprequest; + struct XDATA { + uint8 ext_fhandle[2]; /* all zero */ + uint8 fhandle[4]; /* Dateihandle */ + uint8 reserve2[2]; /* z.B 0x0 0x0 */ + NW_FILE_INFO fileinfo; + } *xdata= (struct XDATA*)responsedata; + int fhandle=nw_creat_open_file((int)input->dirhandle, + input->data, input->len, + &(xdata->fileinfo), + (int)input->attrib, + (int)input->access, 0, + (int)(ncprequest->task)); - if (fhandle > -1){ - U32_TO_BE32(fhandle, xdata->fhandle); - U16_TO_BE16(0, xdata->ext_fhandle); - U16_TO_BE16(0, xdata->reserve2); + if (fhandle > -1){ + U32_TO_BE32(fhandle, xdata->fhandle); + U16_TO_BE16(0, xdata->ext_fhandle); + U16_TO_BE16(0, xdata->reserve2); - data_len = sizeof(struct XDATA); + data_len = sizeof(struct XDATA); #ifdef TEST_FNAME - input->data[input->len] = '\0'; - if (strstr(input->data, TEST_FNAME)){ - test_handle = fhandle; - do_druck++; - } + input->data[input->len] = '\0'; + if (strstr(input->data, TEST_FNAME)){ + test_handle = fhandle; + do_druck++; + } #endif - } else completition = (uint8) (-fhandle); - } - break; + } else completition = (uint8) (-fhandle); + } + break; #if WITH_NAME_SPACE_CALLS - case 0x56 : /* some extended atrribute calls */ + case 0x56 : /* some extended atrribute calls */ { int result = handle_func_0x56(requestdata, responsedata, ncprequest->task); if (result > -1) data_len = result; @@ -1361,7 +1358,7 @@ static int handle_ncp_serv(void) } break; - case 0x57 : /* some new namespace calls */ + case 0x57 : /* some new namespace calls */ { int result = handle_func_0x57(requestdata, responsedata, ncprequest->task); if (result > -1) data_len = result; @@ -1371,79 +1368,79 @@ static int handle_ncp_serv(void) #endif #ifdef _MAR_TESTS_XX - case 0x5f : { /* ????????????? UNIX Client */ + case 0x5f : { /* ????????????? UNIX Client */ /* a 4.1 Server also do not know this call */ - struct INPUT { - uint8 header[7]; /* Requestheader */ + struct INPUT { + uint8 header[7]; /* Requestheader */ uint8 unknown[4]; /* 0x10, 0,0,0 */ - } *input = (struct INPUT *)ncprequest; - completition = 0; + } *input = (struct INPUT *)ncprequest; + completition = 0; } break; #endif #if 0 - case 0x61 : { /* Negotiate Buffer Size, Packetsize new ? */ + case 0x61 : { /* Negotiate Buffer Size, Packetsize new ? */ /* > 3.11 */ - int wantsize = GET_BE16((uint8*)requestdata); + int wantsize = GET_BE16((uint8*)requestdata); int flags = (int) *(requestdata+2); /* wantsize is here normally 1500 */ - struct XDATA { - uint8 getsize[2]; - uint8 socket[2]; /* echo socket */ + struct XDATA { + uint8 getsize[2]; + uint8 socket[2]; /* echo socket */ uint8 flags; /* zero */ - } *xdata= (struct XDATA*)responsedata; + } *xdata= (struct XDATA*)responsedata; memset(xdata, 0, sizeof(*xdata)); - wantsize = min(1500, wantsize); - U16_TO_BE16(wantsize, xdata->getsize); - U16_TO_BE16(sock_echo, xdata->socket); - data_len = sizeof(*xdata); + wantsize = min(1500, wantsize); + U16_TO_BE16(wantsize, xdata->getsize); + U16_TO_BE16(sock_echo, xdata->socket); + data_len = sizeof(*xdata); XDPRINTF((5,0, "Negotiate Buffer (new) =0x%04x,(%d), flags=0x%x", (int) wantsize, (int) wantsize, flags)); - } - break; + } + break; #else - case 0x61 : /* Negotiate Buffer Size, Packetsize new ? */ - XDPRINTF((2,0, "Function '0x61' not supportet")); - completition = 0xfb; /* unknown request */ + case 0x61 : /* Negotiate Buffer Size, Packetsize new ? */ + XDPRINTF((2,0, "Function '0x61' not supportet")); + completition = 0xfb; /* unknown request */ nw_debug=0; break; #endif #if 0 - case 0x65 : /* Packet Burst Connection Request */ - struct INPUT { - uint8 header[7]; /* Requestheader */ + case 0x65 : /* Packet Burst Connection Request */ + struct INPUT { + uint8 header[7]; /* Requestheader */ uint8 conn_id[4]; /* ?? */ uint8 max_packet_size[4]; /* HI-LOW */ uint8 target_socket[2]; uint8 max_sent_size[4]; /* HI-LOW */ uint8 max_recv_size[4]; /* HI-LOW */ - } *input = (struct INPUT *)ncprequest; - struct XDATA { - uint8 result; - uint8 target_id[4]; - uint8 max_packet_size[4]; - } *xdata= (struct XDATA*) responsedata; - break; + } *input = (struct INPUT *)ncprequest; + struct XDATA { + uint8 result; + uint8 target_id[4]; + uint8 max_packet_size[4]; + } *xdata= (struct XDATA*) responsedata; + break; #else - case 0x65 : - XDPRINTF((2,0, "Packet Burst Connection Request not yet supportet")); + case 0x65 : + XDPRINTF((2,0, "Packet Burst Connection Request not yet supportet")); nw_debug=0; - completition = 0xfb; /* unknown request */ - break; + completition = 0xfb; /* unknown request */ + break; #endif - case 0x68 : /* NDS NCP, NDS Fragger Protokoll ?? */ - XDPRINTF((2,0, "NDS Fragger Protokoll not supportet")); + case 0x68 : /* NDS NCP, NDS Fragger Protokoll ?? */ + XDPRINTF((2,0, "NDS Fragger Protokoll not supportet")); nw_debug=0; - completition = 0xfb; /* unknown request */ - break; + completition = 0xfb; /* unknown request */ + break; - default : completition = 0xfb; /* unknown request */ - break; + default : completition = 0xfb; /* unknown request */ + break; } /* switch function */ } else if (ncp_type == 0x1111) { @@ -1463,9 +1460,9 @@ static int handle_ncp_serv(void) uint8 *p = responsedata; XDPRINTF((0,2, "RSPONSE: len %d, DATA:", data_len)); while (j--) { - int c = *p++; - if (c > 32 && c < 127) XDPRINTF((0,3,",\'%c\'", (char) c)); - else XDPRINTF((0,3,",0x%x", c)); + int c = *p++; + if (c > 32 && c < 127) XDPRINTF((0,3,",\'%c\'", (char) c)); + else XDPRINTF((0,3,",0x%x", c)); } XDPRINTF((0,1, NULL)); } @@ -1483,6 +1480,84 @@ static void handle_after_bind() int data_len = 0; int completition = 0; switch (ncprequest->function) { + /* QUOTA support from: Matt Paley */ + case 0x16 : { + uint8 ufunc = *(requestdata+2); + switch (ufunc) { + case 0x21: { + /* change Vol restrictions for Obj */ + uint8 volnr = *(requestdata+3); + uint32 id = GET_BE32(requestdata+4); + uint32 blocks = GET_32(requestdata+8); + int gid = ((int *) bindresponse)[0]; + int uid = ((int *) bindresponse)[1]; + int perm = ((int *) bindresponse)[2]; + int result; + XDPRINTF((5, 0, + "Change vol rest id=%x vol=%d blocks=%d gid=%d uid=%d p=%d", + (int) id, (int) volnr, (int) blocks, + (int) gid, (int) uid, (int) perm)); + if (perm == 0) { + result = nw_set_vol_restrictions(volnr, uid, blocks); + } else { + result = -0x85; + } + if (result < 0) completition = (uint8)-result; + } + break; + case 0x22: { + /* Remove Vol restrictions for Obj */ + uint8 volnr = *(requestdata+3); + uint32 id = GET_BE32(requestdata+4); + int gid = ((int *) bindresponse)[0]; + int uid = ((int *) bindresponse)[1]; + int perm = ((int *) bindresponse)[2]; + int result; + XDPRINTF((1, 0, "Remove vol rest id=%x vol=%d gid=%d uid=%d p=%d", + (int) id, (int) volnr, (int) gid, (int) uid, (int) perm)); + if (perm == 0) { + result = nw_set_vol_restrictions(volnr, uid, 0); + } else { + result = -0x85; + } + if (result < 0) completition = (uint8)-result; + } + break; + case 0x29: { + /* Get Vol restrictions for Obj */ + uint8 volnr = *(requestdata+3); + uint32 id = GET_BE32(requestdata+4); + int gid = ((int *) bindresponse)[0]; + int uid = ((int *) bindresponse)[1]; + int perm = ((int *) bindresponse)[2]; + uint32 quota, used; + int result; + struct XDATA { + uint8 restriction[4]; + uint8 inuse[4]; + } *xdata = (struct XDATA*) responsedata; + XDPRINTF((5, 0, "Get vol rest id=%x vol=%d gid=%d uid=%d p=%d", + (int) id, (int) volnr, (int) gid, (int) uid, (int) perm)); + if (perm == 0) { + result = nw_get_vol_restrictions(volnr, uid, "a, &used); + } else { + result = -0x85; + } + data_len = 8; + if (result == 0) { + U32_TO_32(quota, xdata->restriction); + U32_TO_32(used, xdata->inuse); + } else { + U32_TO_32(0x40000000, xdata->restriction); + U32_TO_32(0x0, xdata->inuse); + completition = (uint8) -result; + } + } + break; + default : completition = 0xfb; + } + break; + } case 0x17 : { /* FILE SERVER ENVIRONMENT */ uint8 ufunc = *(requestdata+2); switch (ufunc) { @@ -1687,7 +1762,7 @@ int main(int argc, char **argv) } else { /* OK for direct sending */ XDPRINTF((6,0, "NWCONN:direct sending:type 0x3333, completition=0x%x, len=%d", - (int)(ncprequest->function), data_len)); + (int)(ncprequest->function), data_len)); if (data_len) memcpy(responsedata, readbuff+sizeof(NCPRESPONSE), data_len); ncpresponse->connect_status = ((NCPRESPONSE*)readbuff)->connect_status; diff --git a/nwdbm.c b/nwdbm.c index 63151d6..1f541f5 100644 --- a/nwdbm.c +++ b/nwdbm.c @@ -1,4 +1,4 @@ -/* nwdbm.c 19-Dec-96 data base for mars_nwe */ +/* nwdbm.c 20-Jan-97 data base for mars_nwe */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -41,13 +41,16 @@ #define DBM_REMAINS_OPEN 1 -int tells_server_version=0; +int tells_server_version=1; /* default 1 since 12-Jan-97 */ int password_scheme=0; /* PW_SCHEME_CHANGE_PW; */ +static int entry8_flags = 0; + static datum key; static datum data; static DBM *my_dbm=NULL; + #define FNPROP 0 #define FNVAL 1 #define FNOBJ 2 @@ -1341,7 +1344,33 @@ int nw_keychange_passwd(uint32 obj_id, uint8 *cryptkey, uint8 *oldpass, return(memcmp(newpass, storedpass, 16) ? 0 : 1); } -int nw_test_adr_access(uint32 obj_id, ipxAddr_t *client_adr) +static int nw_test_time_access(uint32 obj_id) +/* Routine from Matt Paley */ +{ + time_t t; + struct tm *tm; + uint8 more_segments; + uint8 property_flags; + char *propname="LOGIN_CONTROL"; + uint8 buff[200]; + int segment = 1; + int half_hours; + int result=nw_get_prop_val_by_obj_id(obj_id, segment, + propname, strlen(propname), + buff, &more_segments, &property_flags); + if (result < 0) + return(0); /* No time limits available */ + time(&t); + tm = localtime(&t); + half_hours = tm->tm_wday*48 + tm->tm_hour*2 + ((tm->tm_min>=30)? 1 : 0); + if ((buff[14+(half_hours/8)] & (1<<(half_hours % 8))) != 0) + return(0); + XDPRINTF((1, 0, "No access for user %x at day %d %02d:%02d", + obj_id, tm->tm_wday, tm->tm_hour, tm->tm_min)); + return(-0xda); /* unauthorized login time */ +} + +static int nw_test_adr_access(uint32 obj_id, ipxAddr_t *client_adr) { uint8 more_segments; uint8 property_flags; @@ -1365,10 +1394,22 @@ int nw_test_adr_access(uint32 obj_id, ipxAddr_t *client_adr) p+=10; } } - XDPRINTF((1, 0, "No access for Station %s", visable_ipx_adr(client_adr))); + XDPRINTF((1, 0, "No access for user %x at Station %s", + obj_id, visable_ipx_adr(client_adr))); return(-0xdb); /* unauthorized login station */ } +int nw_test_adr_time_access(uint32 obj_id, ipxAddr_t *client_adr) +{ + int result; + if (obj_id==1 && (entry8_flags & 8)) + return(0); /* no limits for SU */ + result=nw_test_adr_access(obj_id, client_adr); + if (!result) + result=nw_test_time_access(obj_id); + return(result); +} + #if 0 int prop_add_new_member(uint32 obj_id, int prop_id, uint32 member_id) /* add member to set, if member not in set */ @@ -1632,6 +1673,9 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) default : password_scheme = 0; break; } /* switch */ + + } else if (8 == what) { /* entry8_flags */ + entry8_flags = hextoi((char*)buff); } else if (21 == what) { /* QUEUES */ char name[100]; char directory[200]; diff --git a/nwdbm.h b/nwdbm.h index 68d3c59..df5e474 100644 --- a/nwdbm.h +++ b/nwdbm.h @@ -1,4 +1,4 @@ -/* nwdbm.h 18-Dec-96 */ +/* nwdbm.h 20-Jan-97 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -192,7 +192,7 @@ extern int nw_keychange_passwd(uint32 obj_id, int cryptedlen, uint8 *newpass, uint32 act_id); -extern int nw_test_adr_access(uint32 obj_id, ipxAddr_t *client_adr); +extern int nw_test_adr_time_access(uint32 obj_id, ipxAddr_t *client_adr); extern int nw_get_q_dirname(uint32 q_id, uint8 *buff); extern int nw_get_q_prcommand(uint32 q_id, uint8 *buff); diff --git a/nwfile.c b/nwfile.c index db4b087..d8c7679 100644 --- a/nwfile.c +++ b/nwfile.c @@ -1,4 +1,4 @@ -/* nwfile.c 31-Dec-96 */ +/* nwfile.c 14-Jan-97 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -683,9 +683,15 @@ int nw_server_copy(int qfhandle, uint32 qoffset, return(-0x88); /* wrong filehandle */ } - int nw_lock_datei(int fhandle, int offset, int size, int do_lock) { + MDEBUG(D_FH_LOCK, { + char fname[200]; + int r=fd_2_fname(fhandle, fname, sizeof(fname)); + dprintf("nw_%s_datei: fd=%d, fn=`%s`,r=%d,offs=%d,len=%d", + (do_lock) ? "lock" : "unlock", + fhandle, fname,r,offset, size); + }) if (fhandle > HOFFS && (--fhandle < anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fd > -1) { diff --git a/nwqueue.c b/nwqueue.c index 54a88f6..eec4217 100644 --- a/nwqueue.c +++ b/nwqueue.c @@ -383,12 +383,24 @@ int nw_close_file_queue(uint8 *queue_id, INT_QUEUE_JOB *jo=queue_jobs[jo_id-1]; int fhandle = (int)jo->fhandle; char unixname[300]; + QUEUE_PRINT_AREA qpa; + if (jo->old_job) { + memcpy(&qpa, jo->q.o.client_area, sizeof(QUEUE_PRINT_AREA)); + } else { + memcpy(&qpa, jo->q.n.client_area, sizeof(QUEUE_PRINT_AREA)); + } strmaxcpy((uint8*)unixname, (uint8*)file_get_unix_name(fhandle), sizeof(unixname)-1); XDPRINTF((5,0,"nw_close_file_queue fhandle=%d", fhandle)); if (*unixname) { - char printcommand[256]; + char buff[1024]; + char printcommand[300]; FILE *f=NULL; - strmaxcpy((uint8*)printcommand, prc, prc_len); + if (prc_len && *(prc+prc_len-1)=='!'){ + strmaxcpy((uint8*)buff, prc, prc_len-1); + sprintf(printcommand, "%s %s %s", buff, + qpa.banner_user_name, qpa.banner_file_name); + } else + strmaxcpy((uint8*)printcommand, prc, prc_len); nw_close_datei(fhandle, 1); jo->fhandle = 0L; if (NULL == (f = fopen(unixname, "r"))) { @@ -401,7 +413,6 @@ int nw_close_file_queue(uint8 *queue_id, int is_ok = 0; FILE_PIPE *fp = ext_popen(printcommand, geteuid(), getegid()); if (fp) { - char buff[1024]; int k; is_ok++; while ((k = fread(buff, 1, sizeof(buff), f)) > 0) { diff --git a/nwqueue.h b/nwqueue.h index bf63b05..5a72371 100644 --- a/nwqueue.h +++ b/nwqueue.h @@ -79,8 +79,8 @@ typedef struct { uint8 form_name[16]; /* "UNKNOWN" */ uint8 reserved[6]; /* all zero */ uint8 banner_user_name[13]; /* "SUPERVISOR" */ - uint8 bannner_file_name[13]; /* "LST:" */ - uint8 bannner_header_file_name[14]; /* all zero */ + uint8 banner_file_name[13]; /* "LST:" */ + uint8 banner_header_file_name[14]; /* all zero */ uint8 file_path_name[80]; /* all zero */ } QUEUE_PRINT_AREA; diff --git a/nwvolume.c b/nwvolume.c index 33ea0f7..9e4fd44 100644 --- a/nwvolume.c +++ b/nwvolume.c @@ -1,4 +1,4 @@ -/* nwvolume.c 07-Nov-96 */ +/* nwvolume.c 01-Feb-97 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -19,6 +19,7 @@ #include "net.h" #include +#include #include #ifndef LINUX @@ -39,6 +40,7 @@ static void volume_to_namespace_map(int volume, NW_VOL *vol) DEV_NAMESPACE_MAP dnm; if (stat(vol->unixname, &statb)) { XDPRINTF((1, 0, "cannot stat vol=%d, `%s`", volume, vol->unixname)); + return; } dnm.dev = statb.st_dev; dnm.namespace = 0; /* NAMESPACE DOS */ @@ -162,7 +164,7 @@ void nw_setup_home_vol(int len, uint8 *fn) nw_volumes[k].maps_count = 0; nw_volumes[k].unixnamlen = len; new_str(nw_volumes[k].unixname, unixname); - if (len) + if (len>0) volume_to_namespace_map(k, &(nw_volumes[k])); } } @@ -277,7 +279,7 @@ int nw_get_volume_name(int volnr, uint8 *volname) } -/* next is stolen from GNU-fileutils */ +/* stolen from GNU-fileutils */ static long adjust_blocks (long blocks, int fromsize, int tosize) { if (fromsize == tosize) /* E.g., from 512 to 512. */ @@ -366,3 +368,170 @@ int get_volume_inode(int volnr, struct stat *stb) return(result); } + +#if QUOTA_SUPPORT + +/* QUOTA support from: Matt Paley */ + +#include +#include +#include + +/* Return the device special file that the specified path uses */ +const char *find_device_file(const char *path) +{ + struct stat s; + dev_t dev; + struct mntent *mntent; + FILE *fp; + const char *mount_device; + + if (path == (char *) NULL || *path == '\0' || stat(path, &s) != 0) + return((char *) NULL); + dev = s.st_dev; + if ((fp=setmntent(MOUNTED, "r")) == (FILE *) NULL) + return((char *) NULL); + mount_device = (char *) NULL; + while (!ferror(fp)) { + /* mntent will be a static struct mntent */ + mntent = getmntent(fp); + if (mntent == (struct mntent *) NULL) + break; + if (stat(mntent->mnt_fsname, &s) == 0) { + if (S_ISCHR(s.st_mode) || S_ISBLK(s.st_mode)) { + if (s.st_rdev == dev) { + /* Found it */ + mount_device = mntent->mnt_fsname; + break; + } + } + } + } + endmntent(fp); + return(mount_device); +} + +#include +#include + +#ifdef LINUX +# include +# if defined(__alpha__) +# include +# include +# include +int quotactl(int cmd, const char * special, int id, caddr_t addr) +{ + return syscall(__NR_quotactl, cmd, special, id, addr); +} +# else /* not __alpha__ */ +# define __LIBRARY__ +# include +_syscall4(int, quotactl, int, cmd, const char *, special, + int, id, caddr_t, addr); +# endif /* __alpha__ */ +#endif /* LINUX */ + +static int su_quotactl(int cmd, const char * special, int id, caddr_t addr) +{ + int result; + int euid=geteuid(); + seteuid(0); + result=quotactl(cmd, special, id, addr); + if (seteuid(euid)) { + errorp(1, "seteuid", "cannot change to uid=%d\n", euid); + exit(1); + } + return(result); +} + + +/* NOTE: The error numbers in here are probably wrong */ +int nw_set_vol_restrictions(uint8 volnr, int uid, uint32 quota) +{ + const char *device; + struct dqblk dqblk; + int res; + + XDPRINTF((2,0, "nw_set_vol_restrictions vol=%d uid=%d quota=%d blocks", + volnr, uid, quota)); + + /* Convert from blocks to K */ + quota *= 4; + + if (volnr >= used_nw_volumes || nw_volumes == (NW_VOL *) NULL) + return(-0x98); + device=find_device_file(nw_volumes[volnr].unixname); + if (device == (char *) NULL) + return(-0x98); + + /* If this call fails then it it probable that quotas are not enabled + * on the specified device. Someone needs to set the error number + * to whatever will make most sense to netware. + */ + res=su_quotactl(QCMD(Q_GETQUOTA, USRQUOTA), device, uid, (caddr_t) &dqblk); + + if (res != 0) + return(0); + dqblk.dqb_bhardlimit = quota; + dqblk.dqb_bsoftlimit = quota; + if (quota == 0) + dqblk.dqb_ihardlimit = dqblk.dqb_isoftlimit = 0; + XDPRINTF((2,0, "Set quota device=%s uid=%d %d(%d)K %d(%d) files", + device, uid, + dqblk.dqb_bhardlimit, + dqblk.dqb_curblocks, + dqblk.dqb_ihardlimit, + dqblk.dqb_curinodes)); + + (void)su_quotactl(QCMD(Q_SETQLIM, USRQUOTA), device, uid, (caddr_t) &dqblk); + + + + return(0); +} + +int nw_get_vol_restrictions(uint8 volnr, int uid, uint32 *quota, uint32 *inuse) +{ + const char *device; + struct dqblk dqblk; + int res; + *quota = 0x40000000; + *inuse = 0; + if (volnr >= used_nw_volumes || nw_volumes == (NW_VOL *) NULL) + return(-0x98); + + device=find_device_file(nw_volumes[volnr].unixname); + if (device == (char *) NULL) + return(-0x98); + + XDPRINTF((2,0, "Get quota for uid %d on device %s", + uid, device)); + + res=su_quotactl(QCMD(Q_GETQUOTA, USRQUOTA), device, uid, (caddr_t) &dqblk); + + if (res != 0) + return(0); /* Quotas are probably not enabled */ + if (dqblk.dqb_bhardlimit == 0) { + *quota = 0x40000000; + *inuse = 0; + } else { + *quota = dqblk.dqb_bhardlimit / 4; /* Convert from K to blocks */ + *inuse = dqblk.dqb_curblocks / 4; + } + return(0); +} + +#else +int nw_set_vol_restrictions(uint8 volnr, int uid, uint32 quota) +{ + return(-0xfb); +} + +int nw_get_vol_restrictions(uint8 volnr, int uid, uint32 *quota, uint32 *inuse) +{ + *quota = 0x40000000; + *inuse = 0; + return(0); +} +#endif diff --git a/nwvolume.h b/nwvolume.h index 1a858e1..67cd66f 100644 --- a/nwvolume.h +++ b/nwvolume.h @@ -1,4 +1,4 @@ -/* nwvolume.h 27-Jul-96 */ +/* nwvolume.h 17-Jan-97 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -76,7 +76,9 @@ extern int nw_get_volume_number(uint8 *volname, int namelen); extern int nw_get_volume_name(int volnr, uint8 *volname); extern int nw_get_fs_usage(uint8 *volname, struct fs_usage *fsu); extern int get_volume_options(int volnr, int mode); -extern int get_volume_inode(int volnr, struct stat *stb); +extern int get_volume_inode(int volnr, struct stat *stb); +extern int nw_set_vol_restrictions(uint8 volnr, int uid, uint32 quota); +extern int nw_get_vol_restrictions(uint8 volnr, int uid, uint32 *quota, uint32 *inuse); extern uint32 nw_vol_inode_to_handle(int volume, ino_t inode, DEV_NAMESPACE_MAP *dnm);