diff --git a/Makefile b/Makefile index ba12b4a..6cf2cbf 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ all: rmeflag mk.li config.h nw.ini echo ""; \ echo "********************************************************" ; \ echo ""; \ - cat .mk.notes; rm .mk.notes ; \ + cat .mk.notes; rm -f .mk.notes ; \ echo ""; \ echo "********************************************************" ; \ echo ""; echo "" ; fi ) fi @@ -41,6 +41,8 @@ install_ini: nw.ini clean: mk.li nw.ini ./mk.li $@ + rm -f .mk.notes + rm -f .eflag distrib: mk.li nw.ini ./mk.li $@ @@ -84,6 +86,7 @@ rmeflag: @- rm -f .eflag nw.ini: examples/nw.ini + @rm -f .mk.notes @if [ -r $@ ] ; then echo "NOTE:examples/$@ is newer then $@" > .mk.notes ; \ echo "please compare examples/$@ with $@" >> .mk.notes; \ echo "make the changes you need and touch $@" >> .mk.notes; \ diff --git a/README b/README index a9be0a6..cff6f97 100644 --- a/README +++ b/README @@ -1,29 +1,100 @@ This is Mars_nwe, a free NetWare(tm) emulator for Linux and UnixWare, written by Martin Stover, Marburg, Germany. +>>>> Please read THE WHOLE of this file as it gives important +>>>> information about mars_nwe, how you can get help and so on. + +This software is freely distributable under the GNU public license, a +copy of which you should have received with this software (in a file +called COPYING). + + +WHAT CAN MARS_NWE DO? +===================== + +Here is a very short list of what mars_nwe can do for you. + +- mars_nwe is a very functional clone of a NetWare server that runs + under Linux. It works fine with the usual DOS client software that + normally comes with your NetWare server. + +- mars_nwe offers file, bindery and print services for NetWare client + software. + +- It was reported that if you patch your Linux kernel with the + speed-enhancing patch in examples/, mars_nwe is slower than NetWare + 3.12, but FASTER THAN NetWare 4.1 on the same hardware. + +- mars_nwe does not include any user license restrictions. You can + increase mars_nwe's licenses by simply recompiling it, and you can + start any number of mars_nwe's on your network! + +- mars_nwe includes a RIP/SAP daemon that turns your Linux box into a + fine IPX router. + + +Related packages include: + +- mars_dosutils: Some utilities that should free you from having to + use proprietary utilities when you want to use mars_nwe with DOS + clients. + +- ncpfs: a linux-only filesystem allowing you to mount volumes + exported by NetWare servers on your linux box. This is included as + standard with Linux 2.0 and later. + + +FTP SITE +======== + +Martin Stover has no online internet site. New versions are always +sent by uuencoded mail to Volker Lendecke, who puts them on +ftp.gwdg.de:/pub/linux/misc/ncpfs. sunsite mirrors this directory in +sunsite.unc.edu:/pub/Linux/system/Filesystems/ncpfs. + + +DOCUMENTATION +============= + There is not yet too much documentation available, look into the doc/ subdirectory. As Martin's native tongue is german, the documentation, as well as a lot of the code comments are a mixture of english and -german. This will certainly converge to english in the future. +german. This will certainly converge to english in the future. Feel +free to increase the rate of convergence, see above for patches! + INSTALLATION +============ + look in doc/INSTALL or doc/INSTALL.ger HELP +==== To get help you can mail to and/or subscribe to LinWare mailing list: Topics for the list: -- discussing LinWare server, its features, installation problems and bugs +- discussing mars_nwe server, its features, installation problems and bugs - using IPX protocol under Linux - IPX routing and router daemons under Linux -- mars_nwe +- and, last but not least, the LinWare daemon You can subscribe to the list by sending command "add linware" in mail message body to address: "listserv@sh.cvut.cz". Your list postings should be sent to address: "linware@sh.cvut.cz". +CONTRIBUTIONS +============= +If you want to contribute to the development of the software then +please join the mailing list. + +Martin accept patches (preferably in "diff -u" format) and is +always glad to receive feedback or suggestions. + +Remember that free software of this kind lives or dies by the response +we get. If noone tells us they like it then we'll probably move onto +something else. diff --git a/connect.c b/connect.c index 1d640c1..649502f 100644 --- a/connect.c +++ b/connect.c @@ -1,4 +1,4 @@ -/* connect.c 13-Jul-96 */ +/* connect.c 09-Aug-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -28,9 +28,6 @@ static int test_handle=-1; #endif -#define DONT_KNOW_IF_OK 0 - - static int default_uid=-1; static int default_gid=-1; @@ -81,7 +78,6 @@ static char *build_unix_name(NW_PATH *nwpath, int modus) *p = '\0'; } } - if (nw_volumes[volume].options & VOL_OPTION_DOWNSHIFT) downstr((uint8*)pp); return(unixname); } @@ -92,62 +88,60 @@ static int new_dir_handle(ino_t inode, NW_PATH *nwpath) */ { int rethandle; - DIR_HANDLE *fh = NULL; + DIR_HANDLE *dh = NULL; time_t akttime = time(NULL); time_t last_time = akttime; int thandle = 0; int nhandle = 0; for (rethandle=0; rethandle < anz_dirhandles; rethandle++){ - fh=&(dir_handles[rethandle]); - if (!fh->inode) { + dh=&(dir_handles[rethandle]); + if (!dh->inode) { if (!nhandle) nhandle = rethandle+1; - } else if (fh->inode == inode && fh->volume == nwpath->volume){ + } else if (dh->inode == inode && dh->volume == nwpath->volume){ /* Dieser hat Vorrang */ - if (fh->f) closedir(fh->f); - fh->f = NULL; - fh->timestamp = akttime; + if (dh->f) closedir(dh->f); + dh->f = NULL; + dh->timestamp = akttime; nhandle = rethandle+1; break; - } else if (fh->timestamp < last_time){ + } else if (dh->timestamp < last_time){ thandle = rethandle+1; - last_time = fh->timestamp; + last_time = dh->timestamp; } } if (!nhandle){ if (anz_dirhandles < MAX_DIRHANDLES) { - fh=&(dir_handles[anz_dirhandles]); + dh=&(dir_handles[anz_dirhandles]); rethandle = ++anz_dirhandles; } else { - fh=&(dir_handles[thandle-1]); - if (fh->f) closedir(fh->f); - fh->f = NULL; + dh=&(dir_handles[thandle-1]); + if (dh->f) closedir(dh->f); + dh->f = NULL; rethandle = thandle; } } else rethandle=nhandle; /* init dir_handle */ - fh=&(dir_handles[rethandle-1]); - strcpy(fh->unixname, build_unix_name(nwpath, 0)); - if ((fh->f = opendir(fh->unixname)) != (DIR*) NULL){ - fh->kpath = fh->unixname + strlen(fh->unixname); - fh->volume = nwpath->volume; - fh->vol_options = nw_volumes[fh->volume].options; - fh->inode = inode; - fh->timestamp = akttime; - - fh->sequence = 0; - fh->dirpos = (off_t)0; - - if (fh->vol_options & VOL_OPTION_REMOUNT) { - closedir(fh->f); - fh->f = NULL; + dh=&(dir_handles[rethandle-1]); + strcpy(dh->unixname, build_unix_name(nwpath, 0)); + dh->kpath = dh->unixname + strlen(dh->unixname); + if ((dh->f = opendir(dh->unixname)) != (DIR*) NULL){ + dh->volume = nwpath->volume; + dh->vol_options = nw_volumes[dh->volume].options; + dh->inode = inode; + dh->timestamp = akttime; + dh->sequence = 0; + dh->dirpos = (off_t)0; + if (dh->vol_options & VOL_OPTION_REMOUNT) { + closedir(dh->f); + dh->f = NULL; } } else { - fh->f = (DIR*)NULL; - fh->unixname[0] = '\0'; - fh->vol_options = 0; - fh->kpath = (char*)NULL; - rethandle = -0x9c; + dh->f = (DIR*)NULL; + dh->unixname[0] = '\0'; + dh->vol_options = 0; + dh->kpath = (char*)NULL; + rethandle = /* -0x9c */ -0xff; } return(rethandle); } @@ -155,12 +149,12 @@ static int new_dir_handle(ino_t inode, NW_PATH *nwpath) static int free_dir_handle(int dhandle) { if (dhandle > 0 && --dhandle < anz_dirhandles) { - DIR_HANDLE *fh=&(dir_handles[dhandle]); - if (fh->f != (DIR*) NULL) { - closedir(fh->f); - fh->f = (DIR*)NULL; + DIR_HANDLE *dh=&(dir_handles[dhandle]); + if (dh->f != (DIR*) NULL) { + closedir(dh->f); + dh->f = (DIR*)NULL; } - fh->inode = 0; + dh->inode = 0; while (anz_dirhandles && !dir_handles[anz_dirhandles-1].inode) anz_dirhandles--; return(0); @@ -183,27 +177,23 @@ void set_default_guid(void) void set_guid(int gid, int uid) { - char aktname[100]; - if (gid > -1 && uid > -1) { - seteuid(uid); - cuserid(aktname); - } else aktname[0] = '\0'; if ( gid < 0 || uid < 0 || seteuid(0) - || setegid(gid) == -1 - || seteuid(uid) == -1 ) { - DPRINTF(("SET GID=%d, UID=%d failed\n", gid, uid)); + || setegid(gid) + || seteuid(uid) ) { set_default_guid(); } else { - if (aktname[0]) { + struct passwd *pw = getpwuid(uid); + if (NULL != pw) { seteuid(0); - initgroups(aktname, gid); - if (seteuid(uid) == -1) set_default_guid(); + initgroups(pw->pw_name, gid); } - XDPRINTF((5,0,"SET GID=%d, UID=%d OK", gid, uid)); act_gid = gid; act_uid = uid; + if (seteuid(uid)) set_default_guid(); } + XDPRINTF((5,0,"SET GID=%d, UID=%d %s", gid, uid, + (gid==act_gid && uid == act_uid) ? "OK" : "failed")); } static char *conn_get_nwpath_name(NW_PATH *p) @@ -218,7 +208,7 @@ static char nwpathname[300]; return(nwpathname); } -static int x_str_match(uint8 *s, uint8 *p) +static int x_str_match(uint8 *s, uint8 *p, int soptions) { uint8 pc, sc; uint state = 0; @@ -256,7 +246,7 @@ static int x_str_match(uint8 *s, uint8 *p) case '*' : if (!*p) return(1); /* last star */ while (*s) { - if (x_str_match(s, p) == 1) return(1); + if (x_str_match(s, p, soptions) == 1) return(1); else if (*s == '.') return(0); ++s; } @@ -270,7 +260,13 @@ static int x_str_match(uint8 *s, uint8 *p) state = 100; continue; - default : if (pc != *s++) return(0); /* normal char */ + default : /* 'normal' chars */ + if (soptions & VOL_OPTION_IGNCASE) { + if (*s != pc && ((!isalpha(pc)) || (!isalpha(*s)) + || (pc | 0x20) != (*s | 0x20))) + return(0); + } else if (pc != *s) return(0); + s++; break; } /* switch */ @@ -317,10 +313,11 @@ static int x_str_match(uint8 *s, uint8 *p) default : break; } /* switch */ } /* while */ + if (*s=='.' && *(s+1)=='\0') return(1); /* I hope this is right */ return ( (*s) ? 0 : 1); } -int fn_match(uint8 *s, uint8 *p, int options) +int fn_dos_match(uint8 *s, uint8 *p, int options) { uint8 *ss=s; int len=0; @@ -332,14 +329,18 @@ int fn_match(uint8 *s, uint8 *p, int options) } else { ++len; if ((pf && len > 3) || len > 8) return(0); - if (options & VOL_OPTION_DOWNSHIFT){ /* only downshift chars */ - if (*ss >= 'A' && *ss <= 'Z') return(0); - } else { /* only upshift chars */ - if (*ss >= 'a' && *ss <= 'z') return(0); + + if (!(options & VOL_OPTION_IGNCASE)){ + if (options & VOL_OPTION_DOWNSHIFT){ /* only downshift chars */ + if (*ss >= 'A' && *ss <= 'Z') return(0); + } else { /* only upshift chars */ + if (*ss >= 'a' && *ss <= 'z') return(0); + } } + } } - return(x_str_match(s, p)); + return(x_str_match(s, p, options)); } typedef struct { @@ -370,7 +371,9 @@ static int func_search_entry(NW_PATH *nwpath, int attrib, if (volume < 0 || volume >= used_nw_volumes) return(-1); /* something wrong */ else soptions = nw_volumes[volume].options; strcpy((char*)entry, (char*)nwpath->fn); +#if 0 if (soptions & VOL_OPTION_DOWNSHIFT) downstr(entry); /* now downshift chars */ +#endif nwpath->fn[0] = '\0'; strcpy(xkpath, build_unix_name(nwpath, 1|2)); @@ -386,7 +389,7 @@ static int func_search_entry(NW_PATH *nwpath, int attrib, okflag = (name[0] != '.' && ( (entry[0] == '*' && entry[1] == '\0') || (!strcmp((char*)name, (char*)entry)) - || fn_match(name, entry, soptions))); + || fn_dos_match(name, entry, soptions))); if (okflag) { *kpath = '\0'; strcpy(kpath, (char*)name); @@ -395,7 +398,9 @@ static int func_search_entry(NW_PATH *nwpath, int attrib, || ( ( (fs->statb.st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10))); if (okflag){ strcpy((char*)nwpath->fn, (char*)name); +#if 0 if (soptions & VOL_OPTION_DOWNSHIFT) upstr(nwpath->fn); +#endif XDPRINTF((5,0,"FOUND=:%s: attrib=0x%x", nwpath->fn, fs->statb.st_mode)); result = (*fs_func)(nwpath, fs); if (result < 0) break; @@ -429,8 +434,9 @@ static int get_dir_entry(NW_PATH *nwpath, if (volume < 0 || volume >= used_nw_volumes) return(0); /* something wrong */ else soptions = nw_volumes[volume].options; strcpy((char*)entry, (char*)nwpath->fn); +#if 0 if (soptions & VOL_OPTION_DOWNSHIFT) downstr(entry); /* now downshift chars */ - +#endif nwpath->fn[0] = '\0'; strcpy(xkpath, build_unix_name(nwpath, 1|2)); XDPRINTF((5,0,"get_dir_entry attrib=0x%x path:%s:, xkpath:%s:, entry:%s:", @@ -456,7 +462,7 @@ static int get_dir_entry(NW_PATH *nwpath, okflag = (name[0] != '.' && ( (entry[0] == '*' && entry[1] == '\0') || (!strcmp((char*)name, (char*)entry)) - || fn_match(name, entry, soptions))); + || fn_dos_match(name, entry, soptions))); if (okflag) { *kpath = '\0'; strcpy(kpath, (char*)name); @@ -465,7 +471,9 @@ static int get_dir_entry(NW_PATH *nwpath, || ( ( (statb->st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10))); if (okflag){ strcpy((char*)nwpath->fn, (char*)name); +#if 0 if (soptions & VOL_OPTION_DOWNSHIFT) upstr(nwpath->fn); +#endif XDPRINTF((5,0,"FOUND=:%s: attrib=0x%x", nwpath->fn, statb->st_mode)); break; /* ready */ } @@ -483,7 +491,7 @@ static DIR *give_dh_f(DIR_HANDLE *dh) { if (!dh->f) { *(dh->kpath) = '\0'; - dh->f = opendir(dh->unixname); + dh->f = opendir(dh->unixname); } return(dh->f); } @@ -511,8 +519,9 @@ static int get_dh_entry(DIR_HANDLE *dh, struct dirent *dirbuff; uint8 entry[256]; strmaxcpy(entry, search, 255); - +#if 0 if (dh->vol_options & VOL_OPTION_DOWNSHIFT) downstr(entry); +#endif if ( (uint16)*sequence == MAX_U16) *sequence = 0; if (*sequence < dh->sequence) { @@ -532,7 +541,7 @@ static int get_dh_entry(DIR_HANDLE *dh, } dh->dirpos = telldir(f); } - XDPRINTF((5,0,"get_dh_entry seq=x%x, attrib=0x%x path:%s:, entry:%s:", + XDPRINTF((5,0,"get_dh_entry seq=0x%x, attrib=0x%x path:%s:, entry:%s:", *sequence, attrib, dh->unixname, entry)); while ((dirbuff = readdir(f)) != (struct dirent*)NULL){ @@ -543,7 +552,7 @@ static int get_dh_entry(DIR_HANDLE *dh, okflag = (name[0] != '.' && ( (!strcmp((char*)name, (char*)entry)) || (entry[0] == '*' && entry[1] == '\0') - || fn_match(name, entry, dh->vol_options))); + || fn_dos_match(name, entry, dh->vol_options))); if (okflag) { strcpy(dh->kpath, (char*)name); @@ -555,19 +564,19 @@ static int get_dh_entry(DIR_HANDLE *dh, || (((statb->st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10))); if (okflag){ strcpy((char*)search, (char*)name); +#if 0 if (dh->vol_options & VOL_OPTION_DOWNSHIFT) upstr(search); +#endif break; /* ready */ } } else okflag = 0; } } /* if */ } /* while */ - dh->kpath[0] = '\0'; *sequence = dh->sequence; dh->dirpos = telldir(f); release_dh_f(dh); - } /* if */ return(okflag); } @@ -587,9 +596,12 @@ static void conn_build_path_fn( uint8 *vol, *has_wild = 0; /* no wild char */ while (len-- && *data){ if (*data == 0xae) *p1++ = '.'; +#if 0 else if (*data > 0x60 && *data < 0x7b) { *p1++ = *data - 0x20; /* all is upshift */ - } else if (*data == 0xaa|| *data == '*' ) { + } +#endif + else if (*data == 0xaa|| *data == '*' ) { *p1++ = '*'; (*has_wild)++; } else if (*data == 0xbf|| *data == '?' ) { @@ -602,6 +614,7 @@ static void conn_build_path_fn( uint8 *vol, int len = (int) (p1 - path); memcpy(vol, path, len); vol[len] = '\0'; + upstr(vol); p1 = path; } else *p1++ = *data; data++; @@ -645,6 +658,13 @@ static int build_path( NW_PATH *path, while (j--) { if (!strcmp((char*)nw_volumes[j].sysname, (char*)vol)) { path->volume = j; + if (nw_volumes[j].options & VOL_OPTION_DOWNSHIFT) { + downstr(path->path); + downstr(path->fn); + } else { + upstr(path->path); + upstr(path->fn); + } break; } } @@ -700,7 +720,6 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */ strcpy((char*)nwpath->path, (char*)dirs[dir_handle].path); } else return(-0x9b); /* wrong dir handle */ } - if (*p) { uint8 *panf = nwpath->path; uint8 *p1 = panf+strlen((char*)panf); @@ -758,13 +777,37 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */ } } } - if (!completition) completition = nw_path_ok(nwpath); + if (!completition) { + if (nwpath->volume > -1 && nwpath->volume < used_nw_volumes){ + NW_VOL *v = &nw_volumes[nwpath->volume]; + if (v->options & VOL_OPTION_DOWNSHIFT) { + downstr(nwpath->path); + downstr(nwpath->fn); + } else { + upstr(nwpath->path); + upstr(nwpath->fn); + } + if (v->options & VOL_OPTION_IGNCASE) { + uint8 unixname[1024]; /* should be enough */ + uint8 *pp=unixname+v->unixnamlen; + int pathlen = strlen(nwpath->path); + int fnlen = strlen(nwpath->fn); + memcpy(unixname, v->unixname, v->unixnamlen); + strcpy(pp, nwpath->path); + if (fnlen) + strcpy(pp+pathlen, nwpath->fn); + mangle_dos_name(v, unixname, pp); + XDPRINTF((5, 0, "Mangled DOS/unixname=%s", unixname)); + memcpy(nwpath->path, pp, pathlen); + if (fnlen) + memcpy(nwpath->fn, pp+pathlen, fnlen); + } + } else return(-0x98); /* wrong volume */ + completition = nw_path_ok(nwpath); + } return(completition); } -#if DONT_KNOW_IF_OK -static int lastdirhandle=0; -#endif int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle, uint8 *data, int len, int only_dir) /* @@ -772,16 +815,9 @@ int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle, * else a negativ errcode will be returned */ { - int completition; -#if DONT_KNOW_IF_OK - if (!dirhandle && len > 1 && *data== ':' && *(data+1) == '/') { - --len; - data++; - dirhandle = lastdirhandle; - } else if (dirhandle) lastdirhandle = dirhandle; -#endif - completition = build_path(nwpath, data, len, only_dir); - XDPRINTF((5, 0, "conn_get_kpl_path %s", conn_get_nwpath_name(nwpath))); + int completition = build_path(nwpath, data, len, only_dir); + XDPRINTF((5, 0, "compl=0x%x, conn_get_kpl_path %s", + completition, conn_get_nwpath_name(nwpath))); if (!completition) completition = build_verz_name(nwpath, dirhandle); return(completition); } @@ -905,6 +941,8 @@ static int get_file_attrib(NW_FILE_INFO *f, struct stat *stb, NW_PATH *nwpath) { strncpy((char*)f->name, (char*)nwpath->fn, sizeof(f->name)); + f->attrib=0; /* d->name could be too long */ + upstr(f->name); f->attrib = (uint8) un_nw_attrib(stb, 0, 0); XDPRINTF((5,0, "get_file_attrib = 0x%x of ,%s, uid=%d, gid=%d", (int)f->attrib, conn_get_nwpath_name(nwpath), @@ -923,7 +961,8 @@ static int get_dir_attrib(NW_DIR_INFO *d, struct stat *stb, { XDPRINTF((5,0, "get_dir_attrib of %s", conn_get_nwpath_name(nwpath))); strncpy((char*)d->name, (char*)nwpath->fn, sizeof(d->name)); - + d->attrib=0; /* d->name could be too long */ + upstr(d->name); d->attrib = 0x10; /* Verzeichnis */ d->ext_attrib = 0xff; /* effektive rights ?? */ un_date_2_nw(stb->st_mtime, d->create_date, 1); @@ -1009,14 +1048,7 @@ int nw_chmod_datei(int dir_handle, uint8 *data, int len, char unname[256]; struct stat stbuff; int completition=-0x9c; - NW_PATH nwpath; -#if DONT_KNOW_IF_OK - if (!dir_handle && len > 1 && *data== ':' && *(data+1) == '/') { - --len; - data++; - dir_handle = lastdirhandle; - } else if (dir_handle) lastdirhandle = dir_handle; -#endif + NW_PATH nwpath; build_path(&nwpath, data, len, 0); if (nwpath.fn[0] != '.') { /* Files with . at the beginning are not ok */ completition = build_verz_name(&nwpath, dir_handle); @@ -1048,10 +1080,10 @@ int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode) } else { /* rmdir */ int j = -1; while (++j < (int)anz_dirhandles){ - DIR_HANDLE *fh=&(dir_handles[j]); - if (fh->inode == completition && fh->f != (DIR*) NULL) { - closedir(fh->f); - fh->f = (DIR*)NULL; + DIR_HANDLE *dh=&(dir_handles[j]); + if (dh->inode == completition && dh->f != (DIR*) NULL) { + closedir(dh->f); + dh->f = (DIR*)NULL; } } XDPRINTF((5,0,"RMDIR dirname:%s:", unname)); @@ -1065,8 +1097,8 @@ int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode) } j = -1; while (++j < (int)anz_dirhandles){ - DIR_HANDLE *fh=&(dir_handles[j]); - if (fh->inode == completition) free_dir_handle(j+1); + DIR_HANDLE *dh=&(dir_handles[j]); + if (dh->inode == completition) free_dir_handle(j+1); } completition = 0; } else if (errno == EEXIST) @@ -1163,7 +1195,20 @@ static int change_dir_entry( NW_DIR *dir, int volume, int new_entry, int task) { if (new_entry || (dir->inode && dir->is_temp != 2)) { - new_str(dir->path, path); + int len=strlen(path); + if (dir->path) xfree(dir->path); + dir->path=xmalloc(len+2); + if (len) { + memcpy(dir->path, path, len); + if (dir->path[len-1] != '/') { + *(dir->path + len) = '/'; + ++len; + } + } else { + *(dir->path) = '/'; + ++len; + } + *(dir->path+len) = '\0'; dir->inode = inode; dir->volume = (uint8) volume; dir->timestamp = time(NULL); @@ -1360,20 +1405,25 @@ int nw_dir_search(uint8 *info, if (dirhandle > 0 && --dirhandle < anz_dirhandles){ DIR_HANDLE *dh = &(dir_handles[dirhandle]); struct stat stbuff; + if (dh->vol_options & VOL_OPTION_DOWNSHIFT) { + downstr(nwpath.fn); + } else { + upstr(nwpath.fn); + } if (get_dh_entry(dh, nwpath.fn, &searchsequence, search_attrib, &stbuff)){ - if ( S_ISDIR(stbuff.st_mode) ) { - get_dir_attrib((NW_DIR_INFO*)info, &stbuff, - &nwpath); - } else { - get_file_attrib((NW_FILE_INFO*)info, &stbuff, - &nwpath); - } - return(searchsequence); - } else return(-0xff); /* not found */ + if ( S_ISDIR(stbuff.st_mode) ) { + get_dir_attrib((NW_DIR_INFO*)info, &stbuff, + &nwpath); + } else { + get_file_attrib((NW_FILE_INFO*)info, &stbuff, + &nwpath); + } + return(searchsequence); + } else return(-0xff); /* not found */ } else return(completition); /* wrong path */ } @@ -1417,8 +1467,8 @@ int nw_open_dir_handle( int dir_handle, completition = new_dir_handle((ino_t)completition, &nwpath); if (completition > -1) { - DIR_HANDLE *fh = &(dir_handles[completition-1]); - *volume = fh->volume; + DIR_HANDLE *dh = &(dir_handles[completition-1]); + *volume = dh->volume; *dir_id = completition; *searchsequence = MAX_U16; completition = 0xff; /* all rights */ @@ -1558,11 +1608,18 @@ static int s_nw_scan_dir_info(int dir_handle, uint8 dirname[256]; if (!dirsequenz) dirsequenz++; + if (dh->vol_options & VOL_OPTION_DOWNSHIFT) { + downstr(wild); + } else { + upstr(wild); + } + strcpy((char*)dirname, (char*)wild); XDPRINTF((5,0,"SCAN_DIR: rights = 0x%x, subnr = %d", (int)rights, (int)GET_BE16(subnr))); if (*dirname) { + while ( get_dh_entry( dh, dirname, &searchsequence, @@ -1572,6 +1629,7 @@ static int s_nw_scan_dir_info(int dir_handle, XDPRINTF((5,0,"SCAN_DIR: von %s, found %s:", dh->unixname, dirname)); if (++aktsequenz == dirsequenz) { /* actual found */ U16_TO_BE16(aktsequenz, subnr); + upstr(dirname); strncpy((char*)subname, (char*)dirname, 16); U32_TO_BE32(1L, owner); /* erstmal */ un_date_2_nw(stbuff.st_mtime, subdatetime, 1); @@ -1581,7 +1639,8 @@ static int s_nw_scan_dir_info(int dir_handle, strcpy((char*)dirname, (char*)wild); } /* while */ } else { - strcpy(dh->kpath, "."); + *(dh->kpath) = '.'; + *(dh->kpath+1) = '\0'; if (!stat(dh->unixname, &stbuff)) { U16_TO_BE16(1, subnr); memset(subname, 0, 16); @@ -1622,43 +1681,20 @@ int nw_scan_dir_info(int dir_handle, uint8 *data, int len, uint8 *subnr, } -typedef struct { - uint8 time[2]; - uint8 date[2]; - uint8 id[4]; -} NW_FILE_DATES_INFO; -typedef struct { - uint8 subdir[4]; - uint8 attributes[4]; /* 0x20,0,0,0 File */ - uint8 uniqueid; /* 0 */ - uint8 flags; /* 0x18 */ - uint8 namespace; /* 0 */ - uint8 namlen; - uint8 name[12]; - NW_FILE_DATES_INFO created; - NW_FILE_DATES_INFO archived; - NW_FILE_DATES_INFO updated; - uint8 size[4]; - uint8 reserved_1[44]; - uint8 inherited_rights_mask[2]; - uint8 last_access_date[2]; - uint8 reserved_2[28]; -} NW_DOS_FILE_INFO; - -static void get_dos_file_attrib(NW_DOS_FILE_INFO *f, +void get_dos_file_attrib(NW_DOS_FILE_INFO *f, struct stat *stb, - NW_PATH *nwpath) + uint8 *path) { - f->namlen=min(strlen((char*)nwpath->fn), 12); - strncpy((char*)f->name, (char*)nwpath->fn, f->namlen); + uint8 spath[14]; + f->namlen=min(strlen((char*)path), 12); + strmaxcpy(spath, path, 12); + upstr(spath); + strncpy((char*)f->name, (char*)spath, f->namlen); /* Attribute */ /* 0x20 Archive Flag */ /* 0x80 Sharable */ f->attributes[0] = (uint8) un_nw_attrib(stb, 0, 0); - XDPRINTF((5,0, "get_dos_file_attrib = 0x%x of ,%s, uid=%d, gid=%d", - (int)f->attributes[0], conn_get_nwpath_name(nwpath), - stb->st_uid, stb->st_gid)); un_date_2_nw(stb->st_mtime, f->created.date, 0); un_time_2_nw(stb->st_mtime, f->created.time, 0); U32_TO_BE32(1, f->created.id); @@ -1667,32 +1703,15 @@ static void get_dos_file_attrib(NW_DOS_FILE_INFO *f, U32_TO_32(stb->st_size, f->size); } -typedef struct { - uint8 subdir[4]; - uint8 attributes[4]; /* 0x10,0,0,0 DIR */ - uint8 uniqueid; /* 0 */ - uint8 flags; /* 0x14 or 0x1c */ - uint8 namespace; /* 0 */ - uint8 namlen; - uint8 name[12]; - NW_FILE_DATES_INFO created; - NW_FILE_DATES_INFO archived; - uint8 modify_time[2]; - uint8 modify_date[2]; - uint8 next_trustee[4]; - uint8 reserved_1[48]; - uint8 max_space[4]; - uint8 inherited_rights_mask[2]; - uint8 reserved_2[26]; -} NW_DOS_DIR_INFO; - - -static void get_dos_dir_attrib(NW_DOS_DIR_INFO *f, +void get_dos_dir_attrib(NW_DOS_DIR_INFO *f, struct stat *stb, - NW_PATH *nwpath) + uint8 *path) { - f->namlen=min(strlen((char*)nwpath->fn), 12); - strncpy((char*)f->name, (char*)nwpath->fn, f->namlen); + uint8 spath[14]; + f->namlen=min(strlen((char*)path), 12); + strmaxcpy(spath, path, 12); + upstr(spath); + strncpy((char*)f->name, (char*)spath, f->namlen); f->attributes[0] = 0x10; /* Dir */ un_date_2_nw(stb->st_mtime, f->created.date,0); un_time_2_nw(stb->st_mtime, f->created.time,0); @@ -1702,13 +1721,6 @@ static void get_dos_dir_attrib(NW_DOS_DIR_INFO *f, U32_TO_BE32(MAX_U32, f->max_space); } -typedef struct { - uint8 searchsequence[4]; - union { - NW_DOS_DIR_INFO d; - NW_DOS_FILE_INFO f; - } u; -} NW_SCAN_DIR_INFO; int nw_scan_a_directory(uint8 *rdata, int dirhandle, @@ -1733,12 +1745,16 @@ int nw_scan_a_directory(uint8 *rdata, memset(rdata, 0, sizeof(NW_SCAN_DIR_INFO)); U32_TO_BE32((uint32)searchsequence, scif->searchsequence); + XDPRINTF((5,0, "nw_scan_a_directory = %s, uid=%d, gid=%d", + conn_get_nwpath_name(&nwpath), + stbuff.st_uid, stbuff.st_gid)); + if ( (stbuff.st_mode & S_IFMT) == S_IFDIR) { get_dos_dir_attrib(&(scif->u.d), &stbuff, - &nwpath); + nwpath.fn); } else { get_dos_file_attrib(&(scif->u.f), &stbuff, - &nwpath); + nwpath.fn); } return(sizeof(NW_SCAN_DIR_INFO)); } else return(-0xff); /* not found */ @@ -1758,11 +1774,65 @@ int nw_scan_a_root_dir(uint8 *rdata, if (!stat(build_unix_name(&nwpath, 2), &stbuff)) { NW_DOS_DIR_INFO *d=(NW_DOS_DIR_INFO*)rdata; memset(rdata, 0, sizeof(NW_DOS_DIR_INFO)); - get_dos_dir_attrib(d, &stbuff, &nwpath); + get_dos_dir_attrib(d, &stbuff, nwpath.fn); return(sizeof(NW_DOS_DIR_INFO)); } else return(-0xff); /* not found */ } else return(completition); /* wrong path */ } +static int my_match(uint8 *s, uint8 *p) +{ + int len=0; + int dot=0; + for (; *s && *p; s++,p++) { + if (len == 12) return(0); + if (*s == '.') { + if (dot) return(0); + dot++; + } else if (dot) { + if (dot++ > 3) return(0); + } else if (len == 8) return(0); + + if (*s != *p && ((!isalpha(*p)) || (!isalpha(*s)) + || (*p | 0x20) != (*s | 0x20))) + return(0); + ++len; + } + return( ((!*s) && (*p=='/' || *p == '\0')) ? len : 0); +} + +static int get_match(uint8 *unixname, uint8 *p) +{ + DIR *d; + if (!p || !*p) return(1); + *p = '\0'; + if (NULL != (d=opendir(unixname))) { + struct dirent *dirbuff; + XDPRINTF((10, 0, "opendir OK unixname='%s' p='%s'", unixname, p+1)); + *p = '/'; + while ((dirbuff = readdir(d)) != (struct dirent*)NULL){ + int len; + if (dirbuff->d_ino) { + XDPRINTF((10, 0, "get match found d_name='%s'", dirbuff->d_name)); + if (0 != (len=my_match(dirbuff->d_name, p+1))) { + memcpy(p+1, dirbuff->d_name, len); + XDPRINTF((10, 0, "get match, match OK")); + closedir(d); + return(get_match(unixname, p+1+len)); + } + } + } + closedir(d); + } else { + XDPRINTF((2, 0, "DOS get_match opendir failed unixname='%s'", unixname)); + *p='/'; + } + return(0); +} + +void mangle_dos_name(NW_VOL *vol, uint8 *unixname, uint8 *pp) +{ + get_match(unixname, pp-1); +} diff --git a/connect.h b/connect.h index c5a3c04..6a6be8b 100644 --- a/connect.h +++ b/connect.h @@ -1,4 +1,4 @@ -/* connect.h 04-May-96 */ +/* connect.h 28-Jul-96 */ #ifndef _CONNECT_H_ #define _CONNECT_H_ typedef struct { @@ -55,6 +55,57 @@ typedef struct { } NW_DIR_INFO; +typedef struct { + uint8 time[2]; + uint8 date[2]; + uint8 id[4]; +} NW_FILE_DATES_INFO; + +typedef struct { + uint8 subdir[4]; + uint8 attributes[4]; /* 0x20,0,0,0 File */ + uint8 uniqueid; /* 0 */ + uint8 flags; /* 0x18 */ + uint8 namespace; /* 0 */ + uint8 namlen; + uint8 name[12]; + NW_FILE_DATES_INFO created; + NW_FILE_DATES_INFO archived; + NW_FILE_DATES_INFO updated; + uint8 size[4]; + uint8 reserved_1[44]; + uint8 inherited_rights_mask[2]; + uint8 last_access_date[2]; + uint8 reserved_2[28]; +} NW_DOS_FILE_INFO; + +typedef struct { + uint8 subdir[4]; + uint8 attributes[4]; /* 0x10,0,0,0 DIR */ + uint8 uniqueid; /* 0 */ + uint8 flags; /* 0x14 or 0x1c */ + uint8 namespace; /* 0 */ + uint8 namlen; + uint8 name[12]; + NW_FILE_DATES_INFO created; + NW_FILE_DATES_INFO archived; + uint8 modify_time[2]; + uint8 modify_date[2]; + uint8 next_trustee[4]; + uint8 reserved_1[48]; + uint8 max_space[4]; + uint8 inherited_rights_mask[2]; + uint8 reserved_2[26]; +} NW_DOS_DIR_INFO; + +typedef struct { + uint8 searchsequence[4]; + union { + NW_DOS_DIR_INFO d; + NW_DOS_FILE_INFO f; + } u; +} NW_SCAN_DIR_INFO; + extern int nw_init_connect(void); extern void nw_exit_connect(void); @@ -130,6 +181,15 @@ extern int nw_scan_dir_info(int dir_handle, uint8 *data, int len, uint8 *subdatetime, uint8 *owner); +extern void get_dos_file_attrib(NW_DOS_FILE_INFO *f, + struct stat *stb, + uint8 *path); + +void get_dos_dir_attrib(NW_DOS_DIR_INFO *f, + struct stat *stb, + uint8 *path); + + #define MAX_NW_DIRS 255 extern NW_DIR dirs[MAX_NW_DIRS]; extern int used_dirs; @@ -154,11 +214,15 @@ extern int nw_scan_a_root_dir(uint8 *rdata, int dirhandle); -extern int fn_match(uint8 *s, uint8 *p, int options); +extern int fn_dos_match(uint8 *s, uint8 *p, int options); extern void un_date_2_nw(time_t time, uint8 *d, int high_low); extern time_t nw_2_un_time(uint8 *d, uint8 *t); extern void un_time_2_nw(time_t time, uint8 *d, int high_low); + +extern void mangle_dos_name(NW_VOL *vol, uint8 *unixname, uint8 *pp); + + #endif diff --git a/doc/CHANGES b/doc/CHANGES index af60b72..146eb2a 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -163,6 +163,8 @@ Erste 'oeffentliche' Version - Dummy Routinen fuer OS/2 extended attributes eingebaut. - NFS-namespace rudimentaer eingebaut. <----- ^^^^^^^^^^ pl0 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - +- bessere OS2 Nameunterstuetzung. +- 0x17 0x81 als Dummy implementiert fuer Windows Client. +<----- ^^^^^^^^^^ pl1 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/CREDITS b/doc/CREDITS index 1038fdf..e077f40 100644 --- a/doc/CREDITS +++ b/doc/CREDITS @@ -17,7 +17,7 @@ Ales Dryak his linware gave the kick Fritz Elfert - gives Bugreport and Patches + gives bugreport and patches Ruedi Kneubuehler helping and testing for linux/sparc @@ -31,6 +31,9 @@ James B. MacLean Jiri A. Randus testing bindery code +Gregory Steuck + testings and errorreports + Winfried Truemper : re-wrote `INSTALL' and added explanations to `nw.ini' diff --git a/doc/NEWS b/doc/NEWS index 6fd5b0d..957bb54 100644 --- a/doc/NEWS +++ b/doc/NEWS @@ -1,4 +1,6 @@ -# in this files are important notes for user of mars_nwe. +# in this files are some notes for user of mars_nwe. +------30-Jul-96--- 0.98.pl1 ---------- +- better OS2 name handling (upper/lowercase) ------22-Jul-96--- 0.98.pl0 ---------- - problems with directory handles eliminated. (missunderstood 'creat permanent directory handle' call :( ) diff --git a/doc/mars_nwe.lsm b/doc/mars_nwe.lsm index 795136f..5d37c5d 100644 --- a/doc/mars_nwe.lsm +++ b/doc/mars_nwe.lsm @@ -1,7 +1,7 @@ Begin3 Title: mars_nwe -Version: 0.98 -Entered-date: 22-Jul-96 +Version: 0.98.pl1 +Entered-date: 14-Aug-96 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 - 165kB mars_nwe-0.98.tgz + 165kB mars_nwe-0.98.pl1.tgz Alternate-site: ftp.uni-duisburg.de /pub/linux/ipxware 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 f8f01c7..4bc7381 100644 --- a/examples/config.h +++ b/examples/config.h @@ -43,7 +43,7 @@ /* <--------------------------------------------------------------------> */ #define MAX_NW_VOLS 10 /* max. number of mars_nwe-volumes */ -#define MAX_FILE_HANDLES_CONN 80 /* max. number of open files per */ +#define MAX_FILE_HANDLES_CONN 255 /* max. number of open files per */ /* connection */ /* <--------------- new namespace services call -----------------------> */ #define MAX_DIR_BASE_ENTRIES 50 /* max. cached base entries per */ diff --git a/examples/nw.ini b/examples/nw.ini index 61a6d6e..06221d6 100644 --- a/examples/nw.ini +++ b/examples/nw.ini @@ -59,8 +59,12 @@ # individual home-directory # # OPTIONS: none or some of the following characters (without a seperator) -# k allow lowercase-filenames (if you don't set this, all -# files _must_ be upper-case) +# +# Next two options control DOS and OS/2 namespace. +# i ignore case, handle mixing upper/lowercase filenames (slow) +# k use lowercase-filenames (if you don't set this, +# and you don't set 'i' all files _must_ be upper-case) +# # m removable volume (e.g. cd-roms) # r volume is read-only and always reports "0 byte free" # (this is intended for copies of CD-ROMs on harddisks) @@ -72,6 +76,7 @@ # p "PIPE"-filesystem. All files are pipe commands. # See `doc/PIPE-FS'. # +# additional Namespaces # O + OS/2 namespace. # N + NFS namespace. # ------------------------------------------------------------------------- diff --git a/makefile.unx b/makefile.unx index c1dab66..f294754 100644 --- a/makefile.unx +++ b/makefile.unx @@ -1,5 +1,5 @@ #if 0 -#makefile.unx 12-Jul-96 +#makefile.unx 28-Jul-96 #endif VPATH=$(V_VPATH) @@ -9,9 +9,9 @@ C=.c V_H=0 V_L=98 -P_L=0 +P_L=1 -#define D_P_L 0 +#define D_P_L 1 DISTRIB=mars_nwe #if D_P_L DISTRIBF=$(DISTRIB)-$(V_H).$(V_L).pl$(P_L) @@ -106,7 +106,7 @@ PROGS=$(PROG1) $(PROG2) $(PROG3) $(PROG4) $(PROG5) $(PROG6) $(NWROUTED) OBJ1= $(EMUTLIOBJ) net1$(O) tools$(O) OBJ2= $(OBJ1) $(EMUTLIOBJ1) $(NWROUTE_O) OBJ3= $(OBJ1) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O) \ -nwqueue$(O) +nwqueue$(O) nameos2$(O) OBJ4= $(OBJ1) OBJ5= $(OBJ1) OBJ6= $(OBJ1) nwdbm$(O) nwcrypt$(O) unxlog$(O) diff --git a/nameos2.c b/nameos2.c new file mode 100644 index 0000000..426ca86 --- /dev/null +++ b/nameos2.c @@ -0,0 +1,271 @@ +/* nameos2.c 08-Aug-96 : NameSpace OS2 Services, mars_nwe */ +/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "net.h" +#include +#include +#ifndef LINUX +#include +#endif + +#include "nwvolume.h" +#include "connect.h" +#include "nwfile.h" +#include "unxfile.h" +#include "nameos2.h" + +#if WITH_NAME_SPACE_CALLS + +#define MAX_NAME_OS2_CACHE 0 + +#if MAX_NAME_OS2_CACHE +typedef struct { + uint8 *cache[MAX_NAME_OS2_CACHE]; +} OS2BUF; + +static void init_os2buf(NW_VOL *vol) +{ + vol->os2buf = xcmalloc(sizeof(OS2BUF)); +} + +static int vgl_name(uint8 *s, uint8 *p) +{ + int hit=0; + if (!s) return(0); + for (; *s && *p; s++,p++) { + if (*s == *p) { + if (*s == '/') + ++hit; + } else if ((!isalpha(*p)) || (!isalpha(*s)) + || (*p | 0x20) != (*s | 0x20)) { + return(hit); + } + } + return((*s == *p) ? -1 : hit); +} +#endif + +static int my_match(uint8 *s, uint8 *p) +{ + int len=0; + for (; *s && *p; s++,p++) { + if (*s != *p && ((!isalpha(*p)) || (!isalpha(*s)) + || (*p | 0x20) != (*s | 0x20))) + return(0); + ++len; + } + return( ((!*s) && (*p=='/' || *p == '\0')) ? len : 0); +} + +static int get_match(uint8 *unixname, uint8 *p) +{ + DIR *d; + if (!p || !*p) return(1); + *p = '\0'; + if (NULL != (d=opendir(unixname))) { + struct dirent *dirbuff; + XDPRINTF((10, 0, "opendir OK unixname='%s' p='%s'", unixname, p+1)); + *p = '/'; + while ((dirbuff = readdir(d)) != (struct dirent*)NULL){ + int len; + if (dirbuff->d_ino) { + XDPRINTF((10, 0, "get match found d_name='%s'", dirbuff->d_name)); + if (0 != (len=my_match(dirbuff->d_name, p+1))) { + memcpy(p+1, dirbuff->d_name, len); + XDPRINTF((10, 0, "get match, match OK")); + closedir(d); + return(get_match(unixname, p+1+len)); + } + } + } + closedir(d); + } else { + XDPRINTF((2, 0, "os2 get_match opendir failed unixname='%s'", unixname)); + *p='/'; + } + return(0); +} + +#if MAX_NAME_OS2_CACHE +static int get_name(uint8 *s, uint8 *unixname, int hit, uint8 *p) +{ + if (hit && s) { + for (; *s && *p; s++,p++) { + if (*s=='/') { + if (!--hit) break; + } else *p=*s; + } + } else + --p; /* to get last '/' */ + return(get_match(unixname, p)); +} +#endif + +void mangle_os2_name(NW_VOL *vol, uint8 *unixname, uint8 *pp) +{ +#if MAX_NAME_OS2_CACHE + int k = -1; + int besthit = -1; + int maxhits = 0; + OS2BUF *b; + if (!vol->os2buf) init_os2buf(vol); + b= (OS2BUF*)vol->os2buf; + + while (++k < MAX_NAME_OS2_CACHE) { + int hits=vgl_name(b->cache[k], pp); + if (hits < 0) { + besthit=k; + break; + } else if (hits > maxhits) { + besthit=k; + maxhits =hits; + } + } + if (maxhits > -1) { + /* do not completely match */ + if (get_name(maxhits ? b->cache[besthit] : NULL, + unixname, maxhits, pp)) { + int k=MAX_NAME_OS2_CACHE-1; + xfree(b->cache[k]); + while (k--) { + b->cache[k+1] = b->cache[k]; + } + b->cache[0] = NULL; + new_str(b->cache[0], pp); + } + } else { + strcpy(pp, b->cache[besthit]); + if (besthit > 2) { + uint8 *sp=b->cache[besthit]; + while (besthit--) { + b->cache[besthit+1] = b->cache[besthit]; + } + b->cache[0] = sp; + } + } +#else + get_match(unixname, pp-1); +#endif +} + +int fn_os2_match(uint8 *s, uint8 *p, int soptions) +/* OS/2 name matching routine */ +{ + int pc, sc; + uint state = 0; + int anf, ende; + int not = 0; + uint found = 0; + while ( (pc = *p++) != 0) { + if (!(soptions & VOL_OPTION_IGNCASE)) { + if (soptions & VOL_OPTION_DOWNSHIFT){ /* only downshift chars */ + if (*s >= 'A' && *s <= 'Z') return(0); + } else { + if (*s >= 'a' && *s <= 'z') return(0); + } + } + switch (state){ + case 0 : + if (pc == 255) { + switch (pc=*p++) { + case 0xaa : + case '*' : pc=3000; break; /* star */ + + case 0xae : + case '.' : pc=1000; break; /* point */ + + case 0xbf : + case '?' : pc=2000; break; /* ? */ + + default : break; + } + } else if (pc == '\\') continue; + + switch (pc) { + case '.' : + case 1000: if (*s && ('.' != *s++) ) return(0); + break; + + case '?' : + case 2000: if (!*s) return(0); + ++s; + break; + + case '*' : + case 3000: if (!*p) return(1); /* last star */ + while (*s) { + if (fn_os2_match(s, p, soptions) == 1) return(1); + else if (*s=='.' && !*(p+1)) return(0); + ++s; + } + if (*p == '.') return(fn_os2_match(s, p, soptions)); + return(0); + + case '[' : if ( (*p == '!') || (*p == '^') ){ + ++p; + not = 1; + } + state = 1; + continue; + + default : if (soptions & VOL_OPTION_IGNCASE) { + if ( pc != *s && + ( (!isalpha(pc)) + || (!isalpha(*s)) + || (pc | 0x20) != (*s | 0x20) ) ) + return(0); + } else if (pc != *s) return(0); + ++s; + break; + + } /* switch */ + break; + + case 1 : /* Bereich von Zeichen */ + sc = *s++; + found = not; + if (!sc) return(0); + do { + if (pc == '\\') pc = *(p++); + if (!pc) return(0); + anf = pc; + if (*p == '-' && *(p+1) != ']'){ + ende = *(++p); + p++; + } + else ende = anf; + if (found == not) { /* only if not found */ + if (anf == sc || (anf <= sc && sc <= ende)) + found = !not; + } + } while ((pc = *(p++)) != ']'); + if (! found ) return(0); + not = 0; + found = 0; + state = 0; + break; + + default : break; + } /* switch */ + } /* while */ + if (*s=='.' && *(s+1)=='\0') return(1); + return ( (*s) ? 0 : 1); +} + + +#endif diff --git a/nameos2.h b/nameos2.h new file mode 100644 index 0000000..489ff1a --- /dev/null +++ b/nameos2.h @@ -0,0 +1,14 @@ +/* + * nameos2.h: 08-Aug-96 + * + * (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany + */ +#ifndef _NAMEOS2_H_ +#define _NAMEOS2_H_ +#if WITH_NAME_SPACE_CALLS + +extern void mangle_os2_name(NW_VOL *vol, uint8 *unixname, uint8 *pp); +extern int fn_os2_match(uint8 *s, uint8 *p, int soptions); + +#endif +#endif diff --git a/namspace.c b/namspace.c index 5b8a978..7b360ae 100644 --- a/namspace.c +++ b/namspace.c @@ -1,4 +1,4 @@ -/* namspace.c 17-Jul-96 : NameSpace Services, mars_nwe */ +/* namspace.c 09-Aug-96 : NameSpace Services, mars_nwe */ /* !!!!!!!!!!!! NOTE !!!!!!!!!! */ /* Its very dirty till now. */ @@ -33,6 +33,7 @@ #include "nwfile.h" #include "unxfile.h" #include "namspace.h" +#include "nameos2.h" #if WITH_NAME_SPACE_CALLS @@ -45,13 +46,13 @@ typedef struct { int namespace; /* which namespace do we use here*/ struct stat statb; /* stat buff */ uint8 *fn; /* points to last entry of path */ - uint8 path[512]; /* path + fn */ + uint8 path[512]; /* path + fn, unixfilename */ } N_NW_PATH; typedef struct { DIR *fdir; /* for dir searches */ uint8 *kpath; /* points one after unixname */ - uint8 *unixname; /* is allocates fullname of path */ + uint8 *unixname; /* allocated fullname of path */ /* + 257 Byte for filename. */ } DIR_SEARCH_STRUCT; @@ -69,11 +70,12 @@ static int anz_dbe = 0; static void init_nwpath(N_NW_PATH *nwpath, int namespace) { - nwpath->volume = -1; - nwpath->namespace = namespace; - nwpath->has_wild = 0; - nwpath->fn = nwpath->path; - *(nwpath->path) = '\0'; + nwpath->volume = -1; + nwpath->namespace = namespace; + nwpath->has_wild = 0; + nwpath->fn = nwpath->path; + *(nwpath->path) = '\0'; + nwpath->statb.st_ino = -1; } static void norm_nwpath_fn(N_NW_PATH *nwpath) @@ -122,6 +124,7 @@ static char *xnwpath_2_unix(N_NW_PATH *nwpath, int modus, if (p > unixname+1) { --p; --len; + --m; } else { *p++ = '.'; ++len; @@ -136,9 +139,12 @@ static char *xnwpath_2_unix(N_NW_PATH *nwpath, int modus, len += len_extra; } *p = '\0'; - if (nwpath->namespace == NAME_DOS - && nw_volumes[volume].options & VOL_OPTION_DOWNSHIFT) - downstr((uint8*)pp); +#if 0 + if (nwpath->namespace == NAME_DOS) { + if (nw_volumes[volume].options & VOL_OPTION_DOWNSHIFT) + downstr((uint8*)pp); + } +#endif } if (!allocate_extra) { xfree(last_unixname); @@ -212,29 +218,38 @@ static int base_open_seek_dir(DIR_BASE_ENTRY *dbe, uint32 offset) static DIR_BASE_ENTRY *allocate_dbe_p(int namespace) /* returns new allocated dir_base_entry */ { - int j=-1; + int j =-1; int to_use=-1; DIR_BASE_ENTRY **pdbe=(DIR_BASE_ENTRY**) NULL; - /* if (namespace) return(NULL); /* TODO: more namespaces */ - while (++j < anz_dbe && NULL != *(pdbe = &(dir_base[j])) ){ - if (to_use < 0 && !(*pdbe)->basehandle && !(*pdbe)->locked) to_use=j; + if (!(*pdbe)->basehandle && j > 3 && !(*pdbe)->locked) to_use=j; + if ((*pdbe)->slot != j) { + XDPRINTF((0,0, "slot %d = %d", j, (*pdbe)->slot)); + } } if (j == anz_dbe) { - if (anz_dbe == MAX_DIR_BASE_ENTRIES) { /* return(-0xff); */ - if (to_use > -1) j=to_use; - else while (j--) { + if (anz_dbe == MAX_DIR_BASE_ENTRIES) { + if (to_use > -1) { + j = to_use; pdbe = &(dir_base[j]); - if (!(*pdbe)->locked) break; /* remove last not locked from list */ + } else { + while (j--) { + pdbe = &(dir_base[j]); + if (!(*pdbe)->locked) break; /* remove last not locked from list */ + } } free_dbe_ptr(*pdbe); } else pdbe = &(dir_base[anz_dbe++]); } - + while (j--) { + *pdbe = dir_base[j]; + if (*pdbe) (*pdbe)->slot=j+1; + pdbe--; + } *pdbe = (DIR_BASE_ENTRY*)xcmalloc(sizeof(DIR_BASE_ENTRY)); - (*pdbe)->slot = j; + (*pdbe)->slot = 0; init_nwpath(&((*pdbe)->nwpath), namespace); return(*pdbe); } @@ -260,31 +275,30 @@ static int touch_handle_entry_p(DIR_BASE_ENTRY *dbe) /* routine touchs this entry and returns the new offset */ { int dbase = (NULL != dbe) ? dbe->slot : -1; - XDPRINTF((4, 0, "touch_handle_entry entry dbase=%d", dbase)); - if (dbase > 2) { + XDPRINTF((4, 0, "touch_handle_entry_p entry dbase=%d", dbase)); + if (dbase > 4) { DIR_BASE_ENTRY **dbp=&(dir_base[dbase]); DIR_BASE_ENTRY **dbpq=dbp; int aktbase=dbase; + while (dbase--) { --dbpq; - if ( dbase < (MAX_DIR_BASE_ENTRIES/2) || !(*dbpq) || !(*dbpq)->locked) { + if (!(*dbpq) || !(*dbpq)->locked) { *dbp = *dbpq; if (*dbp) (*dbp)->slot = dbase+1; dbp=dbpq; aktbase=dbase; } } + dbase = aktbase; dir_base[dbase] = dbe; dbe->slot = dbase; } - XDPRINTF((4, 0, "touch_handle_entry return dbase=%d", dbase)); + XDPRINTF((4, 0, "touch_handle_entry_p return dbase=%d", dbase)); return(dbase); } -#define touch_handle_entry(dbase) \ - touch_handle_entry_p(((dbase) > -1 && (dbase) < anz_dbe) ? dir_base[dbase] : NULL) - char *debug_nwpath_name(N_NW_PATH *p) /* only for debugging */ { @@ -294,10 +308,11 @@ char *debug_nwpath_name(N_NW_PATH *p) int len; if (nw_get_volume_name(p->volume, volname) < 1) sprintf(volname, "<%d=NOT-OK>", (int)p->volume); - len = strlen(volname) + strlen(p->path) + strlen(p->fn) + 30; + len = strlen(volname) + strlen(p->path) + strlen(p->fn) + 40; xfree(nwpathname); nwpathname=xmalloc(len); - sprintf(nwpathname, "`%s:%s`,fn=`%s`", volname, p->path, p->fn); + sprintf(nwpathname, "%d `%s:%s`,fn=`%s`", + p->namespace, volname, p->path, p->fn); #else static char nwpathname[2]; nwpathname[0]='\0'; @@ -322,13 +337,17 @@ static int get_comp_pathes_size(NW_HPATH *nwp, uint8 *pp_pathes) static int add_hpath_to_nwpath(N_NW_PATH *nwpath, NW_HPATH *nwp, uint8 *pp_pathes) -/* Routine adds nwp to nwpath */ -/* nwpath must be setup correctly before entry */ -/* return > -1 if ok */ +/* + * Routine adds nwp to nwpath + * nwpath must be filled correctly before entry + * return > -1 if ok + */ { int result = 0; int k = -1; - uint8 *pp = nwpath->path+strlen(nwpath->path); + int npbeg = strlen(nwpath->path); + uint8 *pp = nwpath->path+npbeg; + XDPRINTF((2, 0, "entry add_hpath_to_nwpath: %s", debug_nwpath_name(nwpath))); @@ -339,20 +358,23 @@ static int add_hpath_to_nwpath(N_NW_PATH *nwpath, if (!k && nwpath->volume == -1) { /* first component is volume */ if ((nwpath->volume=nw_get_volume_number(p, len)) < 0) { + /* something not OK */ result = nwpath->volume; goto leave_build_nwpath; } + pp = nwpath->path; + *pp = '\0'; + npbeg = 0; } else { /* here is path (+ fn ) */ int i=len; if (pp > nwpath->path) { /* not the first entry */ - *pp = '/'; + *pp = '/'; /* we must add a slash */ *++pp = '\0'; } + while (i--) { if (*p == 0xae) *pp++ = '.'; - else if (*p > 0x60 && *p < 0x7b && nwpath->namespace == NAME_DOS) { - *pp++ = *p - 0x20; /* all is upshift */ - } else if (*p == 0xaa || *p == '*' ) { + else if (*p == 0xaa || *p == '*' ) { *pp++ = '*'; nwpath->has_wild++; } else if (*p == 0xbf || *p == '?' ) { @@ -360,14 +382,15 @@ static int add_hpath_to_nwpath(N_NW_PATH *nwpath, nwpath->has_wild++; } else if (*p == '/' || *p == '\\') { *pp++ = '/'; - } else if (*p == ':') { /* extract volume */ + } else if (*p == ':') { /* extract volumename */ int vlen = (int) (pp - nwpath->path); if ((nwpath->volume=nw_get_volume_number(nwpath->path, vlen)) < 0) { result = nwpath->volume; goto leave_build_nwpath; } - pp=nwpath->path; - *pp='\0'; + pp = nwpath->path; + *pp = '\0'; + npbeg = 0; } else *pp++ = *p; p++; } /* while */ @@ -376,6 +399,34 @@ static int add_hpath_to_nwpath(N_NW_PATH *nwpath, } /* while */ if (nwpath->volume < 0) result=-0x9c; leave_build_nwpath: + if (!result) { + NW_VOL *v = &nw_volumes[nwpath->volume]; + if (nwpath->namespace == NAME_DOS || nwpath->namespace == NAME_OS2) { + if (v->options & VOL_OPTION_IGNCASE) { + int nplen= (int)(pp - nwpath->path) - npbeg; + uint8 unixname[1024]; /* should be enough */ + memcpy(unixname, v->unixname, v->unixnamlen); + strcpy(unixname+v->unixnamlen, nwpath->path); + pp=unixname+v->unixnamlen+npbeg; + if (nwpath->namespace == NAME_OS2) { + mangle_os2_name(v, unixname, pp); + if (nplen > 0) + memcpy(nwpath->path+npbeg, pp, nplen); + XDPRINTF((5,0, "Mangle OS/2 unixname='%s'", unixname)); + } else if (nwpath->namespace == NAME_DOS) { + mangle_dos_name(v, unixname, pp); + if (nplen > 0) + memcpy(nwpath->path+npbeg, pp, nplen); + XDPRINTF((5,0, "Mangle DOS unixname='%s'", unixname)); + } + } else { + if (v->options & VOL_OPTION_DOWNSHIFT) + downstr(nwpath->path); + else + upstr(nwpath->path); + } + } + } XDPRINTF((2, 0, "add_hpath_to_nwpath: result=0x%x, %s", result, debug_nwpath_name(nwpath))); return(result); @@ -391,7 +442,7 @@ static int nwp_stat(N_NW_PATH *nwpath, char *debstr) xdebstr[0]='\0'; debstr = xdebstr; } - XDPRINTF((4, 0, "nwp_stat:%s:%d,`%s`", + XDPRINTF((4, 0, "nwp_stat:%s:%d,%s", debstr, result, debug_nwpath_name(nwpath))); @@ -417,7 +468,7 @@ static uint32 name_2_base(N_NW_PATH *nwpath, int namespace, int no_stat) } static int add_dbe_entry(int namspace, int volume, - uint32 basehandle, uint8 *path) + uint32 basehandle, uint8 *path, struct stat *stb) { DIR_BASE_ENTRY *dbe=allocate_dbe_p(namspace); if (dbe) { @@ -427,38 +478,47 @@ static int add_dbe_entry(int namspace, int volume, strcpy(dbe->nwpath.path, path); norm_nwpath_fn(&(dbe->nwpath)); } + if (stb) + memcpy(&(dbe->nwpath.statb), stb, sizeof(struct stat)); + return(touch_handle_entry_p(dbe)); - } else return(-0x9b); + } + return(-0x9b); } static int find_base_entry(int volume, uint32 basehandle) { int k=-1; DEV_NAMESPACE_MAP dnm; - ino_t ino = nw_vol_handle_to_inode(volume, basehandle, &dnm); + ino_t ino; + if (!basehandle) return(-0x9b); + + ino = nw_vol_handle_to_inode(volume, basehandle, &dnm); + while (++k < anz_dbe) { DIR_BASE_ENTRY *e=dir_base[k]; if ( (DIR_BASE_ENTRY*)NULL != e - && volume == e->nwpath.volume - && ( (basehandle == e->basehandle) - || (ino == e->nwpath.statb.st_ino)) ) + && volume == e->nwpath.volume + && ino == e->nwpath.statb.st_ino + && dnm.dev == e->nwpath.statb.st_dev) return(k); } + /* now we test whether it is the root of volume */ - if (0 < (ino = nw_vol_handle_to_inode(volume, basehandle, &dnm)) - && ino == get_volume_inode(volume) ) { - /* its the handle of the volumes root */ - return(add_dbe_entry(dnm.namespace, volume, basehandle, NULL)); + if (0 < ino) { + struct stat statb; + if (ino == get_volume_inode(volume, &statb)) { + /* its the handle of the volumes root */ + return(add_dbe_entry(dnm.namespace, volume, basehandle, NULL, &statb)); + } } return(-0x9b); } -static int insert_get_base_entry(DIR_BASE_ENTRY *dbe, - int namespace, int creatmode) +static int insert_get_base_entry(N_NW_PATH *nwpath, + int namespace, int creatmode) { - N_NW_PATH *nwpath = &(dbe->nwpath); uint32 basehandle = name_2_base(nwpath, namespace, 0); - if (!basehandle && creatmode) { /* now creat the entry (file or dir) */ int result = 0; char *unname = nwpath_2_unix(nwpath, 2); @@ -478,22 +538,18 @@ static int insert_get_base_entry(DIR_BASE_ENTRY *dbe, if (result) return(result); basehandle = name_2_base(nwpath, namespace, 0); } - if (basehandle) { int k=-1; while (++k < anz_dbe) { DIR_BASE_ENTRY *e=dir_base[k]; if ( (DIR_BASE_ENTRY*)NULL != e && basehandle == e->basehandle - && nwpath->volume == e->nwpath.volume) { - free_dbe_p(e); - dbe->basehandle = basehandle; - return(touch_handle_entry_p(dbe)); - } + && nwpath->volume == e->nwpath.volume) + return(touch_handle_entry_p(e)); } /* while */ /* now i know that it's a new base entry */ - dbe->basehandle = basehandle; - return(touch_handle_entry_p(dbe)); + return(add_dbe_entry(namespace, nwpath->volume, + basehandle, nwpath->path, &(nwpath->statb))); } return(-0xff); /* invalid path = -0x9c, -0xff no matching files */ } @@ -501,46 +557,52 @@ static int insert_get_base_entry(DIR_BASE_ENTRY *dbe, static int build_base(int namespace, NW_HPATH *nwp, uint8 *pathes, - DIR_BASE_ENTRY *dbe, int mode, uint8 *rets) -/* routine returns the actual dbe entry offset or */ -/* < 0 if error */ -/* if mode == 1, then last path element will be ignored and will be put */ -/* into the rets variable */ +/* + * routine returns the actual dbe entry offset or + * < 0 if error + * if mode == 1, then last path element will be ignored + * and will be put into the rets variable + */ + { - N_NW_PATH *nwpath=&(dbe->nwpath); int result=0; - if (!nwp->flag) { /* short handle */ + N_NW_PATH loc_nwpath; + N_NW_PATH *nwpath=&loc_nwpath; + init_nwpath(nwpath, namespace); + if (!nwp->flag) { /* short directory handle */ int dir_handle = (int)nwp->base[0]; NW_DIR *dir = (dir_handle > 0 && dir_handle <= used_dirs) ? &(dirs[dir_handle-1]) : NULL; if (dir && dir->inode) { - int llen = strlen(dir->path); - nwpath->volume = dir->volume; + int llen = strlen(dir->path); + uint8 *p = nwpath->path+llen; + nwpath->volume = dir->volume; memcpy(nwpath->path, dir->path, llen+1); - if (llen && *(nwpath->path + llen -1) == '/') - *(nwpath->path+llen-1) = '\0'; + if (llen && *(p-1) == '/') + *(p-1) = '\0'; result = (nwpath->volume > -1) ? 0 : -0x98; } else result = -0x9b; - XDPRINTF((4, 0, "build_base with dir_handle=%d, result=x%x", + XDPRINTF((4, 0, "build_base with short_dir_handle=%d, result=0x%x", dir_handle, result)); } else if (nwp->flag == 1) { /* basehandle */ if (-1 < (result = find_base_entry(nwp->volume, GET_32(nwp->base)))) { - DIR_BASE_ENTRY *e=dir_base[result]; + DIR_BASE_ENTRY *e = dir_base[result]; nwpath->volume = nwp->volume; strcpy(nwpath->path, e->nwpath.path); result = 0; } else if (!GET_32(nwp->base)) { - nwpath->volume = nwp->volume; - nwpath->path[0]='\0'; + nwpath->volume = nwp->volume; + nwpath->path[0] = '\0'; result = 0; } - XDPRINTF((4, 0, "build_base with basehandle=%ld, result=x%x", + XDPRINTF((4, 0, "build_base with basehandle=%ld, result=0x%x", GET_32(nwp->base), result)); - } else if (nwp->flag != 0xff) result=-0xff; + } else if (nwp->flag != 0xff) + result=-0xff; if (!result) { nwpath->namespace = namespace; if ((result = add_hpath_to_nwpath(nwpath, nwp, pathes)) > -1) { @@ -556,7 +618,7 @@ static int build_base(int namespace, } } nwpath->fn = (pp) ? (uint8*)pp+1 : nwpath->path; - result = insert_get_base_entry(dbe, namespace, 0); + result = insert_get_base_entry(nwpath, namespace, 0); } } return(result); @@ -569,22 +631,19 @@ int nw_generate_dir_path(int namespace, /* returns Volume Number >=0 or errcode < 0 if error */ { - DIR_BASE_ENTRY *dbe=allocate_dbe_p(namespace); - int result = -0xfb; - if (NULL != dbe) { - if ((result = build_base(namespace, nwp, nwp->pathes, dbe, 0, NULL)) > -1) { - U32_TO_32(dbe->basehandle, ns_dir_base); /* LOW - HIGH */ - if (namespace != NAME_DOS) { - U32_TO_32(name_2_base(&(dbe->nwpath), NAME_DOS, 1), dos_dir_base); - } else { - U32_TO_32(dbe->basehandle, dos_dir_base); - } - XDPRINTF((3, 0, "nw_generate_dir_path path=%s, result=%d, basehandle=0x%x", - debug_nwpath_name(&(dbe->nwpath)), result, dbe->basehandle)); - result= dbe->nwpath.volume; - } else free_dbe_p(dbe); - } - if (result < 0) { + int result = build_base(namespace, nwp, nwp->pathes, 0, NULL); + if (result > -1) { + DIR_BASE_ENTRY *dbe=dir_base[result]; + U32_TO_32(dbe->basehandle, ns_dir_base); /* LOW - HIGH */ + if (namespace != NAME_DOS) { + U32_TO_32(name_2_base(&(dbe->nwpath), NAME_DOS, 1), dos_dir_base); + } else { + U32_TO_32(dbe->basehandle, dos_dir_base); + } + XDPRINTF((3, 0, "nw_generate_dir_path path=%s, result=%d, basehandle=0x%x", + debug_nwpath_name(&(dbe->nwpath)), result, dbe->basehandle)); + result= dbe->nwpath.volume; + } else { XDPRINTF((3, 0, "nw_generate_dir_path NOT OK result=-0x%x", -result)); } return(result); @@ -600,6 +659,7 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p) U32_TO_32(stb->st_size, p); } p += 4; + if (infomask & INFO_MSK_ATTRIBUTE_INFO) { uint32 mask=0L; if (S_ISDIR(stb->st_mode)) mask |= FILE_ATTR_DIR; @@ -608,16 +668,19 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p) U16_TO_16((uint16)(mask & 0xFFFF), p); p +=2; } else p+=6; + if (infomask & INFO_MSK_DATA_STREAM_SIZE) { U32_TO_32(stb->st_size, p); } p +=4; + if (infomask & INFO_MSK_TOTAL_DATA_STREAM_SIZE) { U32_TO_32(stb->st_size, p); p +=4; U16_TO_16(0, p); p +=2; } else p+=6; + if (infomask & INFO_MSK_CREAT_INFO) { un_time_2_nw(stb->st_mtime, p, 0); p +=2; @@ -626,6 +689,7 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p) U32_TO_32(1, p); p +=4; } else p+=8; + if (infomask & INFO_MSK_MODIFY_INFO) { un_time_2_nw(stb->st_mtime, p, 0); p +=2; @@ -636,6 +700,7 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p) un_date_2_nw(stb->st_atime, p, 0); /* access date */ p +=2; } else p+=10; + if (infomask & INFO_MSK_ARCHIVE_INFO) { un_time_2_nw(0, p, 0); p +=2; @@ -644,18 +709,25 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p) U32_TO_32(0, p); p +=4; } else p+=8; + if (infomask & INFO_MSK_RIGHTS_INFO) { U16_TO_16(0, p); } p +=2; + if (infomask & INFO_MSK_DIR_ENTRY_INFO) { U32_TO_32(dbe->basehandle, p); p +=4; +#if 0 U32_TO_32(dbe->basehandle, p); +#else + U32_TO_32(name_2_base(nwpath, NAME_DOS, 1), p); +#endif p +=4; U32_TO_32(nwpath->volume, p); p +=4; } else p+=12; + if (infomask & INFO_MSK_EXT_ATTRIBUTES) { U32_TO_32(0, p); /* Ext Attr Data Size */ p +=4; @@ -664,10 +736,12 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p) U32_TO_32(0, p); /* Ext Attr Key Size */ p +=4; } else p+=12; + if (infomask & INFO_MSK_NAME_SPACE_INFO){ U32_TO_32(0, p); /* Creator of the name space number */ } p +=4; + /* ---------------------------------------------- */ if (infomask & INFO_MSK_ENTRY_NAME) { *p = (uint8) strlen(nwpath->fn); @@ -690,16 +764,14 @@ int nw_optain_file_dir_info(int namespace, NW_HPATH *nwp, * But the _valid_ info is. */ { - DIR_BASE_ENTRY *dbe = allocate_dbe_p(namespace); - int result = -0xfb; - if (NULL != dbe) { - if ((result = build_base(namespace, nwp, nwp->pathes, dbe, 0, NULL)) > -1) { - nwp_stat(&(dbe->nwpath), "nw_optain_file_dir_info"); - result = build_dir_info(dbe, infomask, responsedata); - } else free_dbe_p(dbe); - } - if (result < 0) { - XDPRINTF((3, 0, "nw_optain_file_dir_info NOT OK result=-0x%x", -result)); + int result = build_base(namespace, nwp, nwp->pathes, 0, NULL); + if (result > -1) { + DIR_BASE_ENTRY *dbe=dir_base[result]; + nwp_stat(&(dbe->nwpath), "nw_optain_file_dir_info"); + result = build_dir_info(dbe, infomask, responsedata); + } else { + XDPRINTF((3, 0, "nw_optain_file_dir_info NOT OK result=-0x%x", + -result)); } return(result); } @@ -709,47 +781,40 @@ static int nw_init_search(int namespace, uint8 *pathes, uint8 *responsedata) { - DIR_BASE_ENTRY *dbe=allocate_dbe_p(namespace); - int result = -0xfb; - if (NULL != dbe) { - if ((result = build_base(namespace, nwp, pathes, dbe, 0, NULL)) > -1) { - result = base_open_seek_dir(dbe, 0L); - if (result > -1) { - *responsedata++ = dbe->nwpath.volume; - U32_TO_32(dbe->basehandle, responsedata); - responsedata+=4; - U32_TO_32(0L, responsedata); /* searchsequenz */ - result = 9; - } - XDPRINTF((3, 0, "nw_init_search path=%s, result=%d, basehandle=0x%x", - debug_nwpath_name(&(dbe->nwpath)), result, dbe->basehandle)); - } else free_dbe_p(dbe); - } - if (result < 0) { + int result = build_base(namespace, nwp, pathes, 0, NULL); + if (result > -1) { + DIR_BASE_ENTRY *dbe=dir_base[result]; + result = base_open_seek_dir(dbe, 0L); + if (result > -1) { + *responsedata++ = dbe->nwpath.volume; + U32_TO_32(dbe->basehandle, responsedata); + responsedata+=4; + U32_TO_32(0L, responsedata); /* searchsequenz */ + result = 9; + } + XDPRINTF((3, 0, "nw_init_search path=%s, result=%d, basehandle=0x%x", + debug_nwpath_name(&(dbe->nwpath)), result, dbe->basehandle)); + } else { XDPRINTF((3, 0, "nw_init_search NOT OK result=%d", result)); } return(result); } -int get_add_new_entry(DIR_BASE_ENTRY *qbe, uint8 *path, int creatmode) + +static int get_add_new_entry(DIR_BASE_ENTRY *qbe, int namespace, + uint8 *path, int creatmode) { - DIR_BASE_ENTRY *dbe=allocate_dbe_p(qbe->nwpath.namespace); - if (NULL != dbe) { - N_NW_PATH *nwpath=&(dbe->nwpath); - int result = -0x9c; - nwpath->volume = qbe->nwpath.volume; - strcpy(nwpath->path, qbe->nwpath.path); - nwpath->fn = nwpath->path+strlen(nwpath->path); - if (nwpath->fn > nwpath->path && *(nwpath->fn-1) != '/') { - *(nwpath->fn) = '/'; - *(++nwpath->fn) = '\0'; - } - strcpy(nwpath->fn, path); - result = insert_get_base_entry(dbe, qbe->nwpath.namespace, creatmode); - if (result < 0) free_dbe_p(dbe); - return(result); + N_NW_PATH nwpath; + nwpath.volume = qbe->nwpath.volume; + nwpath.namespace = namespace; + strcpy(nwpath.path, qbe->nwpath.path); + nwpath.fn = nwpath.path+strlen(nwpath.path); + if (nwpath.fn > nwpath.path && *(nwpath.fn-1) != '/') { + *(nwpath.fn) = '/'; + *(++nwpath.fn) = '\0'; } - return(-1); + strcpy(nwpath.fn, path); + return(insert_get_base_entry(&nwpath, namespace, creatmode)); } static int namespace_fn_match(uint8 *s, uint8 *p, int namespace) @@ -860,25 +925,41 @@ int nw_search_file_dir(int namespace, int datastream, int vol_options = get_volume_options(volume, 0); dbe->locked++; strmaxcpy(entry, path, min(255, len)); - if (namespace == NAME_DOS && (vol_options & VOL_OPTION_DOWNSHIFT)) - downstr(entry); - XDPRINTF((5,0,"nw_search_file_dir searchpath=%s", entry)); + + if ( (namespace == NAME_DOS || namespace == NAME_OS2) + && !(vol_options & VOL_OPTION_IGNCASE) ) { + if (vol_options & VOL_OPTION_DOWNSHIFT) { + downstr(entry); + } else { + upstr(entry); + } + } + + XDPRINTF((5,0,"nw_search_file_dir namspace=%d, searchpath='%s'", + namespace, entry)); while ((dirbuff = readdir(ds->fdir)) != (struct dirent*)NULL){ if (dirbuff->d_ino) { uint8 *name=(uint8*)(dirbuff->d_name); - XDPRINTF((10,0,"nw_search_file_dir Name=%s", + int flag; + XDPRINTF((5,0,"nw_search_file_dir Name='%s'", name)); - if ( (name[0] != '.' && ( - (!strcmp(name, entry)) - || (entry[0] == '*' && entry[1] == '\0' && namespace != NAME_DOS) - || (namespace == NAME_DOS) - ? fn_match(name, entry, vol_options) - : namespace_fn_match(name, entry, namespace) ))) { + + if (namespace == NAME_DOS) { + flag = (*name != '.' && fn_dos_match(name, entry, vol_options)); + } else if (namespace == NAME_OS2) { + flag = (*name != '.' || (*(name+1) != '.' && *(name+1) != '\0' )) + && fn_os2_match(name, entry, vol_options); + } else { + flag = (!strcmp(name, entry) + || namespace_fn_match(name, entry, namespace)); + } + + if (flag) { strcpy(ds->kpath, name); XDPRINTF((5,0,"nw_search_file_dir Name found=%s unixname=%s", name, ds->unixname)); if (!stat(ds->unixname, &statb)) { - int flag= (searchattrib & W_SEARCH_ATTR_ALL) == W_SEARCH_ATTR_ALL; + flag= (searchattrib & W_SEARCH_ATTR_ALL) == W_SEARCH_ATTR_ALL; if (!flag) { if (S_ISDIR(statb.st_mode)) flag=(searchattrib & FILE_ATTR_DIR); @@ -887,18 +968,21 @@ int nw_search_file_dir(int namespace, int datastream, } if (flag) { strcpy(entry, name); - if (namespace == NAME_DOS && - (vol_options & VOL_OPTION_DOWNSHIFT)) upstr(entry); - if ((dest_entry = get_add_new_entry(dbe, entry, 0)) > -1) + if ((dest_entry = get_add_new_entry(dbe, namespace, entry, 0)) > -1) break; + } else { + XDPRINTF((10, 0, "type = %s not ok searchattrib=0x%x", + S_ISDIR(statb.st_mode) ? "DIR" :"FILE" ,searchattrib)); } } else { XDPRINTF((5,0,"nw_search_file_dir stat error")); } + *(ds->kpath) = '\0'; } } /* if */ } /* while */ *(ds->kpath) = '\0'; + if (dest_entry > -1) { DIR_BASE_ENTRY *dest_dbe=dir_base[dest_entry]; (void) nwp_stat(&(dest_dbe->nwpath), "nw_search_file_dir"); @@ -918,6 +1002,8 @@ int nw_search_file_dir(int namespace, int datastream, } else result=-0xff; /* no files matching */ dbe->locked=0; + if (get_volume_options(dbe->nwpath.volume,1) & VOL_OPTION_REMOUNT) + free_dbe_dir(dbe); } /* if result */ } return(result); @@ -931,59 +1017,54 @@ static int nw_open_creat_file_or_dir(int namespace, NW_HPATH *nwp, uint8 *pathes, uint8 *responsedata) { - DIR_BASE_ENTRY *dbe=allocate_dbe_p(namespace); - int result = -0xfb; - if (NULL != dbe) { - int exist=-1; - uint8 last_part[258]; - *last_part='\0'; - if ((result = build_base(namespace, nwp, pathes, dbe, 0, NULL)) > -1) { - exist = result; - } else if (opencreatmode & OPC_MODE_CREAT) { - result = build_base(namespace, nwp, pathes, dbe, 1, last_part); - XDPRINTF((5, 0, "nw_open_c... result=%d, last_part='%s'", + int result = build_base(namespace, nwp, pathes, 0, NULL); + int exist = result; + uint8 last_part[258]; + *last_part='\0'; + if (result < 0 && (opencreatmode & OPC_MODE_CREAT)) { /* do not exist */ + result = build_base(namespace, nwp, pathes, 1, last_part); + XDPRINTF((5, 0, "nw_open_c... result=%d, last_part='%s'", result, last_part)); - if (result > -1) { - result = get_add_new_entry(dbe, last_part, - (creatattrib & FILE_ATTR_DIR) ? FILE_ATTR_DIR : 1); - if (result > -1) - dbe = dir_base[result]; - } - } - if (result > -1) { - uint32 fhandle=0L; - int actionresult=0; - if (exist < 0) actionresult |= OPC_ACTION_CREAT; - if (!(creatattrib & FILE_ATTR_DIR)) { - int creatmode=0; /* open */ - int attrib=0; - if (opencreatmode & (OPC_MODE_OPEN | OPC_MODE_CREAT) ) { - if (opencreatmode & OPC_MODE_CREAT) { + if (result > -1) + result = get_add_new_entry(dir_base[result], namespace, last_part, + (creatattrib & FILE_ATTR_DIR) ? FILE_ATTR_DIR : 1); + } + if (result > -1) { + uint32 fhandle=0L; + int actionresult=0; + DIR_BASE_ENTRY *dbe=dir_base[result]; + if (exist < 0) actionresult |= OPC_ACTION_CREAT; + if (!(creatattrib & FILE_ATTR_DIR)) { + int creatmode=0; /* open */ + int attrib=0; + if (opencreatmode & (OPC_MODE_OPEN | OPC_MODE_CREAT) ) { + if (opencreatmode & OPC_MODE_CREAT) { #if 0 - if (exist > -1 && !(opencreatmode & OPC_MODE_REPLACE)) - creatmode=2; - else + if (exist > -1 && !(opencreatmode & OPC_MODE_REPLACE)) + creatmode=2; + else #endif - creatmode = 1; - } - if ((result = file_creat_open(dbe->nwpath.volume, - nwpath_2_unix(&dbe->nwpath, 2), &(dbe->nwpath.statb), - attrib, access_rights, creatmode)) > -1) { - fhandle = (uint32) result; - actionresult |= OPC_ACTION_OPEN; /* FILE OPEN */ - if (exist > -1 && (opencreatmode & OPC_MODE_REPLACE)) - actionresult |= OPC_ACTION_REPLACE; /* FILE REPLACED */ - } - } else result=-0xff; - } else if (exist > -1) result=-0x84; - if (result > -1) { - U32_TO_BE32(fhandle, responsedata); - responsedata += 4; - *responsedata =(uint8) actionresult; - responsedata++ ; - result = 5 + build_dir_info(dbe,infomask, responsedata); - } - } else free_dbe_p(dbe); + creatmode = 1; + } + if ((result = file_creat_open(dbe->nwpath.volume, + nwpath_2_unix(&dbe->nwpath, 2), &(dbe->nwpath.statb), + attrib, access_rights, creatmode)) > -1) { + fhandle = (uint32) result; + actionresult |= OPC_ACTION_OPEN; /* FILE OPEN */ + if (exist > -1 && (opencreatmode & OPC_MODE_REPLACE)) + actionresult |= OPC_ACTION_REPLACE; /* FILE REPLACED */ + } + } else result=-0xff; + } else if (exist > -1) result=-0x84; + + if (result > -1) { + U32_TO_BE32(fhandle, responsedata); + responsedata += 4; + *responsedata =(uint8) actionresult; + /* responsedata++ ; */ + responsedata+=2; + result = 6 + build_dir_info(dbe,infomask, responsedata); + } } XDPRINTF((3, 0, "nw_open_creat mode=0x%x, creatattr=0x%x, access=0x%x, attr=0x%x, result=%d", opencreatmode, creatattrib, access_rights, attrib, result)); @@ -993,30 +1074,28 @@ static int nw_open_creat_file_or_dir(int namespace, static int nw_delete_file_dir(int namespace, int searchattrib, NW_HPATH *nwp) { - DIR_BASE_ENTRY *dbe = allocate_dbe_p(namespace); - int result = -0xfb; - if (dbe != NULL) { - if ((result = build_base(namespace, nwp, nwp->pathes, dbe, 0, NULL)) > -1) { - uint8 *unname=(uint8*)nwpath_2_unix(&(dbe->nwpath), 2); - if (get_volume_options(dbe->nwpath.volume, 1) & + int result = build_base(namespace, nwp, nwp->pathes, 0, NULL); + if (result > -1) { + DIR_BASE_ENTRY *dbe=dir_base[result]; + uint8 *unname=(uint8*)nwpath_2_unix(&(dbe->nwpath), 2); + if (get_volume_options(dbe->nwpath.volume, 1) & VOL_OPTION_READONLY) result = -0x8a; - else { - if (S_ISDIR(dbe->nwpath.statb.st_mode)) { - free_dbe_p(dbe); - result = rmdir(unname); - } else { - if (-1 < (result = unlink(unname))) - free_dbe_p(dbe); - } - if (result < 0) { - switch (errno) { - case EEXIST: result=-0xa0; /* dir not empty */ - default: result=-0x8a; /* No privilegs */ - } - } else - result = 0; + else { + if (S_ISDIR(dbe->nwpath.statb.st_mode)) { + free_dbe_p(dbe); + result = rmdir(unname); + } else { + if (-1 < (result = unlink(unname))) + free_dbe_p(dbe); } - } else free_dbe_p(dbe); + if (result < 0) { + switch (errno) { + case EEXIST: result=-0xa0; /* dir not empty */ + default: result=-0x8a; /* No privilegs */ + } + } else + result = 0; + } } return(result); } @@ -1024,16 +1103,14 @@ static int nw_delete_file_dir(int namespace, int searchattrib, static int nw_alloc_short_dir_handle(int namespace, int hmode, NW_HPATH *nwp, int task, int *volume) { - DIR_BASE_ENTRY *dbe=allocate_dbe_p(namespace); - int result = -0xfb; - if (NULL != dbe) { - if ((result = build_base(namespace, nwp, nwp->pathes, dbe, 0, NULL)) > -1) { - if (S_ISDIR(dbe->nwpath.statb.st_mode)) { - result=xinsert_new_dir(dbe->nwpath.volume, dbe->nwpath.path, - dbe->nwpath.statb.st_ino, 300, hmode, task); - *volume=dbe->nwpath.volume; - } else result=-0xff; - } else free_dbe_p(dbe); + int result = build_base(namespace, nwp, nwp->pathes, 0, NULL); + if (result > -1) { + DIR_BASE_ENTRY *dbe=dir_base[result]; + if (S_ISDIR(dbe->nwpath.statb.st_mode)) { + result=xinsert_new_dir(dbe->nwpath.volume, dbe->nwpath.path, + dbe->nwpath.statb.st_ino, 300, hmode, task); + *volume=dbe->nwpath.volume; + } else result=-0xff; } return(result); } @@ -1044,16 +1121,15 @@ static int nw_rename_file_dir(int namespace, int searchattrib, int renameflag) { - DIR_BASE_ENTRY *dbe_s = allocate_dbe_p(namespace); - DIR_BASE_ENTRY *dbe_d = (NULL != dbe_s) ? allocate_dbe_p(namespace) : NULL; - int result = -0xfb; - if (dbe_d && - (result = build_base(namespace, nwps, pathes_s, dbe_s, 0, NULL)) > -1) { + int result = build_base(namespace, nwps, pathes_s, 0, NULL); + if (result > -1) { + DIR_BASE_ENTRY *dbe_s = dir_base[result]; uint8 last_part[258]; uint8 *unname_s= (uint8*)nwpath_2_unix1(&(dbe_s->nwpath), 2, 1); - if ((result = build_base(namespace, nwpd, pathes_d, dbe_d, - 1, last_part)) > -1) { + result = build_base(namespace, nwpd, pathes_d, 1, last_part); + if (result > -1) { + DIR_BASE_ENTRY *dbe_d = dir_base[result]; uint8 *unname_d = (uint8*)nwpath_2_unix2(&(dbe_d->nwpath), 0, 1, last_part); @@ -1068,9 +1144,7 @@ static int nw_rename_file_dir(int namespace, else result = unx_mvfile(unname_s, unname_d); } - XDPRINTF((5, 0, "Rename:%d '%s' -> '%s'", result, unname_s, unname_d)); - xfree(unname_d); switch (result) { case 0 : break; @@ -1081,12 +1155,81 @@ static int nw_rename_file_dir(int namespace, } if (!result) { free_dbe_p(dbe_s); - if ((result=get_add_new_entry(dbe_d, last_part, 0)) > -1) + if ((result=get_add_new_entry(dbe_d, namespace, last_part, 0)) > -1) result = 0; } - } else free_dbe_p(dbe_d); + } xfree(unname_s); - } else free_dbe_p(dbe_s); + } + return(result); +} + +static int nw_modify_file_dir(int namespace, + NW_HPATH *nwp, uint8 *path, + int searchattrib, + uint32 infomask, DOS_MODIFY_INFO *dmi) +{ + int result = build_base(namespace, nwp, nwp->pathes, 0, NULL); + if (result > -1) { + DIR_BASE_ENTRY *dbe=dir_base[result]; + uint8 *uname=nwpath_2_unix1(&(dbe->nwpath), 2, 1); + struct stat *stb = &(dbe->nwpath.statb); + if (-1 != (result=stat(uname, stb))){ + struct utimbuf ut; + int do_utime=0; + uint8 datetime[4]; + un_time_2_nw(stb->st_mtime, datetime, 1); + un_date_2_nw(stb->st_mtime, datetime+2, 1); + ut.actime = stb->st_atime; + ut.modtime = stb->st_mtime; + + XDPRINTF((5, 0, "modify datetime 1=%2x,%2x,%2x,%2x", + (int) *datetime, + (int) *(datetime+1), + (int) *(datetime+2), + (int) *(datetime+3))); + + if (infomask & DOS_MSK_MODIFY_DATE || infomask & DOS_MSK_MODIFY_TIME) { +#if 1 + if (infomask & DOS_MSK_MODIFY_TIME){ + datetime[0] = dmi->modified_time[1]; + datetime[1] = dmi->modified_time[0]; + } + + if (infomask & DOS_MSK_MODIFY_DATE) { + datetime[2] = dmi->modified_date[1]; + datetime[3] = dmi->modified_date[0]; + } +#endif + do_utime++; + } else if (infomask & DOS_MSK_CREAT_DATE + || infomask & DOS_MSK_CREAT_TIME) { +#if 1 + if (infomask & DOS_MSK_CREAT_TIME) { + datetime[0] = dmi->created_time[1]; + datetime[1] = dmi->created_time[0]; + } + if (infomask & DOS_MSK_CREAT_DATE) { + datetime[2] = dmi->created_date[1]; + datetime[3] = dmi->created_date[0]; + } +#endif + do_utime++; + } + if (do_utime) { + XDPRINTF((5, 0, "modify datetime 2=%2x,%2x,%2x,%2x", + (int) *datetime, + (int) *(datetime+1), + (int) *(datetime+2), + (int) *(datetime+3))); + + ut.modtime = nw_2_un_time(datetime+2, datetime); + utime(uname, &ut); + } + return(0); + } else result=-0xff; + xfree(uname); + } return(result); } @@ -1167,18 +1310,25 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task) int searchattrib = (int) GET_16(p+2); /* LOW-HI */ uint32 infomask = GET_32(p+4); /* LOW-HI */ NW_HPATH *nwpathstruct = (NW_HPATH *) (p+8); - result = nw_optain_file_dir_info(namespace, nwpathstruct, + result = nw_optain_file_dir_info(namespace, nwpathstruct, destnamspace, searchattrib, infomask, responsedata); } break; - case 0x07 : /* Modify File or Dir Info */ { - - + NW_HPATH nwp; + DOS_MODIFY_INFO dmi; + int searchattrib = (int) GET_16(p+2); + uint32 infomask = GET_32(p+4); /* LOW-HI */ + p+=8; + memcpy(&dmi, p, sizeof(DOS_MODIFY_INFO)); + p+= sizeof(DOS_MODIFY_INFO); + memcpy(&nwp, p, 7); + result = nw_modify_file_dir(namespace, &nwp, p+7, + searchattrib, infomask, &dmi); } break; @@ -1292,6 +1442,77 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task) return(result); } +static void build_dos_name(DIR_BASE_ENTRY *e, uint8 *fname) +{ + uint8 *ss=e->nwpath.fn; + int len=0; + int pf=0; + int is_ok=1; + int options=get_volume_options(e->nwpath.volume, 1); + for (; *ss; ss++){ + if (*ss == '.') { + if (pf++) { /* no 2. point */ + is_ok=0; + break; + } + len=0; + } else { + ++len; + if ((pf && len > 3) || len > 8) { + is_ok=0; + break; + } + if (!(options & VOL_OPTION_IGNCASE)){ + if (options & VOL_OPTION_DOWNSHIFT){ /* only downshift chars */ + if (*ss >= 'A' && *ss <= 'Z') { + is_ok=0; + break; + } + } else { /* only upshift chars */ + if (*ss >= 'a' && *ss <= 'z') { + is_ok=0; + break; + } + } + } + } + } + if (is_ok) + strcpy(fname, e->nwpath.fn); + else + sprintf(fname, "%ld.___", (long)e->nwpath.statb.st_ino); +} + +int get_namespace_dir_entry(int volume, uint32 basehandle, + int namspace, uint8 *rdata) +{ + int result = find_base_entry(volume, basehandle); + XDPRINTF((3, 0, "get_ns_dir_entry: vol=%d, base=0x%lx, namspace=%d", + volume, basehandle, namspace)); + if (result > -1) { + DIR_BASE_ENTRY *e = dir_base[result]; + NW_SCAN_DIR_INFO *scif = (NW_SCAN_DIR_INFO*)rdata; + uint8 fname[20]; + (void) nwp_stat(&(e->nwpath), "get_namespace_dir_entry"); + memset(rdata, 0, sizeof(NW_SCAN_DIR_INFO)); +#if 0 + U32_TO_32(basehandle, scif->searchsequence); +#else + U32_TO_32(name_2_base(&(e->nwpath), NAME_DOS, 1), scif->searchsequence); +#endif + build_dos_name(e, fname); + if (S_ISDIR(e->nwpath.statb.st_mode)) { + get_dos_dir_attrib(&(scif->u.d), &e->nwpath.statb, + fname); + } else { + get_dos_file_attrib(&(scif->u.f), &e->nwpath.statb, + fname); + } + return(sizeof(NW_SCAN_DIR_INFO)); + } + return(result); +} + int handle_func_0x56(uint8 *p, uint8 *responsedata, int task) /* extended attribute calls */ @@ -1300,10 +1521,13 @@ int handle_func_0x56(uint8 *p, uint8 *responsedata, int task) int ufunc = (int) *p++; /* now p locates at 4 byte boundary */ XDPRINTF((3, 0, "0x56 call ufunc=0x%x", ufunc)); switch (ufunc) { + #if 1 case 0x01 : /* close extended attribute handle */ { + /* uint32 ea_handle=GET_BE32(p+2); + */ result=0; /* dummy */ } break; @@ -1316,6 +1540,7 @@ int handle_func_0x56(uint8 *p, uint8 *responsedata, int task) case 0x03 : /* read extended attribute */ { +#if 0 int flags = GET_16(p); /* LOW-HIGH */ /* next 2 entries only if flags bits 0-1 = 00 */ /* (~(flags & 3)) volume + basehandle */ @@ -1326,6 +1551,7 @@ int handle_func_0x56(uint8 *p, uint8 *responsedata, int task) uint32 readpos = GET_32(p+10); uint32 size = GET_32(p+14); uint16 keylen = GET_16(p+18); /* LOW-HIGH */ +#endif struct OUTPUT { uint8 errorcode[4]; /* LOW-HIGH */ uint8 ttl_v_length[4]; /* LOW-HIGH */ diff --git a/namspace.h b/namspace.h index 7c09784..4f82688 100644 --- a/namspace.h +++ b/namspace.h @@ -17,6 +17,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifndef _NAMSPACE_H_ +#define _NAMSPACE_H_ #if WITH_NAME_SPACE_CALLS #define NAME_DOS 0 @@ -33,6 +35,23 @@ typedef struct { uint8 pathes[1]; /* form len+name */ } NW_HPATH; +typedef struct { + uint8 attributes[4]; + uint8 created_date[2]; + uint8 created_time[2]; + uint8 created_id[4]; + uint8 modified_date[2]; + uint8 modified_time[2]; + uint8 modified_id[4]; + uint8 archived_date[2]; + uint8 archived_time[2]; + uint8 archived_id[4]; + uint8 last_access_date[2]; + uint8 rightsgrantmask[2]; + uint8 rightsrevokemask[2]; + uint8 maxspace[4]; +} DOS_MODIFY_INFO; + #define INFO_MSK_ENTRY_NAME 0x00000001 #define INFO_MSK_DATA_STREAM_SPACE 0x00000002 #define INFO_MSK_ATTRIBUTE_INFO 0x00000004 @@ -67,7 +86,31 @@ typedef struct { #define OPC_ACTION_REPLACE 0x04 +/* Modify File or Subdirektory DOS Info infomask */ +#define DOS_MSK_ATTRIBUTE 0x00000002 + +#define DOS_MSK_CREAT_DATE 0x00000004 +#define DOS_MSK_CREAT_TIME 0x00000008 +#define DOS_MSK_CREAT_ID 0x00000010 + +#define DOS_MSK_ARCHIVE_DATE 0x00000020 +#define DOS_MSK_ARCHIVE_TIME 0x00000040 +#define DOS_MSK_ARCHIVE_ID 0x00000080 + +#define DOS_MSK_MODIFY_DATE 0x00000100 +#define DOS_MSK_MODIFY_TIME 0x00000200 +#define DOS_MSK_MODIFY_ID 0x00000400 + +#define DOS_MSK_ACCESS_DATE 0x00000800 +#define DOS_MSK_INHERIT_RIGHTS 0x00001000 +#define DOS_MSK_MAX_SPACE 0x00002000 + extern int handle_func_0x57(uint8 *p, uint8 *responsedata, int task); extern int handle_func_0x56(uint8 *p, uint8 *responsedata, int task); +extern int get_namespace_dir_entry(int volume, uint32 basehandle, + int namspace, uint8 *rdata); + #endif +#endif + diff --git a/net.h b/net.h index 2c4ca2a..88b75d0 100644 --- a/net.h +++ b/net.h @@ -19,6 +19,7 @@ #ifndef _M_NET_H_ #define _M_NET_H_ +#include #include #include #include @@ -214,6 +215,10 @@ extern int errno; # define MAX_DIR_BASE_ENTRIES 50 #endif +#if MAX_DIR_BASE_ENTRIES < 10 +# define MAX_DIR_BASE_ENTRIES 10 +#endif + #ifndef MAX_NW_ROUTES # define MAX_NW_ROUTES 50 #endif diff --git a/nwbind.c b/nwbind.c index 5df0433..6693f3c 100644 --- a/nwbind.c +++ b/nwbind.c @@ -1,5 +1,5 @@ /* nwbind.c */ -#define REVISION_DATE "12-Jul-96" +#define REVISION_DATE "14-Aug-96" /* NCP Bindery SUB-SERVER */ /* authentification and some message handling */ @@ -1147,6 +1147,18 @@ static void handle_fxx(int gelen, int func) completition=0xd5; /* no Queue Job */ }break; + case 0x81 : { /* Get Queue Job List */ + NETOBJ obj; + struct XDATA { + uint8 total_jobs[4]; + uint8 reply_numbers[4]; + uint8 job_list[4]; /* this is repeated */ + } *xdata = (struct XDATA*) responsedata; + obj.id = GET_BE32(rdata); + XDPRINTF((2, 0, "TODO:GET QUEUE JOB List of Q=0x%lx", obj.id)); + memset(xdata, 0, sizeof(struct XDATA)); + }break; + case 0xc8 : { /* CHECK CONSOLE PRIVILEGES */ XDPRINTF((1, 0, "TODO: CHECK CONSOLE PRIV")); /* !!!!!! TODO completition=0xc6 (no rights) */ diff --git a/nwconn.c b/nwconn.c index eef544f..6494a15 100644 --- a/nwconn.c +++ b/nwconn.c @@ -683,6 +683,20 @@ static int handle_ncp_serv(void) completition = 0xfb; /* TODO: !!! */ } else if (*p == 0x2f){ /* ?????? */ completition = 0xfb; /* TODO: !!! */ + +#if WITH_NAME_SPACE_CALLS + } 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); + int result=get_namespace_dir_entry( + volume, basehandle, namespace, + responsedata); + if (result > -1) { + data_len = result; + } else completition = (uint8) -result; +#endif } else completition = 0xfb; /* unkwown request */ } break; @@ -696,7 +710,7 @@ static int handle_ncp_serv(void) #if FUNC_17_02_IS_DEBUG case 0x02 : { - /* I hope this is call isn't used */ + /* I hope this call isn't used */ /* now missused as a debug switch :) */ struct XDATA { uint8 nw_debug; /* old level */ @@ -730,7 +744,7 @@ static int handle_ncp_serv(void) uint8 data[2]; /* Name */ } *input = (struct INPUT *)ncprequest; - struct OUTPUT { + struct XDATA { uint8 sequence[2]; /* next sequence */ /* NW_FILE_INFO f; */ uint8 f[sizeof(NW_FILE_INFO)]; @@ -738,11 +752,11 @@ static int handle_ncp_serv(void) uint8 archive_date[2]; uint8 archive_time[2]; uint8 reserved[56]; - } *xdata = (struct OUTPUT*)responsedata; + } *xdata = (struct XDATA*)responsedata; int len = input->len; int searchsequence; NW_FILE_INFO f; - memset(xdata, 0, sizeof(struct OUTPUT)); + memset(xdata, 0, sizeof(struct XDATA)); searchsequence = nw_search( (uint8*) &f, (int)input->dir_handle, (int) GET_BE16(input->sequence), @@ -752,7 +766,7 @@ static int handle_ncp_serv(void) memcpy(xdata->f, &f, sizeof(NW_FILE_INFO)); U16_TO_BE16((uint16) searchsequence, xdata->sequence); U32_TO_BE32(1L, xdata->owner_id); /* Supervisor */ - data_len = sizeof(struct OUTPUT); + data_len = sizeof(struct XDATA); } else completition = (uint8) (- searchsequence); } break; @@ -844,13 +858,12 @@ static int handle_ncp_serv(void) break; case 0x21 : { /* Negotiate Buffer Size, Packetsize */ - int wantsize = GET_BE16((uint8*)ncprequest); + int wantsize = GET_BE16((uint8*)requestdata); uint8 *getsize=responsedata; - -#if IPX_DATA_GR_546 - wantsize = min(0x400, wantsize); -#else +#if !IPX_DATA_GR_546 wantsize = min(0x200, wantsize); +#else + wantsize = min(0x400, wantsize); #endif U16_TO_BE16(wantsize, getsize); data_len = 2; @@ -923,7 +936,7 @@ static int handle_ncp_serv(void) } *input = (struct INPUT *) ncprequest; int len=input->len ; /* FN Length */ - struct OUTPUT { + struct XDATA { uint8 searchsequence[2]; /* same as request sequence */ uint8 dir_id[2]; /* Direktory ID */ /* is correct !! */ @@ -931,7 +944,7 @@ static int handle_ncp_serv(void) NW_DIR_INFO d; NW_FILE_INFO f; } u; - } *xdata = (struct OUTPUT*)responsedata; + } *xdata = (struct XDATA*)responsedata; int searchsequence = nw_dir_search( (uint8*) &(xdata->u), @@ -942,7 +955,7 @@ static int handle_ncp_serv(void) if (searchsequence > -1) { U16_TO_BE16((uint16) searchsequence, xdata->searchsequence); memcpy(xdata->dir_id, input->dir_id, 2); - data_len = sizeof(struct OUTPUT); + data_len = sizeof(struct XDATA); } else completition = (uint8) (- searchsequence); } break; @@ -957,14 +970,14 @@ static int handle_ncp_serv(void) uint8 len; uint8 data[2]; /* Name */ } *input = (struct INPUT *)ncprequest; - struct OUTPUT { + 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 OUTPUT*)responsedata; + } *xdata = (struct XDATA*)responsedata; int len = input->len; uint8 my_sequenz[2]; int searchsequence; @@ -976,7 +989,7 @@ static int handle_ncp_serv(void) input->data, len); if (searchsequence > -1) { U16_TO_BE16((uint16) searchsequence, xdata->sequenz); - data_len = sizeof(struct OUTPUT); + data_len = sizeof(struct XDATA); } else completition = (uint8) (- searchsequence); } break; @@ -990,12 +1003,12 @@ static int handle_ncp_serv(void) uint8 len; /* namelaenge */ uint8 data[2]; /* Name */ } *input = (struct INPUT *)ncprequest; - struct OUTPUT { + 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 OUTPUT*)responsedata; + } *xdata= (struct XDATA*)responsedata; int fhandle=nw_creat_open_file((int)input->dirhandle, input->data, input->len, &(xdata->fileinfo), @@ -1006,7 +1019,7 @@ static int handle_ncp_serv(void) U32_TO_BE32(fhandle, xdata->fhandle); U16_TO_BE16(0, xdata->ext_fhandle); U16_TO_BE16(0, xdata->reserve2); - data_len = sizeof(struct OUTPUT); + data_len = sizeof(struct XDATA); } else completition = (uint8) (-fhandle); } break; @@ -1038,12 +1051,12 @@ static int handle_ncp_serv(void) uint8 len; uint8 data[1]; /* Name */ } *input = (struct INPUT *)ncprequest; - struct OUTPUT { + struct XDATA { uint8 extfhandle[2]; uint8 fhandle[4]; /* Filehandle */ uint8 reserved[2]; /* rese. by NOVELL */ NW_FILE_INFO fileinfo; - } *xdata= (struct OUTPUT*)responsedata; + } *xdata= (struct XDATA*)responsedata; int fhandle=nw_creat_open_file( (int)input->dirhandle, input->data, @@ -1053,7 +1066,7 @@ static int handle_ncp_serv(void) 0, (function==0x43) ? 1 : 2); if (fhandle > -1){ - data_len = sizeof(struct OUTPUT); + data_len = sizeof(struct XDATA); U32_TO_BE32(fhandle, xdata->fhandle); U16_TO_BE16(0, xdata->extfhandle); U16_TO_BE16(0, xdata->reserved); @@ -1134,13 +1147,13 @@ static int handle_ncp_serv(void) uint8 ext_filehandle[2]; /* all zero */ uint8 fhandle[4]; /* Dateihandle */ } *input = (struct INPUT *)ncprequest; - struct OUTPUT { + struct XDATA { uint8 size[4]; /* Position ??? */ - } *xdata=(struct OUTPUT*)responsedata; + } *xdata=(struct XDATA*)responsedata; int fhandle = GET_BE32(input->fhandle); int size = nw_seek_datei(fhandle, 0); if (size > -1) { - data_len = sizeof(struct OUTPUT); + data_len = sizeof(struct XDATA); U32_TO_BE32(size, xdata->size); } else completition = (uint8) -size; @@ -1157,10 +1170,10 @@ static int handle_ncp_serv(void) uint8 offset[4]; uint8 max_size[2]; /* byte to readd */ } *input = (struct INPUT *)ncprequest; - struct OUTPUT { + struct XDATA { uint8 size[2]; /* read byzes */ uint8 data[1072]; /* max data */ - } *xdata=(struct OUTPUT*)responsedata; + } *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); @@ -1226,11 +1239,11 @@ static int handle_ncp_serv(void) input_size); if (size < 0) completition = (uint8) -size; else { - struct OUTPUT { + struct XDATA { uint8 zsize[4]; /* real transfered Bytes */ - } *xdata= (struct OUTPUT*)responsedata; + } *xdata= (struct XDATA*)responsedata; U32_TO_BE32(size, xdata->zsize); - data_len = sizeof(struct OUTPUT); + data_len = sizeof(struct XDATA); } } break; @@ -1266,12 +1279,12 @@ static int handle_ncp_serv(void) uint8 len; /* namelaenge */ uint8 data[2]; /* Name */ } *input = (struct INPUT *)ncprequest; - struct OUTPUT { + 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 OUTPUT*)responsedata; + } *xdata= (struct XDATA*)responsedata; int fhandle=nw_creat_open_file((int)input->dirhandle, input->data, input->len, &(xdata->fileinfo), @@ -1283,7 +1296,7 @@ static int handle_ncp_serv(void) U16_TO_BE16(0, xdata->ext_fhandle); U16_TO_BE16(0, xdata->reserve2); - data_len = sizeof(struct OUTPUT); + data_len = sizeof(struct XDATA); #ifdef TEST_FNAME input->data[input->len] = '\0'; if (strstr(input->data, TEST_FNAME)){ @@ -1326,28 +1339,46 @@ static int handle_ncp_serv(void) #endif -#ifdef _MAR_TESTS_ +#if 0 case 0x61 : { /* Negotiate Buffer Size, Packetsize new ? */ /* > 3.11 */ - int wantsize = GET_BE16((uint8*)ncprequest); + int wantsize = GET_BE16((uint8*)requestdata); + int flags = (int) *(requestdata+2); /* wantsize is here normally 1500 */ - /* 1 byte unknown ( zero ) */ - struct OUTPUT { + struct XDATA { uint8 getsize[2]; - uint8 socket[2]; /* socket for echo ?? */ - uint8 unknown; /* zero */ - } *xdata= (struct OUTPUT*)responsedata; + uint8 socket[2]; /* echo socket */ + uint8 flags; /* zero */ + } *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); - XDPRINTF((5,0, "Negotiate Buffer (new) =0x%04x,(%d)", - (int) wantsize, (int) wantsize)); + XDPRINTF((5,0, "Negotiate Buffer (new) =0x%04x,(%d), flags=0x%x", + (int) wantsize, (int) wantsize, flags)); } break; #endif +#if 0 + 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; +#endif + #if 0 case 0x68 : /* NDS NCP, NDS Fragger Protokoll ?? */ #endif diff --git a/nwdbm.c b/nwdbm.c index 5026f24..99227d6 100644 --- a/nwdbm.c +++ b/nwdbm.c @@ -324,7 +324,7 @@ int nw_change_obj_security(NETOBJ *o, int newsecurity) int nw_get_obj(NETOBJ *o) { - int result = -0xfc; /* no Object */ + int result = -0xfc; /* no Object */ XDPRINTF((2,0, "nw_get_obj von OBJ id = 0x%x", (int)o->id)); if (!dbminit(FNOBJ)){ key.dsize = NETOBJ_KEY_SIZE; @@ -1291,7 +1291,7 @@ static void add_pr_queue(uint32 q_id, "Q_DIRECTORY", P_FL_ITEM, 0x33, q_directory, strlen(q_directory)); - /* this is a own property to handler the print job !!! */ + /* this is an own property to handle the print job !!! */ nw_new_obj_prop(q_id ,NULL, 0 , 0 , 0 , "Q_UNIX_PRINT", P_FL_ITEM| P_FL_DYNA, 0x33, q_command, strlen(q_command)); @@ -1300,7 +1300,6 @@ static void add_pr_queue(uint32 q_id, nw_new_obj_prop(q_id , NULL, 0 , 0 , 0 , "Q_USERS", P_FL_SET, 0x31, (char*)buff, 4); - #if 0 nw_new_obj_prop(q_id , NULL, 0 , 0 , 0 , "Q_SERVERS", P_FL_SET, 0x31, diff --git a/nwfile.c b/nwfile.c index 222df00..cd9c7c3 100644 --- a/nwfile.c +++ b/nwfile.c @@ -348,15 +348,11 @@ int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset) FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fd > -1) { if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */ - if (fh->fh_flags & FH_IS_PIPE_COMMAND) - size = fread(data, 1, size, fh->f->fildes[1]); - else { - size = read(fh->fd, data, size); - if (size < 0) { - int k=5; - while (size < 0 && --k /* && errno == EAGAIN */) - size = read(fh->fd, data, size); - } + size = read(fh->fd, data, size); + if (size < 0) { + int k=5; + while (size < 0 && --k /* && errno == EAGAIN */) + size = read(fh->fd, data, size); } } else { #if USE_MMAP @@ -430,11 +426,7 @@ int nw_write_datei(int fhandle, uint8 *data, int size, uint32 offset) if (fh->fd > -1) { if (fh->fh_flags & FH_IS_READONLY) return(-0x94); if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */ - if (size) { - if (fh->fh_flags & FH_IS_PIPE_COMMAND) - return(fwrite(data, 1, size, fh->f->fildes[0])); - return(write(fh->fd, data, size)); - } return(0); + return(size ? write(fh->fd, data, size) : 0); } else { if (fh->offd != (long)offset) fh->offd = lseek(fh->fd, offset, SEEK_SET); diff --git a/nwqueue.c b/nwqueue.c index bc26f34..952fff9 100644 --- a/nwqueue.c +++ b/nwqueue.c @@ -1,4 +1,4 @@ -/* nwconn.c 16-Jul-96 */ +/* nwconn.c 10-Aug-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -18,8 +18,10 @@ #include "net.h" #include -#include "connect.h" + +#include "nwvolume.h" #include "nwfile.h" +#include "connect.h" #include "nwqueue.h" static char **build_argv(char *buf, int bufsize, char *command) @@ -135,6 +137,7 @@ static int x_popen(char *command, int uid, int gid, FILE_PIPE *fp) int x_ = (j) ? 1 : 0; close(piped[j][x_]); piped [j][x_] = -1; + fp->fildes [j] = fdopen(piped[j][x], ( (j) ? "r" : "w") ); if (NULL == fp->fildes[j]){ err_close_pipe(fp, lpid, j+1, piped); @@ -150,8 +153,6 @@ int ext_pclose(FILE_PIPE *fp) void (*intsave) (int) = signal(SIGINT, SIG_IGN); void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN); void (*hupsave) (int) = signal(SIGHUP, SIG_IGN); - - int j = 3; while (j--) if (fp->fildes[j]) fclose(fp->fildes[j]); if (fp->command_pid != waitpid(fp->command_pid, &status, 0)) { @@ -388,7 +389,10 @@ int nw_close_file_queue(uint8 *queue_id, int k; is_ok++; while ((k = fread(buff, 1, sizeof(buff), f)) > 0) { + /* if (1 != fwrite(buff, k, 1, fp->fildes[0])) { + */ + if (k != write(fileno(fp->fildes[0]), buff, k)) { XDPRINTF((1,0,"Cannot write to pipe `%s`", printcommand)); is_ok=0; } diff --git a/nwserv.c b/nwserv.c index 98dd9d4..132911d 100644 --- a/nwserv.c +++ b/nwserv.c @@ -1205,6 +1205,10 @@ int main(int argc, char **argv) { int j = 0; int init_mode=0; + if (seteuid(0) < 0 || setuid(0) < 0) { + fprintf(stderr, "You must have root permission !\n"); + exit(1); + } tzset(); while (++j < argc) { char *a=argv[j]; @@ -1252,7 +1256,6 @@ int main(int argc, char **argv) time(&broadtime); set_sigs(); - creat_pidfile(); polls[NEEDED_SOCKETS].fd = fd_nwbind_in; diff --git a/nwvolume.c b/nwvolume.c index aab187e..012311b 100644 --- a/nwvolume.c +++ b/nwvolume.c @@ -1,4 +1,4 @@ -/* nwvolume.c 14-Jul-96 */ +/* nwvolume.c 08-Aug-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -64,6 +64,7 @@ void nw_init_volumes(FILE *f) if (founds > 1) { NW_VOL *vol=&(nw_volumes[used_nw_volumes]); vol->options = VOL_NAMESPACE_DOS; + upstr(sysname); new_str(vol->sysname, sysname); if (1 == (len = strlen((char*)unixname)) && unixname[0] == '~') { vol->options |= VOL_OPTION_IS_HOME; @@ -78,6 +79,10 @@ void nw_init_volumes(FILE *f) if (founds > 2) { for (p=optionstr; *p; p++) { switch (*p) { + case 'i' : vol->options + |= VOL_OPTION_IGNCASE; + break; + case 'k' : vol->options |= VOL_OPTION_DOWNSHIFT; break; @@ -319,15 +324,16 @@ int get_volume_options(int volnr, int mode) return(result); } -int get_volume_inode(int volnr) +int get_volume_inode(int volnr, struct stat *stb) /* returns inode if OK, else errocode < 0 */ { int result = -0x98; /* Volume not exist */; if (volnr > -1 && volnr < used_nw_volumes) { struct stat statb; - result = stat(nw_volumes[volnr].unixname, &statb); + if (!stb) stb=&statb; + result = stat(nw_volumes[volnr].unixname, stb); if (result == -1) result=-0x98; - else result=statb.st_ino; + else result=stb->st_ino; } XDPRINTF((5,0,"get_volume_inode of VOLNR:%d, result=0x%x", volnr, result)); return(result); diff --git a/nwvolume.h b/nwvolume.h index 399365f..1a858e1 100644 --- a/nwvolume.h +++ b/nwvolume.h @@ -1,4 +1,4 @@ -/* nwvolume.h 14-Jul-96 */ +/* nwvolume.h 27-Jul-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -32,23 +32,26 @@ typedef struct { */ typedef struct { - uint8 *sysname; /* VOL_NAME */ - uint8 *unixname; /* UNIX-DIR */ - int unixnamlen; /* len of unixname */ + uint8 *sysname; /* VOL_NAME */ + uint8 *unixname; /* UNIX-DIR with ending '/' */ + int unixnamlen; /* len of unixname */ DEV_NAMESPACE_MAP *dev_namespace_maps[MAX_DEV_NAMESPACE_MAPS]; - int max_maps_count; /* may be less than MAX_DEV_NAMESPACE_MAPS */ - int maps_count; /* count of dev_namespace_maps */ - uint32 high_inode; /* hight inode to can handle correct */ - int options; /* see defines below */ + int max_maps_count; /* may be less than MAX_DEV_NAMESPACE_MAPS */ + int maps_count; /* count of dev_namespace_maps */ + uint32 high_inode; /* hight inode to can handle correct */ + int options; /* see defines below */ + uint8 *os2buf; /* special stuff for os2 namspace */ } NW_VOL; /* vol options */ -#define VOL_OPTION_DOWNSHIFT 0x0001 /* All downshift */ +#define VOL_OPTION_DOWNSHIFT 0x0001 /* downshift */ #define VOL_OPTION_IS_PIPE 0x0002 /* Volume contains pipes */ #define VOL_OPTION_REMOUNT 0x0004 /* Volume can be remounted (cdroms) */ #define VOL_OPTION_IS_HOME 0x0008 /* Volume is USERS HOME */ #define VOL_OPTION_ONE_DEV 0x0010 /* Volume has only one filesys */ #define VOL_OPTION_READONLY 0x0020 /* Volume is readonly */ +#define VOL_OPTION_IGNCASE 0x0040 /* Do ignore up/downshift */ + /* namespaces */ #define VOL_NAMESPACE_DOS 0x1000 #define VOL_NAMESPACE_OS2 0x2000 @@ -73,7 +76,7 @@ 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); +extern int get_volume_inode(int volnr, struct stat *stb); extern uint32 nw_vol_inode_to_handle(int volume, ino_t inode, DEV_NAMESPACE_MAP *dnm); diff --git a/tools.c b/tools.c index 41fd19e..180064f 100644 --- a/tools.c +++ b/tools.c @@ -1,4 +1,4 @@ -/* tools.c 13-May-96 */ +/* tools.c 07-Aug-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -26,7 +26,7 @@ extern char *_sys_errlist[]; int nw_debug=0; -FILE *logfile=stdout; +FILE *logfile=stderr; static int in_module=0; /* in which process i am ? */ static int connection=0; /* which connection (nwconn) */ @@ -279,7 +279,7 @@ static char *get_pidfilefn(char *buf) return(get_div_pathes(buf, (char*)downstr((uint8*)lbuf), 2, ".pid")); } -void creat_pidfile(void) +static void creat_pidfile(void) { char buf[300]; char *pidfn=get_pidfilefn(buf); @@ -288,7 +288,8 @@ void creat_pidfile(void) fprintf(f, "%d\n", getpid()); fclose(f); } else { - XDPRINTF((1, 0, "Cannot creat pidfile=%s", pidfn)); + errorp(1, "INIT", "Cannot creat pidfile=%s", pidfn); + exit(1); } } @@ -301,6 +302,7 @@ void init_tools(int module, int options) int dodaemon=0; int new_log=0; in_module = module; + my_pid = getpid(); connection = (NWCONN == module) ? options : 0; if (NWSERV == module || NWROUTED == module) { int kill_pid=-1; @@ -351,18 +353,19 @@ void init_tools(int module, int options) if (NWSERV == module || NWROUTED == module) { /* now make daemon */ int fd=fork(); if (fd) exit((fd > 0) ? 0 : 1); + my_pid=getpid(); } if (NULL == (logfile = fopen(logfilename, (new_log && (NWSERV == module || NWROUTED == module)) ? "w" : "a"))) { - char sxx[100]; - sprintf(sxx, "\n\nOpen logfile `%s`", logfilename); - perror(sxx); - logfile = stdout; - fprintf(stderr, "\n!! ABORTED !!\n"); + logfile = stderr; + errorp(1, "INIT", "Cannot open logfile='%s'",logfilename); exit(1); } - if (NWSERV == module || NWROUTED == module) setsid(); - } + if (NWSERV == module || NWROUTED == module) { + creat_pidfile(); + setsid(); + } + } else logfile=stdout; if ( NWCONN != module || nw_debug > 1 ) { XDPRINTF((1, 0, "Starting Version: %d.%02dpl%d", _VERS_H_, _VERS_L_, _VERS_P_ )); @@ -371,7 +374,6 @@ void init_tools(int module, int options) if (nw_debug < 8) sigsegv_func = signal(SIGSEGV, sig_segv); #endif - my_pid = getpid(); } void exit_tools(void) @@ -380,20 +382,15 @@ void exit_tools(void) char buf[300]; unlink(get_pidfilefn(buf)); } - if (logfile != stdout) { - if (logfile != NULL) fclose(logfile); - logfile=stdout; - } } uint8 down_char(uint8 ch) { if (ch > 64 && ch < 91) return(ch + 32); switch(ch){ - case 142: ch = 132; break; - case 153: ch = 148; break; - case 154: ch = 129; break; - default :break; + case 142: return(132); + case 153: return(148); + case 154: return(129); } return(ch); } @@ -402,10 +399,9 @@ uint8 up_char(uint8 ch) { if (ch > 96 && ch < 123) return(ch - 32); switch(ch) { - case 132: ch = 142; break; - case 148: ch = 153; break; - case 129: ch = 154; break; - default : break; + case 132: return(142); + case 148: return(153); + case 129: return(154); } return(ch); } diff --git a/tools.h b/tools.h index 9362ff7..64801c7 100644 --- a/tools.h +++ b/tools.h @@ -50,7 +50,6 @@ extern char *get_div_pathes(char *buff, char *name, int what, char *p, ... ); extern int get_ini_int(int what); extern void get_ini_debug(int what); -extern void creat_pidfile(void); extern void init_tools(int module, int options); extern void exit_tools(void);