diff --git a/connect.c b/connect.c index 48a0f8b..25c4500 100644 --- a/connect.c +++ b/connect.c @@ -1,5 +1,5 @@ -/* connect.c 28-Nov-97 */ -/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany +/* connect.c 01-Feb-98 */ +/* (C)opyright (C) 1993,1998 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 @@ -45,13 +45,16 @@ static int act_umode_file=0; #include "nwfname.h" #include "nwvolume.h" +#include "nwattrib.h" #include "nwfile.h" #include "nwconn.h" +#include "namspace.h" #include "connect.h" typedef struct { - ino_t inode; /* Unix Inode dieses Verzeichnisses */ + int dev; /* unix dev */ + ino_t inode; /* unix inode */ time_t timestamp; /* Zeitmarke */ uint8 *path; /* path ab Volume */ uint8 volume; /* Welches Volume */ @@ -63,9 +66,9 @@ typedef struct { NW_DIR dirs[MAX_NW_DIRS]; int used_dirs=0; -int act_uid=-1; -int act_gid=-1; -int act_obj_id=0L; /* not login */ +int act_uid=-1; /* unix uid 0=root */ +int act_gid=-1; /* unix gid */ +int act_obj_id=0L; /* mars_nwe UID, 0=not logged in, 1=supervisor */ int entry8_flags=0; /* special flags, see examples nw.ini, entry 8 */ static gid_t *act_grouplist=NULL; /* first element is counter !! */ @@ -77,10 +80,11 @@ static int connect_is_init = 0; typedef struct { DIR *f; - char unixname[256]; /* kompletter unixname */ + char unixname[256]; /* full unixname */ + int dev; /* Unix dev */ ino_t inode; /* Unix Inode */ - time_t timestamp; /* fr letzte Allocierung */ - char *kpath; /* Ein Zeichen nach unixname */ + time_t timestamp; /* last allocation */ + char *kpath; /* one char after unixname */ int vol_options; /* searchoptions */ int volume; /* Volume Number */ @@ -127,7 +131,7 @@ static char *build_unix_name(NW_PATH *nwpath, int modus) } -static int new_dir_handle(ino_t inode, NW_PATH *nwpath) +static int new_dir_handle(int dev, ino_t inode, NW_PATH *nwpath) /* * RETURN=errorcode (<0) or dir_handle */ @@ -147,7 +151,8 @@ static int new_dir_handle(ino_t inode, NW_PATH *nwpath) if (!dh->inode) { if (!nhandle) nhandle = rethandle+1; - } else if (dh->inode == inode && dh->volume == nwpath->volume){ + } else if (dh->dev == dev && dh->inode == inode + && dh->volume == nwpath->volume){ nhandle = rethandle+1; break; } else if (dh->timestamp < last_time){ @@ -177,6 +182,7 @@ static int new_dir_handle(ino_t inode, NW_PATH *nwpath) if ((dh->f = opendir(dh->unixname)) != (DIR*) NULL){ dh->volume = nwpath->volume; dh->vol_options = nw_volumes[dh->volume].options; + dh->dev = dev; dh->inode = inode; dh->timestamp = akttime; dh->sequence = 0; @@ -877,12 +883,11 @@ static int build_path( NW_PATH *path, return(0); } -static int nw_path_ok(NW_PATH *nwpath) +static int nw_path_ok(NW_PATH *nwpath, struct stat *stbuff) /* returns UNIX inode of path */ { int j = 0; NW_DIR *d=&(dirs[0]); - struct stat stbuff; int result=0; if ((!act_obj_id) && !(entry8_flags & 1)) { @@ -904,21 +909,24 @@ static int nw_path_ok(NW_PATH *nwpath) while (j++ < (int)used_dirs){ if (d->inode && d->volume == nwpath->volume && !strcmp((char*)nwpath->path, (char*)d->path)){ + stbuff->st_ino = d->inode; + stbuff->st_dev = d->dev; return(d->inode); } d++; } /* while */ - if (!s_stat(build_unix_name(nwpath, 1 | 2 ), &stbuff, NULL) - && S_ISDIR(stbuff.st_mode)) - return(stbuff.st_ino); + if (!s_stat(build_unix_name(nwpath, 1 | 2 ), stbuff, NULL) + && S_ISDIR(stbuff->st_mode)) + return(stbuff->st_ino); result = -0x9c; /* wrong path */ } XDPRINTF((4,0x10, "NW_PATH_OK failed:`%s`", conn_get_nwpath_name(nwpath))); return(result); } -static int build_verz_name(NW_PATH *nwpath, /* gets complete path */ - int dir_handle) /* search with dirhandle */ +static int build_dir_name(NW_PATH *nwpath, /* gets complete path */ + struct stat *stbuff, + int dir_handle) /* search with dirhandle */ /* return -completition code or inode */ { @@ -954,7 +962,7 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */ int state = 0; while ((!completition) && (w = *p++) > 0){ if (!state){ - XDPRINTF((5,0,"in build_verz_name path=:%s:", nwpath->path)); + XDPRINTF((5,0,"in build_dir_name path=:%s:", nwpath->path)); if (w == '.') state = 20; else if (w == '/') state = 30; else state++; @@ -1036,13 +1044,13 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */ memcpy(nwpath->fn, pp+pathlen, fnlen); } } else return(-0x98); /* wrong volume */ - completition = nw_path_ok(nwpath); + completition = nw_path_ok(nwpath, stbuff); } return(completition); } -int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle, - uint8 *data, int len, int only_dir) +static int conn_get_kpl_path(NW_PATH *nwpath, struct stat *stbuff, + int dirhandle, uint8 *data, int len, int only_dir) /* * if ok then the inode of dir will be returned * else a negativ errcode will be returned @@ -1051,7 +1059,7 @@ int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle, 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); + if (!completition) completition = build_dir_name(nwpath, stbuff, dirhandle); return(completition); } @@ -1060,10 +1068,11 @@ int conn_get_full_path(int dirhandle, uint8 *data, int len, /* returns path in form VOLUME:PATH */ { NW_PATH nwpath; + struct stat stbuff; int result = build_path(&nwpath, data, len, 0); fullpath[0]='\0'; if (!result) - result = build_verz_name(&nwpath, dirhandle); + result = build_dir_name(&nwpath, &stbuff, dirhandle); if (result > -1) { uint8 *p=(*nwpath.path=='/') ? nwpath.path+1 : nwpath.path; int len=sprintf(fullpath, "%s:%s", @@ -1087,9 +1096,10 @@ int conn_get_kpl_unxname(char *unixname, */ { NW_PATH nwpath; + struct stat stbuff; int completition = build_path(&nwpath, data, len, 0); if (!completition) - completition = build_verz_name(&nwpath, dirhandle); + completition = build_dir_name(&nwpath, &stbuff, dirhandle); if (completition > -1) { if (unixname) strcpy(unixname, build_unix_name(&nwpath, 0)); @@ -1151,6 +1161,7 @@ time_t nw_2_un_time(uint8 *d, uint8 *t) return(mktime(&s_tm)); } +#if !NEW_ATTRIB_HANDLING int un_nw_attrib(struct stat *stb, int attrib, int mode) /* mode: 0 = un2nw , 1 = nw2un */ { @@ -1166,6 +1177,7 @@ int un_nw_attrib(struct stat *stb, int attrib, int mode) if (!mode) { /* UNIX access -> NW access */ + if (!is_dir) { attrib = FILE_ATTR_A; } else { @@ -1190,6 +1202,7 @@ int un_nw_attrib(struct stat *stb, int attrib, int mode) } else { /* NW access -> UNIX access */ int mode = S_IRUSR | S_IRGRP; + #if 0 /* this is sometimes very BAD */ if (attrib & FILE_ATTR_H) /* hidden */ @@ -1211,16 +1224,17 @@ int un_nw_attrib(struct stat *stb, int attrib, int mode) else stb->st_mode &= ~S_IXGRP; } - return(stb->st_mode); } } +#endif int un_nw_rights(struct stat *stb) /* returns eff rights of file/dir */ /* needs some more work */ { - int rights=0xfb; /* first all rights, but not TRUSTEE_O */ + /* int rights=0xfb; first all rights, but not TRUSTEE_O */ + int rights=0xff; /* first all, pconsole needs TRUSTEE_O */ if (act_uid) { /* if not root */ int is_dir = S_ISDIR(stb->st_mode); @@ -1250,9 +1264,21 @@ static int get_file_attrib(NW_FILE_INFO *f, struct stat *stb, NW_PATH *nwpath) { int voloptions=get_volume_options(nwpath->volume); + uint32 dwattrib; strncpy((char*)f->name, (char*)nwpath->fn, sizeof(f->name)); f->attrib=0; /* d->name could be too long */ up_fn(f->name); +#if NEW_ATTRIB_HANDLING + dwattrib = get_nw_attrib_dword(stb, voloptions); + f->attrib = (uint8)(dwattrib & 0xff); +# if 0 + /* is this OK or next ??? */ + dwattrib >>=8; + f->ext_attrib = (uint8)(dwattrib & 0xff); +# else + f->ext_attrib = 0; +# endif +#else if (voloptions & VOL_OPTION_IS_PIPE) f->attrib = FILE_ATTR_SHARE; else @@ -1261,6 +1287,7 @@ static int get_file_attrib(NW_FILE_INFO *f, struct stat *stb, (int)f->attrib, conn_get_nwpath_name(nwpath), stb->st_uid, stb->st_gid)); f->ext_attrib = 0; +#endif un_date_2_nw(stb->st_mtime, f->create_date, 1); un_date_2_nw(stb->st_atime, f->acces_date, 1); un_date_2_nw(stb->st_mtime, f->modify_date, 1); @@ -1272,16 +1299,24 @@ static int get_file_attrib(NW_FILE_INFO *f, struct stat *stb, static int get_dir_attrib(NW_DIR_INFO *d, struct stat *stb, NW_PATH *nwpath) { + int voloptions=get_volume_options(nwpath->volume); 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 */ up_fn(d->name); - d->attrib = (uint8) un_nw_attrib(stb, 0, 0); -#if 0 /* changed: 02-Nov-96 */ - d->ext_attrib = 0xff; /* effektive rights ?? */ -#else + +#if NEW_ATTRIB_HANDLING + d->attrib = (uint8)get_nw_attrib_dword(stb, voloptions); + d->ext_attrib = (uint8) un_nw_rights(stb); /* effektive rights ?? */ -#endif +#else + d->attrib = (uint8) un_nw_attrib(stb, 0, 0); +# if 0 /* changed: 02-Nov-96 */ + d->ext_attrib = 0xff; /* effektive rights ?? */ +# else + d->ext_attrib = (uint8) un_nw_rights(stb); /* effektive rights ?? */ +# endif +#endif un_date_2_nw(stb->st_mtime, d->create_date, 1); un_time_2_nw(stb->st_mtime, d->create_time, 1); U32_TO_BE32(get_file_owner(stb), d->owner_id); @@ -1302,7 +1337,8 @@ static int do_delete_file(NW_PATH *nwpath, FUNC_SEARCH *fs) int nw_delete_datei(int dir_handle, uint8 *data, int len) { NW_PATH nwpath; - int completition = conn_get_kpl_path(&nwpath, dir_handle, data, len, 0); + struct stat stbuff; + int completition = conn_get_kpl_path(&nwpath, &stbuff, dir_handle, data, len, 0); if (completition > -1) { completition = func_search_entry(&nwpath, 0x6, do_delete_file, NULL); if (completition < 0) return(completition); @@ -1316,11 +1352,11 @@ static int do_set_file_info(NW_PATH *nwpath, FUNC_SEARCH *fs) char unname[256]; int result=0; NW_FILE_INFO *f=(NW_FILE_INFO*)fs->ubuf; - int voloption; + int voloptions; strcpy(unname, build_unix_name(nwpath, 0)); - if ((voloption = get_volume_options(nwpath->volume)) & VOL_OPTION_IS_PIPE){ + if ((voloptions = get_volume_options(nwpath->volume)) & VOL_OPTION_IS_PIPE){ ;; /* don't change 'pipe commands' */ - } else if (voloption & VOL_OPTION_READONLY) { + } else if (voloptions & VOL_OPTION_READONLY) { result=(-0x8c); /* no modify rights */ } else { struct utimbuf ut; @@ -1329,10 +1365,24 @@ static int do_set_file_info(NW_PATH *nwpath, FUNC_SEARCH *fs) S_STATB stb; #endif ut.actime = ut.modtime = nw_2_un_time(f->modify_date, f->modify_time); - if ( 0 == (result=s_stat(unname, &statb, &stb)) && - 0 == (result=s_utime(unname, &ut, &stb))){ - result = s_chmod(unname, + if (0 == (result=s_stat(unname, &statb, &stb))) { +#if NEW_ATTRIB_HANDLING + result = set_nw_attrib_byte(&statb, voloptions, (int) f->attrib); + if (result < 0 && !(f->attrib & FILE_ATTR_R)) { + result = s_chmod(unname, statb.st_mode | S_IWUSR, &stb); + if (!result) { + statb.st_mode |= S_IWUSR; + result = set_nw_attrib_byte(&statb, voloptions, (int)f->attrib); + } + } + if (!result) + result=s_utime(unname, &ut, &stb); +#else + if (0 == (result=s_utime(unname, &ut, &stb))){ + result = s_chmod(unname, un_nw_attrib(&statb, (int)f->attrib, 1), &stb); + } +#endif } if (result) result= (-0x8c); /* no modify rights */ @@ -1345,7 +1395,8 @@ int nw_set_file_information(int dir_handle, uint8 *data, int len, int searchattrib, NW_FILE_INFO *f) { NW_PATH nwpath; - int completition = conn_get_kpl_path(&nwpath, dir_handle, data, len, 0); + struct stat stbuff; + int completition = conn_get_kpl_path(&nwpath, &stbuff, dir_handle, data, len, 0); if (completition > -1) { FUNC_SEARCH fs; fs.ubuf = (uint8*)f; @@ -1357,30 +1408,42 @@ int nw_set_file_information(int dir_handle, uint8 *data, int len, return(completition); } -int nw_chmod_datei(int dir_handle, uint8 *data, int len, - int attrib, int access) +int nw_set_file_attributes(int dir_handle, uint8 *data, int len, + int attrib, int newattrib) { char unname[256]; struct stat stbuff; int completition=-0x9c; NW_PATH nwpath; + int voloptions; #if PERSISTENT_SYMLINKS S_STATB stb; #endif 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); + completition = build_dir_name(&nwpath, &stbuff, dir_handle); } if (completition < 0) return(completition); + voloptions=get_volume_options(nwpath.volume); strcpy(unname, build_unix_name(&nwpath, 2)); - XDPRINTF((5,0,"set file attrib 0x%x, unname:%s:", access, unname)); + XDPRINTF((5,0,"set file attrib 0x%x, unname:%s:", newattrib, unname)); if (!s_stat(unname, &stbuff, &stb)){ - int result = s_chmod(unname, un_nw_attrib(&stbuff, access, 1), &stb); +#if NEW_ATTRIB_HANDLING + int result = set_nw_attrib_byte(&stbuff, voloptions, newattrib); + if (result < 0 && !(newattrib & FILE_ATTR_R)) { + result = s_chmod(unname, stbuff.st_mode | S_IWUSR, &stb); + if (!result) { + stbuff.st_mode |= S_IWUSR; + result = set_nw_attrib_byte(&stbuff, voloptions, newattrib); + } + } +#else + int result = s_chmod(unname, un_nw_attrib(&stbuff, newattrib, 1), &stb); +#endif return( (result != 0) ? -0x8c : 0); /* no modify rights */ } - return(-0x9c); /* wrong path */ } @@ -1408,8 +1471,18 @@ int nw_creat_node(int volnr, uint8 *unname, int mode) return(0); } } else { /* file */ - int fd=(mode & 2) ? open(unname, O_CREAT|O_TRUNC|O_RDWR, 0777) - : creat(unname, 0777); + int fd=-1; + if (mode & 2) { + struct stat stbuff; + int voloptions = get_volume_options(volnr); + if (!stat(unname, &stbuff)) { /* exists */ + if (get_nw_attrib_dword(&stbuff, voloptions) & FILE_ATTR_R) + fd=-2; + } + if (fd!=-2) + fd=open(unname, O_CREAT|O_TRUNC|O_RDWR, 0777); + } else + fd = creat(unname, 0777); if (fd < 0 && (mode & 8)) { /* creat always */ if ( (!seteuid(0)) && (-1 < (fd = @@ -1438,13 +1511,16 @@ int nw_creat_node(int volnr, uint8 *unname, int mode) int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode) { NW_PATH nwpath; - int completition = conn_get_kpl_path(&nwpath, dir_handle, data, len, !mode); - + struct stat stbuff; + int completition = conn_get_kpl_path(&nwpath, &stbuff, + dir_handle, data, len, !mode); if (completition > -1) { char unname[256]; + int voloptions; strcpy(unname, build_unix_name(&nwpath, 2)); - if (get_volume_options(nwpath.volume) & VOL_OPTION_READONLY) + if ((voloptions=get_volume_options(nwpath.volume)) & VOL_OPTION_READONLY) return(mode ? -0x84 : -0x8a); + if (mode) { XDPRINTF((5,0,"MKDIR dirname:%s:", unname)); if (!nw_creat_node(nwpath.volume, unname, 1)) @@ -1455,9 +1531,13 @@ int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode) completition = -0x84; /* No Create Priv.*/ /* -0x9f Direktory Aktive */ } else { /* rmdir */ int j = -1; + if (get_nw_attrib_dword(&stbuff, voloptions) & FILE_ATTR_R) + return(-0x8a); /* don't delete 'readonly' */ + while (++j < (int)anz_dirhandles){ DIR_HANDLE *dh=&(dir_handles[j]); - if (dh->inode == completition && dh->f != (DIR*) NULL) { + if ( dh->dev == stbuff.st_dev && + dh->inode == stbuff.st_ino && dh->f != (DIR*) NULL) { closedir(dh->f); dh->f = (DIR*)NULL; } @@ -1468,7 +1548,8 @@ int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode) NW_DIR *d=&(dirs[0]); j = 0; while (j++ < (int)used_dirs){ - if (d->inode == completition) d->inode = 0; + if ( d->dev == stbuff.st_dev && + d->inode == stbuff.st_ino) d->inode = 0; d++; } j = -1; @@ -1476,6 +1557,7 @@ int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode) DIR_HANDLE *dh=&(dir_handles[j]); if (dh->inode == completition) free_dir_handle(j+1); } + free_nw_ext_inode(stbuff.st_dev, stbuff.st_ino); completition = 0; } else if (errno == EEXIST) completition = -0xa0; /* dir not empty */ @@ -1489,13 +1571,15 @@ int mv_file(int qdirhandle, uint8 *q, int qlen, int zdirhandle, uint8 *z, int zlen) { NW_PATH quellpath; + struct stat qstbuff; NW_PATH zielpath; + struct stat zstbuff; int completition; zlen=apply_wildcards(q, qlen, z, zlen); - completition=conn_get_kpl_path(&quellpath, qdirhandle, q, qlen, 0); + completition=conn_get_kpl_path(&quellpath, &qstbuff, qdirhandle, q, qlen, 0); if (completition > -1) { - completition=conn_get_kpl_path(&zielpath, zdirhandle, z, zlen, 0); + completition=conn_get_kpl_path(&zielpath, &zstbuff, zdirhandle, z, zlen, 0); if (completition > -1) { int optq = get_volume_options(quellpath.volume); int optz = get_volume_options(zielpath.volume); @@ -1529,8 +1613,12 @@ int mv_dir(int dir_handle, uint8 *q, int qlen, uint8 *z, int zlen) { NW_PATH quellpath; + struct stat qstbuff; NW_PATH zielpath; - int completition=conn_get_kpl_path(&quellpath, dir_handle, q, qlen, 0); +#if 0 + struct stat zstbuff; +#endif + int completition=conn_get_kpl_path(&quellpath, &qstbuff, dir_handle, q, qlen, 0); if (completition > -1){ #if 1 /* I do not know anymore why I did these ??? */ @@ -1544,7 +1632,7 @@ int mv_dir(int dir_handle, uint8 *q, int qlen, */ #else /* and NOT these, perhaps this will also be ok ?! -- TODO -- */ - completition=conn_get_kpl_path(&zielpath, dir_handle, z, zlen, 0); + completition=conn_get_kpl_path(&zielpath, &zstbuff, dir_handle, z, zlen, 0); #endif if (completition > -1) { int optq = get_volume_options(quellpath.volume); @@ -1584,7 +1672,8 @@ int mv_dir(int dir_handle, uint8 *q, int qlen, } static int change_dir_entry( NW_DIR *dir, int volume, - uint8 *path, ino_t inode, + uint8 *path, + int dev, ino_t inode, int driveletter, int is_temp, int new_entry, int task) { @@ -1605,6 +1694,7 @@ static int change_dir_entry( NW_DIR *dir, int volume, ++len; } *(dir->path+len) = '\0'; + dir->dev = dev; dir->inode = inode; dir->volume = (uint8) volume; dir->timestamp = time(NULL); @@ -1627,6 +1717,9 @@ void nw_exit_connect(void) if (connect_is_init) { init_file_module(-1); } +#if WITH_NAME_SPACE_CALLS + exit_name_space_module(); +#endif } int nw_init_connect(void) @@ -1642,6 +1735,8 @@ int nw_init_connect(void) int what; int k = MAX_NW_DIRS; NW_DIR *d = &(dirs[0]); + int namspace_max_baseh=0; + int namspace_max_searchh=0; strcpy((char*)nwlogin.path, (char*)login); nwlogin.fn[0] = '\0'; nwlogin.volume = 0; @@ -1695,15 +1790,21 @@ int nw_init_connect(void) } } else if (50 == what) { init_nwfname(buff); + } else if (63 == what) { /* MAX_DIR_BASE */ + namspace_max_baseh=atoi(buff); } else if (68 == what) { /* USE_MMAP */ use_mmap=atoi(buff); + } else if (80 == what) { + namspace_max_searchh=atoi(buff); } else if (what == 103) { /* Debug */ get_debug_level(buff); } } /* while */ nw_init_volumes(f); fclose(f); - +#if WITH_NAME_SPACE_CALLS + init_name_space_module(namspace_max_baseh, namspace_max_searchh); +#endif if (used_nw_volumes < 1) { errorp(1, "No Volumes defined. Look at ini file entry 1, Abort !!", NULL); return(-1); @@ -1715,7 +1816,8 @@ int nw_init_connect(void) "UnixPath=`%s`", build_unix_name(&nwlogin, 0)); return(-1); } - (void)change_dir_entry(&(dirs[0]), 0, nwlogin.path, stbuff.st_ino, + (void)change_dir_entry(&(dirs[0]), 0, nwlogin.path, + stbuff.st_dev, stbuff.st_ino, 0, 0, 1, 0); /* first Handle must be known und must not be temp */ /* and has no Drive-Character */ @@ -1760,7 +1862,7 @@ int nw_free_handles(int task) return(0); } -int xinsert_new_dir(int volume, uint8 *path, int inode, int drive, int is_temp, int task) +int xinsert_new_dir(int volume, uint8 *path, int dev, int inode, int drive, int is_temp, int task) { int j = 0; int freehandle = 0; @@ -1786,17 +1888,18 @@ int xinsert_new_dir(int volume, uint8 *path, int inode, int drive, int is_temp, #endif if (freehandle){ (void)change_dir_entry(&(dirs[freehandle-1]), - volume, path, inode, + volume, path, dev, inode, drive, is_temp, 1, task); while (used_dirs > freehandle && !dirs[used_dirs-1].inode) used_dirs--; return(freehandle); } else return(-0x9d); /* no dir Handles */ } -int insert_new_dir(NW_PATH *nwpath, int inode, int drive, int is_temp, int task) +static int insert_new_dir(NW_PATH *nwpath, int dev, int inode, + int drive, int is_temp, int task) { return(xinsert_new_dir(nwpath->volume, nwpath->path, - inode, drive, is_temp, task)); + dev, inode, drive, is_temp, task)); } @@ -1806,7 +1909,8 @@ int nw_search(uint8 *info, uint32 *fileowner, { NW_PATH nwpath; - int completition = conn_get_kpl_path(&nwpath, dirhandle, data, len, 0); + struct stat stbuff; + int completition = conn_get_kpl_path(&nwpath, &stbuff, dirhandle, data, len, 0); XDPRINTF((5,0,"nw_search path:%s:, fn:%s:, completition:0x%x", nwpath.path, nwpath.fn, completition)); if (completition > -1) { @@ -1889,9 +1993,11 @@ int nw_alloc_dir_handle( int dir_handle, /* source directory handle */ int task) /* Prozess Task */ { NW_PATH nwpath; - int inode=conn_get_kpl_path(&nwpath, dir_handle, data, len, 1); + struct stat stbuff; + int inode=conn_get_kpl_path(&nwpath, &stbuff, dir_handle, data, len, 1); if (inode > -1) - inode = insert_new_dir(&nwpath, inode, driveletter, is_temphandle, task); + inode = insert_new_dir(&nwpath, stbuff.st_dev, stbuff.st_ino, + driveletter, is_temphandle, task); XDPRINTF((2,0,"Allocate %shandle:%s, Qhandle=%d, drive=%d, Task=%d, result=0x%x", (is_temphandle) ? "Temp" : "Perm", conn_get_nwpath_name(&nwpath), dir_handle, driveletter, task, inode)); @@ -1913,12 +2019,13 @@ int nw_open_dir_handle( int dir_handle, { NW_PATH nwpath; - int completition = conn_get_kpl_path(&nwpath, dir_handle, data, len, 1); + struct stat stbuff; + int completition = conn_get_kpl_path(&nwpath, &stbuff, dir_handle, data, len, 1); if (completition > -1) { XDPRINTF((5,0,"NW_OPEN_DIR: completition = 0x%x; nwpath= %s", (int)completition, conn_get_nwpath_name(&nwpath) )); - completition = new_dir_handle((ino_t)completition, &nwpath); + completition = new_dir_handle(stbuff.st_dev, stbuff.st_ino, &nwpath); if (completition > -1) { struct stat stb; DIR_HANDLE *dh = &(dir_handles[completition-1]); @@ -1956,7 +2063,7 @@ int nw_free_dir_handle(int dir_handle, int task) } int alter_dir_handle(int targetdir, int volume, uint8 *path, - int inode, int task) + int dev, int inode, int task) /* targetdir will be changed */ { if (targetdir > 0 && --targetdir < used_dirs @@ -1965,7 +2072,7 @@ int alter_dir_handle(int targetdir, int volume, uint8 *path, XDPRINTF((5,0,"Change dhandle:%d(%d) -> '%d:%s'", targetdir+1, task, volume, path)); return(change_dir_entry(&dirs[targetdir], - volume, path, inode, + volume, path, dev, inode, -1, -1, 0, task)); /* here the existing handle is only modified */ } else return(-0x9b); /* BAD DIR Handle */ @@ -1977,10 +2084,11 @@ int nw_set_dir_handle(int targetdir, int dir_handle, /* targetdirs gets path of dirhandle + data */ { NW_PATH nwpath; - int inode = conn_get_kpl_path(&nwpath, dir_handle, data, len, 1); + struct stat stbuff; + int inode = conn_get_kpl_path(&nwpath, &stbuff, dir_handle, data, len, 1); if (inode > -1) inode = alter_dir_handle(targetdir, nwpath.volume, nwpath.path, - inode, task); + stbuff.st_dev, stbuff.st_ino, task); return(inode); /* invalid PATH */ } @@ -2020,7 +2128,7 @@ int nw_get_eff_dir_rights(int dir_handle, uint8 *data, int len, int modus) char unname[256]; struct stat stbuff; NW_PATH nwpath; - int completition = conn_get_kpl_path(&nwpath, dir_handle, data, len, + int completition = conn_get_kpl_path(&nwpath, &stbuff, dir_handle, data, len, (modus) ? 0 : 1); if (completition < 0) return(completition); strcpy(unname, build_unix_name(&nwpath, 0)); @@ -2041,9 +2149,9 @@ int nw_creat_open_file(int dir_handle, uint8 *data, int len, */ { NW_PATH nwpath; - int completition = conn_get_kpl_path(&nwpath, dir_handle, data, len, 0); + struct stat stbuff; + int completition = conn_get_kpl_path(&nwpath, &stbuff, dir_handle, data, len, 0); if (completition > -1) { - struct stat stbuff; completition=file_creat_open(nwpath.volume, (uint8*)build_unix_name(&nwpath, 0), &stbuff, attrib, access, creatmode, task); @@ -2161,10 +2269,14 @@ void get_dos_file_attrib(NW_DOS_FILE_INFO *f, /* Attribute */ /* 0x20 Archive Flag */ /* 0x80 Sharable */ +#if NEW_ATTRIB_HANDLING + f->attributes[0] = (uint8) get_nw_attrib_dword(stb, voloptions); +#else if (voloptions & VOL_OPTION_IS_PIPE) f->attributes[0] = FILE_ATTR_SHARE; else f->attributes[0] = (uint8) un_nw_attrib(stb, 0, 0); +#endif 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(nw_owner, f->created.id); @@ -2183,11 +2295,16 @@ void get_dos_dir_attrib(NW_DOS_DIR_INFO *f, uint8 *path) { uint8 spath[14]; + int voloptions=get_volume_options(volume); f->namlen=min(strlen((char*)path), 12); strmaxcpy(spath, path, 12); up_fn(spath); strncpy((char*)f->name, (char*)spath, f->namlen); +#if NEW_ATTRIB_HANDLING + f->attributes[0] = (uint8) get_nw_attrib_dword(stb, voloptions); +#else f->attributes[0] = (uint8) un_nw_attrib(stb, 0, 0); +#endif 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(get_file_owner(stb), f->created.id); @@ -2205,11 +2322,11 @@ int nw_scan_a_directory(uint8 *rdata, uint32 searchbeg) /* 32 bit */ { NW_PATH nwpath; - int completition = conn_get_kpl_path(&nwpath, dirhandle, data, len, 0); + struct stat stbuff; + int completition = conn_get_kpl_path(&nwpath, &stbuff, dirhandle, data, len, 0); XDPRINTF((5,0,"nw_scan_a_directory path:%s:, fn:%s:, completition:0x%x", nwpath.path, nwpath.fn, completition)); if (completition > -1) { - struct stat stbuff; int searchsequence = (searchbeg == MAX_U32) ? MAX_U16 : searchbeg; if (get_dir_entry(&nwpath, &searchsequence, @@ -2240,12 +2357,12 @@ int nw_scan_a_root_dir(uint8 *rdata, int dirhandle) { NW_PATH nwpath; + struct stat stbuff; uint8 data[2]; - int completition = conn_get_kpl_path(&nwpath, dirhandle, data, 0, 1); + int completition = conn_get_kpl_path(&nwpath, &stbuff, dirhandle, data, 0, 1); XDPRINTF((5,0,"nw_scan_a_root_directory_2 path:%s:, fn:%s:, completition:0x%x", nwpath.path, nwpath.fn, completition)); if (completition > -1) { - struct stat stbuff; if (!s_stat(build_unix_name(&nwpath, 2), &stbuff, NULL)) { NW_DOS_DIR_INFO *d=(NW_DOS_DIR_INFO*)rdata; memset(rdata, 0, sizeof(NW_DOS_DIR_INFO)); @@ -2335,3 +2452,24 @@ void mangle_dos_name(NW_VOL *vol, uint8 *unixname, uint8 *pp) } +int nw_add_trustee(int dir_handle, uint8 *data, int len, + uint32 id, int trustee, int extended) +/* extended 0=add trustee to dir, 1= add ext trustee to dirs and files */ +{ + char unname[256]; + struct stat stbuff; + NW_PATH nwpath; + int completition = conn_get_kpl_path(&nwpath, &stbuff, dir_handle, data, len, + (extended) ? 0 : 1); + if (completition < 0) return(completition); + strcpy(unname, build_unix_name(&nwpath, 0)); + if (s_stat(unname, &stbuff, NULL) || + (!extended && !S_ISDIR(stbuff.st_mode)) ) { + completition = -0x9c; + } else { + completition=set_nw_trustee(stbuff.st_dev, stbuff.st_ino, + id, trustee); + } + return(completition); +} + diff --git a/connect.h b/connect.h index 1240f18..1d9e6e6 100644 --- a/connect.h +++ b/connect.h @@ -1,4 +1,4 @@ -/* connect.h 27-Nov-97 */ +/* connect.h 01-Feb-98 */ #ifndef _CONNECT_H_ #define _CONNECT_H_ @@ -124,8 +124,8 @@ extern int nw_delete_datei(int dir_handle, uint8 *data, int len); extern int nw_set_file_information(int dir_handle, uint8 *data, int len, int searchattrib, NW_FILE_INFO *f); -extern int nw_chmod_datei(int dir_handle, uint8 *data, int len, - int attrib, int access); +extern int nw_set_file_attributes(int dir_handle, uint8 *data, int len, + int attrib, int newattrib); extern int mv_file(int qdirhandle, uint8 *q, int qlen, int zdirhandle, uint8 *z, int zlen); @@ -153,30 +153,31 @@ extern int nw_find_dir_handle( int dir_handle, int len); /* L„nge Pfad */ extern int xinsert_new_dir(int volume, uint8 *path, - int inode, int drive, int is_temp, int task); + int dev, int inode, + int drive, int is_temp, int task); extern int nw_alloc_dir_handle( - int dir_handle, /* Suche ab Pfad dirhandle */ - uint8 *data, /* zus„tzl. Pfad */ - int len, /* L„nge DATA */ - int driveletter, /* A .. Z normal */ - int is_temphandle, /* tempor„res Handle 1 */ - /* spez. temp Handle 2 */ - int task); /* Prozess Task */ + int dir_handle, /* directory handle */ + uint8 *data, /* extra path */ + int len, /* len of datat */ + int driveletter, /* A .. Z normal */ + int is_temphandle, /* temp Handle 1 */ + /* spez. temp Handle 2 */ + int task); /* Prozess Task */ extern int nw_open_dir_handle( int dir_handle, - uint8 *data, /* zus„tzlicher Pfad */ - int len, /* L„nge DATA */ - int *volume, /* Volume */ - int *dir_id, /* „hnlich Filehandle */ + uint8 *data, /* extra path */ + int len, /* len data */ + int *volume, /* Volume */ + int *dir_id, /* similar to filehandle*/ int *searchsequence); extern int nw_free_dir_handle(int dir_handle, int task); extern int alter_dir_handle(int targetdir, int volume, uint8 *path, - int inode, int task); + int dev, int inode, int task); extern int nw_set_dir_handle(int targetdir, int dir_handle, uint8 *data, int len, int task); @@ -187,7 +188,8 @@ extern int nw_get_vol_number(int dir_handle); -extern int nw_get_eff_dir_rights(int dir_handle, uint8 *data, int len, int modus); +extern int nw_get_eff_dir_rights(int dir_handle, uint8 *data, int len, + int modus); extern int nw_scan_dir_info(int dir_handle, uint8 *data, int len, uint8 *subnr, uint8 *subname, @@ -211,8 +213,6 @@ extern int act_gid; extern int act_obj_id; /* not login == 0 */ extern int entry8_flags; /* special flags, see examples nw.ini, entry 8 */ -extern int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle, - uint8 *data, int len, int only_dir) ; extern int conn_get_full_path(int dirhandle, uint8 *data, int len, uint8 *fullpath); @@ -248,11 +248,19 @@ 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); + +#if !NEW_ATTRIB_HANDLING extern int un_nw_attrib(struct stat *stb, int attrib, int mode); +#endif + extern int un_nw_rights(struct stat *stb); 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); +extern int nw_add_trustee(int dir_handle, uint8 *data, int len, + uint32 id, int trustee, int extended); + + #endif diff --git a/doc/BUGS b/doc/BUGS index be9e01c..7113faf 100644 --- a/doc/BUGS +++ b/doc/BUGS @@ -24,8 +24,8 @@ If you have problems. some short notes for problem- or bug-reports. --------------------------------------------- - report your running environment - full mars_nwe version, example: 0.99.pl0 - linux-kernel, 2.0.29 + full mars_nwe version, example: 0.99.pl5 + linux-kernel, 2.0.32 exact typ of client (NCPFS, DOS (NETX,VLM), OS/2, Win .. ) changes you made into nwserv.conf(nw.ini), config.h. - if you send nwserv.conf, please remove the comments first. diff --git a/doc/CHANGES b/doc/CHANGES index 9aa39d4..19c9a8a 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -392,4 +392,22 @@ Erste 'oeffentliche' Version - Creat mode von Verzeichnissen erweitert. - Verzeichnisse werden nicht mehr auf readonly gesetzt. <----- ^^^^^^^^^^ pl4 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- negotiate Buffersize von < 512 wird nun ignoriert. ( Hayo Schmidt ) +- namspace.c: + - get_dbe_data_from_disk: Rechteproblem beim readlink beseitigt. + - max_dir_base_entries nun auch in conf file aenderbar (section 63) + - nw_search_file_dir so abgeaendert dass das Loeschen von Verzeichnissen + nun funktionieren sollte. Evtl. muss bei sehr grossen Verzeichnissen + max_dir_search_handles(section 80 in nwserv.conf) hochgesetzt werden. +<----- ^^^^^^^^^^ pl5 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- connect.c. un_nw_rights default rights now 0xff (pconsole needs TRUSTEE_O) +- nwattrib.c : set_nw_attrib_byte korrigiert. +- nwserv kann nun per externen Aufruf Interfaces anlegen und loeschen. + nwserv -a device frame net bzw. nwserv -d device frame. +- neuer Schalter nwserv -f. Force send rip sap. +- archive bit ist bei Dateien nun default gesetzt. +- archive bit wird nun bei Client Schreiboperationen gesetzt. +<----- ^^^^^^^^^^ pl6 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + diff --git a/doc/CREDITS b/doc/CREDITS index 029edfb..1993a48 100644 --- a/doc/CREDITS +++ b/doc/CREDITS @@ -79,6 +79,9 @@ Andrew Sapozhnikov added extend "Volume is home" feature. fixed "rename wildcard" bug. +Hayo Schmidt <100305.1424@compuserve.com> + added patch to let ATARI client work. + Gregory Steuck testings and errorreports diff --git a/doc/NEWS b/doc/NEWS index 14b07e4..0bf5cf6 100644 --- a/doc/NEWS +++ b/doc/NEWS @@ -1,3 +1,11 @@ +------08-Feb-98--- 0.99.pl6 --------- +- archive bit handling changed. (default set if file, unset if directory) +- section 5: deleting of ipx devices/routes changed. +- nwserv can be started to work similar to ipx_interface. + 'nwserv -a device frame net' or 'nwserv -d device frame' +------01-Feb-98--- 0.99.pl5 --------- +- config.h: NEW_ATTRIB_HANDLING +- config.h: default HANDLE_ALL_SAP_TYPS is now set to 1. ------27-Nov-97--- 0.99.pl4 --------- - section 1: dir/file creat modes can now be set volume dependent. - section 9: dir creat mode may now be '-1' for use st_mode of diff --git a/doc/mars_nwe.lsm b/doc/mars_nwe.lsm index f93c9a9..5fbd637 100644 --- a/doc/mars_nwe.lsm +++ b/doc/mars_nwe.lsm @@ -1,16 +1,16 @@ Begin3 Title: mars_nwe -Version: 0.99.pl4 -Entered-date: 28-Nov-97 +Version: 0.99.pl6 +Entered-date: 09-Feb-98 Description: Full netware-emulator (src), beta. Supports file-services, bindery-services, printing-services, routing-services. Keywords: novell, netware, server, ipx, ncp, tli Author: mstover@compu-art.de (Martin Stover) Maintained-by: mstover@compu-art.de (Martin Stover) -Primary-site: http://www.compu-art.de/download/mars_nwe-0.99.pl4.tgz +Primary-site: http://www.compu-art.de/download/mars_nwe-0.99.pl6.tgz 250 kB -Alternate-site: ftp://gwdg.de/pub/linux/misc/ncpfs/mars_nwe-0.99.pl4.tgz +Alternate-site: ftp://gwdg.de/pub/linux/misc/ncpfs/mars_nwe-0.99.pl6.tgz Platforms: Linux (1.2.xx, 1.3.xx, 2.xx), UnixWare (2.xx) Copying-policy: GNU End diff --git a/emutli1.c b/emutli1.c index 218f10e..2a0d135 100644 --- a/emutli1.c +++ b/emutli1.c @@ -246,12 +246,13 @@ static int add_special_net(int special, #define add_internal_net(netnum, node) \ add_special_net(IPX_INTERNAL, NULL, 0, (netnum), (node)) -#define add_device_net(devname, frame, netnum) \ - add_special_net(IPX_SPECIAL_NONE, (devname), (frame), (netnum), 0) - #define add_primary_net(devname, frame, netnum) \ add_special_net(IPX_PRIMARY, (devname), (frame), (netnum), 0) +int add_device_net(char *devname, int frame, uint32 netnum) +{ + return(add_special_net(IPX_SPECIAL_NONE, (devname), (frame), (netnum), 0)); +} int get_frame_name(uint8 *framename, int frame) { @@ -340,7 +341,7 @@ void exit_ipx(int flags) ioctl(sock, SIOCAIPXITFCRT, &org_auto_interfaces); close(sock); } - if (have_ipx_started && !(flags&1)) { + if (have_ipx_started && flags&4) { del_all_interfaces_nets(); } } diff --git a/emutli1.h b/emutli1.h index d0339fd..9600099 100644 --- a/emutli1.h +++ b/emutli1.h @@ -26,6 +26,7 @@ extern int read_interface_data(uint8* data, uint32 *rnet, uint8 *node, int *flags, uint8 *name); extern int get_interface_frame_name(char *name, uint32 net); +extern int add_device_net(char *devname, int frame, uint32 netnum); extern int get_frame_name(uint8 *framename, int frame); extern int init_ipx(uint32 network, uint32 node, int ipx_debug, int flags); diff --git a/examples/README.important b/examples/README.important index 64784ad..2e2a002 100644 --- a/examples/README.important +++ b/examples/README.important @@ -1,4 +1,4 @@ -This is an important kernel ipx patch for all known kernels. +This is an important kernel ipx patch for all known kernels prior 2.0.32 In linux/net/ipx/af_ipx.c routine ipx_create one line is missing. diff --git a/examples/config.h b/examples/config.h index 24ba3ae..016ac7e 100644 --- a/examples/config.h +++ b/examples/config.h @@ -1,4 +1,4 @@ -/* config.h: 10-Nov-97 */ +/* config.h: 04-Feb-98 */ /* some of this config is needed by make, others by cc */ #define DO_DEBUG 1 /* compile in debug code */ @@ -33,19 +33,20 @@ /* connections handled by mars_nwe */ /* !! NOTE !! */ /* If set > 255 some NCP calls will probably not work, try it with caution */ - /* and you should apply examples/kpatch2.0.29 */ + /* and you should apply examples/kpatch2.0.29 to kernels prior 2.0.32 */ -#define IPX_DATA_GR_546 1 /* 0 = max. IPX Packets = 546 +30 Byte ( 512 Byte RWBuff) */ +#define IPX_DATA_GR_546 2 /* 0 = max. IPX Packets = 546 +30 Byte ( 512 Byte RWBuff) */ /* 1 = max. IPX packets = 1058 +30 Byte (1024 Byte RWBuff) */ /* 2 = max. IPX packets = 1470 +30 Byte (1444 Byte RWBuff) */ /* 3 = max. IPX packets = 4130 +30 Byte (4096 Byte RWBuff) */ #define ENABLE_BURSTMODE 0 /* 0 = disable burstmode, 1 = enable burstmode */ - /* in 0.98.pl11 still NOT working !! */ + /* still NOT working correct !!!!! */ /* to get Burstmode really enabled, section '6' in conf-file */ /* must be set to a value > 1 (3.12 Server) */ - /* and kernel-patch examples/kpatch2.0.29 should be used */ + /* and kernel-patch examples/kpatch2.0.29 should be used for */ + /* kernels prior 2.0.32 */ #define USE_MMAP 1 /* use mmap systen call, not always best choice */ @@ -69,15 +70,17 @@ /* entry '6' in ini file should be set*/ /* to > '0', too. */ /* <--------------------------------------------------------------------> */ -#define HANDLE_ALL_SAP_TYPS 0 /* if set to 0 only SAP-Typ 4 Servers */ +#define HANDLE_ALL_SAP_TYPS 1 /* if set to 0 only SAP-Typ 4 Servers */ /* will be put into routing table and */ /* if set to 1 all SAP Typs will be */ - /* used. */ + /* used. */ #define PERSISTENT_SYMLINKS 0 /* change to '1' for persistent symlinks */ /* main idea from Victor Khimenko */ /* in 0.99.pl0 still NOT working !! */ +#define NEW_ATTRIB_HANDLING 0 /* better (if working ;)) attrib handling */ + /* <--------------- next is for linux only ----------------------------> */ #define INTERNAL_RIP_SAP 1 /* use internal/own rip/sap routines */ diff --git a/examples/nw.ini b/examples/nw.ini index aac0169..2e9fbd7 100644 --- a/examples/nw.ini +++ b/examples/nw.ini @@ -2,8 +2,9 @@ # This is the configuration-file for "mars_nwe", a free netware-emulator # for Linux. # -# last changed: 27-Nov-97 +# last changed: 08-Feb-98 # +# !! section 5 : deleting of ipx devices/routes changed in 0.99.pl6 !! # !! section 4 : automatic creation of ipx-interfaces changed in 0.98.pl9 !! # # since version 0.98.pl11: @@ -285,22 +286,31 @@ # 4 0x0 ippp0 AUTO 7 # auto ippp0 (isdn ppp) interface. # 4 0x0 ppp0 AUTO 7 # auto detection of ppp0 interface. + 4 0x22 eth0 ethernet_ii 1 4 0x0 * AUTO 1 # Section 5: special device flags # ========================================================================= # Flags -# 0x1 do not remove routes and ipx-devices +# 0x1 do not remove by nwserv/nwrouted added routes and ipx-devices # beyond the lifetime of the server or router. -# If this flag is not set then all ipx-devices/routes -# will be deleted when nwserv/nwrouted ends (default). +# If this flag is not set then all by nwserv/nwrouted added +# ipx-devices/routes will be deleted when +# nwserv/nwrouted ends (default). # # 0x2 Switch on automatic kernel creation of ipx-interfaces. # The automatic kernel creating of ipx-devices sometimes # make trouble (Win95). It should only be used in the # beginning or for testing. # +# 0x4 do remove ALL routes and ipx-devices +# beyond the lifetime of the server or router. +# If this flag is set then all ipx-devices/routes +# will be deleted when nwserv/nwrouted ends. +# This was the default prior mars_nwe 0.99.pl6 ! +# +# # other flags may follow. # value will be interpreted as hex value. @@ -673,12 +683,14 @@ 40 /var/spool/nwserv/.volcache # 41 = path for share/lock files 41 /var/spool/nwserv/.locks -# 42 = path for spool dir +# 42 = path for spool dir, e.g. internal print queue handling 42 /var/spool/nwserv # # # 45 = path for bindery file's 45 /etc +# 46 = path for attribute handling and later trustees +46 /var/lib/nwserv/attrib # ========================================================================= # Section 50: Conversion tables by Victor Khimenko # Tables for DOS->Unix names translation & upper/lowercase translations @@ -701,9 +713,10 @@ # more information in config.h # 60 10 # MAX_CONNECTIONS # 61 10 # MAX_NW_VOLS +# 63 50 # MAX_DIR_BASE_ENTRIES # 68 1 # USE_MMAP (use mmap=1, no mmap=0) -# 69 0 # HANDLE_ALL_SAP_TYPS (all sap typs=1, only typ 4=0) +# 69 1 # HANDLE_ALL_SAP_TYPS (all sap typs=1, only typ 4=0) # 70 0x44444444 # NETWORK_SERIAL_NMBR (4 byte) # 71 0x2222 # NETWORK_APPL_NMBR (2 byte) @@ -713,6 +726,8 @@ # You usally don't want to change anything below this line # -------------------------------------------------------- +# Sections 80-99: some more constants +# 80 50 # max_dir_search_handles (namspace.c) # Sections 100-106: amount of debug-information # diff --git a/makefile.unx b/makefile.unx index 42b06be..52aa92b 100644 --- a/makefile.unx +++ b/makefile.unx @@ -1,5 +1,5 @@ #if 0 -#makefile.unx 10-Nov-97 +#makefile.unx 04-Feb-98 #endif VPATH=$(V_VPATH) @@ -9,7 +9,7 @@ C=.c V_H=0 V_L=99 -P_L=4 +P_L=6 #define D_P_L 1 DISTRIB=mars_nwe @@ -116,7 +116,8 @@ PROGS=$(INSTALLPROGS) $(PROG8) OBJ1= $(EMUTLIOBJ) net1$(O) tools$(O) OBJ2= $(OBJ1) $(EMUTLIOBJ1) $(NWROUTE_O) OBJ3= $(OBJ1) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O) \ -nwqconn$(O) nameos2$(O) nwfname$(O) nwshare$(O) extpipe$(O) +nwqconn$(O) nameos2$(O) nwfname$(O) nwshare$(O) extpipe$(O) \ +nwattrib$(O) OBJ4= $(OBJ1) OBJ5= $(OBJ1) OBJ6= $(OBJ1) nwdbm$(O) nwcrypt$(O) unxlog$(O) sema$(O) nwqueue$(O) @@ -127,6 +128,7 @@ OBJS= $(EMUTLIOBJ) net1$(O) tools$(O) \ $(EMUTLIOBJ1) $(NWROUTE_O) \ connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O)\ nwqconn$(O) nameos2$(O) nwfname$(O) nwshare$(O) extpipe$(O) \ + nwattrib$(O) \ nwdbm$(O) nwcrypt$(O) unxlog$(O) sema$(O) nwqueue$(O) \ $(PROG2)$(O) $(PROG3)$(O) $(PROG4)$(O) $(PROG5)$(O) $(PROG6)$(O) \ $(PROG7)$(O) $(PROG8)$(O) @@ -134,7 +136,7 @@ OBJS= $(EMUTLIOBJ) net1$(O) tools$(O) \ HOBJ3= $(PROG3)$(O) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) \ unxfile$(O) -HOBJ6= $(PROG6)$(O) sema$(O) +HOBJ6= $(PROG6)$(O) sema$(O) #if 0 #$(PROG1): $(PROG1)$(O) $(OBJ1) @@ -192,7 +194,7 @@ n_install: @-if [ -r /sbin/nwserv ] && [ -r /usr/sbin/nwserv ] ; then \ echo "remove old version in /sbin ?" ; \ (cd /sbin && rm -i nwserv nwbind ncpserv nwconn nwclient nwrouted) ; \ - fi ; + fi ; @cd $(VPATH) && (if [ -r $(M_FILENAME_NW_INI) ] ; then \ echo ""; \ echo "********************************************************"; \ @@ -219,8 +221,7 @@ echo "********************************************************"; \ cd $(OBJDIR) ) n_reboot: n_install - -nwserv -k - nwserv + -(nwserv -k ; nwserv)& clean_d: cd $(VPATH) && (\ @@ -230,7 +231,9 @@ clean_d: n_clean: rm -f *.o - cd $(VPATH) && (rm -f $(PROGS) $(PROG7); cd $(OBJDIR) ) + cd $(VPATH) && (rm -f $(PROGS) $(PROG7) \ +; rm -rf $(OBJDIR)/$(VPATH)/$(DISTRIB) \ +; cd $(OBJDIR) ) n_distclean: n_clean clean_d cd $(VPATH) && (rm -f *.dir *.pag; cd $(OBJDIR)) diff --git a/namspace.c b/namspace.c index 0b27b58..bf5e7cf 100644 --- a/namspace.c +++ b/namspace.c @@ -1,9 +1,9 @@ -/* namspace.c 12-Aug-97 : NameSpace Services, mars_nwe */ +/* namspace.c 01-Feb-98 : NameSpace Services, mars_nwe */ /* !!!!!!!!!!!! NOTE !!!!!!!!!! */ /* Its still dirty, but it should work fairly well */ -/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany +/* (C)opyright (C) 1993,1998 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 @@ -30,6 +30,7 @@ #include "nwfname.h" #include "nwvolume.h" #include "connect.h" +#include "nwattrib.h" #include "nwconn.h" #include "nwfile.h" #include "unxfile.h" @@ -40,13 +41,6 @@ #define NW_PATH /* */ - -#if 0 -/* for tests only */ -# undef MAX_DIR_BASE_ENTRIES -# define MAX_DIR_BASE_ENTRIES 10 -#endif - typedef struct { int volume; /* Volume Number */ int has_wild; /* fn has wildcards */ @@ -71,27 +65,24 @@ typedef struct { N_NW_PATH nwpath; } DIR_BASE_ENTRY; -static DIR_BASE_ENTRY *dir_base[MAX_DIR_BASE_ENTRIES]; +static DIR_BASE_ENTRY **dir_base=NULL; static int anz_dbe = 0; - -#define MAX_DIR_SEARCH_HANDLES 10 - -#if MAX_DIR_SEARCH_HANDLES > 255 -# undef MAX_DIR_SEARCH_HANDLES -# define MAX_DIR_SEARCH_HANDLES 255 -#endif +static int max_dir_base_entries=0; typedef struct { + int dev; /* from searchdir */ + ino_t inode; /* from searchdir */ int idle; off_t dirpos; /* last readdirpos */ ino_t found_inode; /* last found inode at readdirpos */ int lastsequence; /* last sequence */ } DIR_SEARCH_HANDLE; -static DIR_SEARCH_HANDLE *dir_search_handles[MAX_DIR_SEARCH_HANDLES]; +static DIR_SEARCH_HANDLE **dir_search_handles=NULL; static int count_dsh = 0; +static int max_dir_search_handles=0; -static uint32 new_search_handle(void) +static uint32 new_search_handle(int dev, ino_t inode) { int k=count_dsh; int foundfree=-1; @@ -99,10 +90,17 @@ static uint32 new_search_handle(void) while (k--) { if (!dir_search_handles[k]) { foundfree=k; - break; - } else dir_search_handles[k]->idle++; + } else { + if (dir_search_handles[k]->idle < MAX_I32) + dir_search_handles[k]->idle++; + else { + xfree(dir_search_handles[k]); + if (foundfree < 0 && k+1==count_dsh) count_dsh--; + else foundfree=k; + } + } } - if (foundfree < 0 && count_dsh < MAX_DIR_SEARCH_HANDLES) + if (foundfree < 0 && count_dsh < max_dir_search_handles) foundfree=count_dsh++; if (foundfree < 0) { int idle=-1; @@ -118,19 +116,19 @@ static uint32 new_search_handle(void) } d=dir_search_handles[foundfree]; memset(d, 0, sizeof(DIR_SEARCH_HANDLE)); + d->dev = dev; + d->inode = inode; return((uint32) foundfree); } -#if 0 /* probably never needed */ -static void free_search_handle(uint32 handle) +static void free_search_handles(void) { - if (handle < count_dsh) { - xfree(dir_search_handles[handle]); - if (count_dsh == handle+1) - --count_dsh; + while (count_dsh--) { + xfree(dir_search_handles[count_dsh]); } + count_dsh=0; + xfree(dir_search_handles); } -#endif static void init_nwpath(N_NW_PATH *nwpath, int namespace) { @@ -338,8 +336,7 @@ static void del_dbe_from_disk(DIR_BASE_ENTRY *dbe) static int get_dbe_data_from_disk(int volume, - int dev, int ino, uint8 *path, - struct stat *statb) + int dev, ino_t inode, uint8 *path) /* returns 0 if all ok */ { char buf[255]; @@ -349,9 +346,11 @@ static int get_dbe_data_from_disk(int volume, #if 0 int voloptions=get_volume_options(volume); #endif - if (nw_get_volume_name(volume, volname) < 1) + if (nw_get_volume_name(volume, volname) < 1) { + XDPRINTF((1, 0, "get_dbe_d_f_d: wrong volume=%d", volume)); return (-1); - U32_TO_BE32(ino, inode_uc); + } + U32_TO_BE32(inode, inode_uc); sprintf(buf, "%s/%s/%x/%x/%x/%x/%x/%x", path_vol_inodes_cache, volname, #if 0 (voloptions & VOL_OPTION_IS_HOME) ? act_connection : 0, @@ -363,12 +362,18 @@ static int get_dbe_data_from_disk(int volume, (int) inode_uc[1], (int) inode_uc[2], (int) inode_uc[3]); + + seteuid(0); l=readlink(buf, path, 511); + reseteuid(); + if (l > 0) { path[l]='\0'; return(0); + } else { + errorp(0, "get_dbe_d_f_d", "readlink of `%s`=%d", buf, l); + return(-1); } - return(-1); } static DIR_BASE_ENTRY *allocate_dbe_p(int namespace) @@ -391,7 +396,7 @@ static DIR_BASE_ENTRY *allocate_dbe_p(int namespace) } if (j == anz_dbe) { - if (anz_dbe == MAX_DIR_BASE_ENTRIES) { + if (anz_dbe == max_dir_base_entries) { if (to_use_free > -1) { j = to_use_free; } else if (to_use_file > -1) { @@ -416,6 +421,24 @@ static DIR_BASE_ENTRY *allocate_dbe_p(int namespace) return(dbe); } +static void free_dir_bases(void) +/* free's all dir_bases */ +{ + if (dir_base) { + while (anz_dbe--) { + if (dir_base[anz_dbe]) { + if (S_ISDIR(dir_base[anz_dbe]->nwpath.statb.st_mode) + || (entry8_flags & 0x20) ) { + put_dbe_to_disk(dir_base[anz_dbe]); + } + xfree(dir_base[anz_dbe]); + } + } + anz_dbe=0; + xfree(dir_base); + } +} + static void xx_free_dbe_p(DIR_BASE_ENTRY **dbe) { if (NULL != dbe && NULL != *dbe) { @@ -443,6 +466,25 @@ static int touch_handle_entry_p(DIR_BASE_ENTRY *dbe) return(dbase); } +static void rmdir_from_structures(DIR_BASE_ENTRY *dbe) +/* is called after directory is deleted from disk, frees some structures */ +{ + int k=count_dsh; + int dev = dbe->nwpath.statb.st_dev; + ino_t inode = dbe->nwpath.statb.st_ino; + free_nw_ext_inode(dev, inode); + while (k--) { + DIR_SEARCH_HANDLE *dsh=dir_search_handles[k]; + if (dsh && dsh->inode == inode && dsh->dev == dev) { + xfree(dir_search_handles[k]); + if (k+1 == count_dsh) + count_dsh--; + } + } + del_dbe_from_disk(dbe); + free_dbe_p(dbe); +} + static int get_comp_pathes_size(NW_HPATH *nwp, uint8 *pp_pathes) /* returns size of path components in bytes */ @@ -683,23 +725,27 @@ static int find_base_entry(int volume, uint32 basehandle) } } } - /* now we test whether it is the root of volume */ + if (0 < ino) { struct stat statb; uint8 path[512]; + /* now we test whether it is the root of volume */ if (ino == get_volume_inode(volume, &statb)) { /* its the handle of the volumes root */ return(add_dbe_entry(dnm.namespace, volume, basehandle, NULL, &statb)); } - if (!get_dbe_data_from_disk(volume, dnm.dev, ino, path, &statb)) { + /* now we try it from disk */ + if (!get_dbe_data_from_disk(volume, dnm.dev, ino, path)) { /* we found it on disk */ return(add_dbe_entry(dnm.namespace, volume, basehandle, path, NULL)); } } - XDPRINTF((1, 0, "Could not find path of vol=%d, base=0x%x", volume, basehandle)); + + XDPRINTF((1, 0, "Could not find path of vol=%d, base=0x%x, dev=0x%x, inode=%d", + volume, basehandle, dnm.dev, ino)); return(-0x9b); } @@ -862,7 +908,7 @@ static int build_dos_name(DIR_BASE_ENTRY *e, uint8 *fname) #if 0 typedef struct { int anz; - DIR_BASE_ENTRY *ee[MAX_DIR_BASE_ENTRIES]; + DIR_BASE_ENTRY **ee; } BASE_COMPONENTS; static BASE_COMPONENTS *get_path_components(DIR_BASE_ENTRY *dbe) @@ -978,10 +1024,14 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, p += 4; if (infomask & INFO_MSK_ATTRIBUTE_INFO) { +#if NEW_ATTRIB_HANDLING + uint32 attrib = get_nw_attrib_dword(stb, voloptions); +#else uint32 attrib = ( (!S_ISDIR(stb->st_mode)) && (voloptions & VOL_OPTION_IS_PIPE) ) ? (uint32) FILE_ATTR_SHARE|FILE_ATTR_A : (uint32) un_nw_attrib(stb, 0, 0); +#endif U32_TO_32(attrib, p); p += 4; U16_TO_16((uint16)(attrib & 0xFFFF), p); @@ -1318,7 +1368,10 @@ int nw_search_file_dir(int namespace, int datastream, int max_counts = *count; #endif int result = find_base_entry(volume, basehandle); - DIR_BASE_ENTRY *dest_dbe=NULL; + DIR_BASE_ENTRY *dest_dbe=NULL; + DIR_SEARCH_HANDLE *dsh=NULL; + DIR_BASE_ENTRY *dbe=NULL; + int sequence; *perhaps_more = 0; *count = 0; @@ -1326,27 +1379,40 @@ int nw_search_file_dir(int namespace, int datastream, MDEBUG(D_FN_SEARCH, { char fname[300]; strmaxcpy(fname, path, min(sizeof(fname)-1, len)); - xdprintf(1,0,"nwsfd:seqence=%d, base=%d, attrib=0x%x, fn=`%s`", - *psequence, basehandle, searchattrib, fname); + xdprintf(1,0,"nwsfd:sequence=%d,%d, base=%d, attrib=0x%x, fn=`%s`", + *psequence & 0xff, *psequence >> 8, basehandle, + searchattrib, fname); }) + if (len > 255) result=-0x9c; /* we say wrong path here */ else if (result > -1) { + dbe=dir_base[result]; if (*psequence == MAX_U32) { - *psequence=new_search_handle(); - + *psequence=new_search_handle(dbe->nwpath.statb.st_dev, + dbe->nwpath.statb.st_ino); MDEBUG(D_FN_SEARCH, { xdprintf(1,0,"nwsfd:got new search seqence=%d", *psequence); }) - + } + sequence = *psequence >> 8; + *psequence &= 0xff; + + if (*psequence < count_dsh) { + dsh=dir_search_handles[*psequence]; + if (dsh && (dbe->nwpath.statb.st_dev != dsh->dev + || dbe->nwpath.statb.st_ino != dsh->inode)) + dsh=NULL; + } + + if (!dsh) { + *psequence=new_search_handle(dbe->nwpath.statb.st_dev, + dbe->nwpath.statb.st_ino); + *psequence &= 0xff; + dsh=dir_search_handles[*psequence]; } } - sequence = *psequence >> 8; - *psequence &= 0xff; - - if (result > -1 && *psequence < count_dsh) { - DIR_SEARCH_HANDLE *dsh=dir_search_handles[*psequence]; - DIR_BASE_ENTRY *dbe=dir_base[result]; + if (NULL != dsh) { DIR_SEARCH_STRUCT *ds=(DIR_SEARCH_STRUCT*) xcmalloc(sizeof(DIR_SEARCH_STRUCT)); ds->unixname = (uint8*)nwpath_2_unix1(&(dbe->nwpath), 2, 258); @@ -1364,7 +1430,7 @@ int nw_search_file_dir(int namespace, int datastream, *(++(ds->kpath)) = '\0'; dbe->locked++; /* lock dbe */ - dsh->idle=0; /* touch dsh */ + dsh->idle=0; /* touch dsh */ while (len--) { uint8 c=*path++; @@ -1480,11 +1546,12 @@ int nw_search_file_dir(int namespace, int datastream, dsh->lastsequence++; } /* while */ *psequence |= (dsh->lastsequence << 8); + if (!*perhaps_more) dsh->idle=MAX_I32-4; XDPRINTF((5, 0, "more=%d, sequence = 0x%x, file=%s,next=%s", *perhaps_more, *psequence, dest_dbe->nwpath.path, dirbuff?dirbuff->d_name:"")); } else { - dsh->idle = 1000; + dsh->idle = MAX_I32-2; dsh->dirpos = (off_t)0; result=-0xff; /* no files matching */ XDPRINTF((5, 0, "no files matching")); @@ -1679,17 +1746,25 @@ static int delete_file_dir(DIR_BASE_ENTRY *dbe, FUNC_SEARCH *fs) uint8 *unname=(uint8*)nwpath_2_unix(&(dbe->nwpath), 2); int result; if (S_ISDIR(dbe->nwpath.statb.st_mode)) { - result = rmdir(unname); - if (result < 0) { - switch (errno) { - case EEXIST: result=-0xa0; /* dir not empty */ - default: result=-0x8a; /* No privilegs */ + int voloptions = get_volume_options(dbe->nwpath.volume); + /* directory */ + if (get_nw_attrib_dword(&dbe->nwpath.statb, voloptions) & FILE_ATTR_R) + result = -0x8a; /* don't delete 'readonly' */ + else { + result = rmdir(unname); + if (result < 0) { + switch (errno) { + case EEXIST: result=-0xa0; /* dir not empty */ + default: result=-0x8a; /* No privilegs */ + } } - } else { + } + if (result>-1) { + rmdir_from_structures(dbe); result = 0; - free_dbe_p(dbe); } } else { + /* file */ if (-1 < (result = nw_unlink(dbe->nwpath.volume, unname))) free_dbe_p(dbe); } @@ -1721,7 +1796,8 @@ static int nw_alloc_short_dir_handle(int namespace, int hmode, 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); + dbe->nwpath.statb.st_dev, dbe->nwpath.statb.st_ino, + 300, hmode, task); *volume=dbe->nwpath.volume; } else result=-0xff; } @@ -1737,7 +1813,7 @@ static int nw_set_short_dir_handle(int namespace, int desthandle, if (S_ISDIR(dbe->nwpath.statb.st_mode)) { result=alter_dir_handle(desthandle, dbe->nwpath.volume, dbe->nwpath.path, - dbe->nwpath.statb.st_ino, task); + dbe->nwpath.statb.st_dev, dbe->nwpath.statb.st_ino, task); } else result=-0x9c; /* wrong path */ } return((result > 0) ? 0 : result); @@ -2405,4 +2481,22 @@ int handle_func_0x56(uint8 *p, uint8 *responsedata, int task) } /* switch */ return(result); } + +void exit_name_space_module(void) +{ + free_dir_bases(); + free_search_handles(); +} + +void init_name_space_module(int max_baseh, int max_searchh) +{ + exit_name_space_module(); + max_dir_base_entries=(max_baseh < 5) ? MAX_DIR_BASE_ENTRIES : max_baseh; + dir_base=(DIR_BASE_ENTRY **)xcmalloc( + sizeof(DIR_BASE_ENTRY*) * max_dir_base_entries); + + max_dir_search_handles=(max_searchh < 10 || max_searchh > 255) ? 50 : max_searchh; + dir_search_handles=(DIR_SEARCH_HANDLE **)xcmalloc( + sizeof(DIR_SEARCH_HANDLE*) * max_dir_search_handles); +} #endif diff --git a/namspace.h b/namspace.h index 5334014..ab494ae 100644 --- a/namspace.h +++ b/namspace.h @@ -1,6 +1,6 @@ -/* namspace.h 01-Aug-97 : NameSpace Services, mars_nwe */ +/* namspace.h 01-Feb-98 : NameSpace Services, mars_nwe */ -/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany +/* (C)opyright (C) 1993,1998 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 @@ -112,6 +112,9 @@ extern int fill_namespace_buffer(int volume, uint8 *rdata); extern int get_namespace_dir_entry(int volume, uint32 basehandle, int namspace, uint8 *rdata); +extern void exit_name_space_module(void); +extern void init_name_space_module(int max_baseh, int max_searchh); + #endif #endif diff --git a/net.h b/net.h index 272911c..15d91de 100644 --- a/net.h +++ b/net.h @@ -123,6 +123,7 @@ extern int errno; #define MAX_U32 ((uint32)0xffffffffL) #define MAX_U16 ((uint16)0xffff) +#define MAX_I32 0x7fffffff /* ===================> config.h <======================= */ #ifdef CALL_NWCONN_OVER_SOCKET @@ -202,7 +203,7 @@ extern int errno; #endif #ifndef IPX_DATA_GR_546 -# define IPX_DATA_GR_546 1 +# define IPX_DATA_GR_546 2 #endif #ifndef USE_MMAP @@ -222,7 +223,7 @@ extern int errno; #endif #ifndef HANDLE_ALL_SAP_TYPS -# define HANDLE_ALL_SAP_TYPS 0 +# define HANDLE_ALL_SAP_TYPS 1 #endif #if IPX_DATA_GR_546 @@ -257,6 +258,11 @@ extern int errno; # define DO_TESTING 0 #endif +#ifndef NEW_ATTRIB_HANDLING +# define NEW_ATTRIB_HANDLING 1 +#endif + + #ifdef LINUX # ifndef QUOTA_SUPPORT # define QUOTA_SUPPORT 0 diff --git a/nwattrib.c b/nwattrib.c new file mode 100644 index 0000000..2d23ae5 --- /dev/null +++ b/nwattrib.c @@ -0,0 +1,329 @@ +/* nwattrib.c 09-Feb-98 */ +/* (C)opyright (C) 1998 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 "unxfile.h" +#include "nwvolume.h" +#include "connect.h" + +#include "nwattrib.h" + +static void put_attr_to_disk(int dev, ino_t inode, uint32 attrib) +{ + char buf[255]; + char battrib[255]; + int l; + uint8 buf_uc[4]; + U32_TO_BE32(inode, buf_uc); + l=sprintf(buf, "%s/%x/%x/%x/%x", path_attributes, + dev, + (int) buf_uc[0], + (int) buf_uc[1], + (int) buf_uc[2]); + seteuid(0); + unx_xmkdir(buf, 0755); + sprintf(buf+l, "/%x", (int) buf_uc[3]); + unlink(buf); + l=sprintf(battrib, "%08x", (unsigned int) attrib); + symlink(battrib, buf); + reseteuid(); +} + +static void free_attr_from_disk(int dev, ino_t inode) +{ + char buf[255]; + uint8 buf_uc[4]; + U32_TO_BE32(inode, buf_uc); + sprintf(buf, "%s/%x/%x/%x/%x/%x", path_attributes, + dev, + (int) buf_uc[0], + (int) buf_uc[1], + (int) buf_uc[2], + (int) buf_uc[3]); + seteuid(0); + unlink(buf); + reseteuid(); +} + +static int get_attr_from_disk(int dev, ino_t inode, uint32 *attrib) +/* returns 0 if all ok */ +{ + char buf[255]; + char battrib[255]; + int l; + uint8 buf_uc[4]; + U32_TO_BE32(inode, buf_uc); + sprintf(buf, "%s/%x/%x/%x/%x/%x", path_attributes, + dev, + (int) buf_uc[0], + (int) buf_uc[1], + (int) buf_uc[2], + (int) buf_uc[3]); + seteuid(0); + l=readlink(buf, battrib, 224); + reseteuid(); + if (l > 0) { + unsigned int uattrib=0; + battrib[l]='\0'; + if (1 == sscanf(battrib, "%x", &uattrib)) { + *attrib = uattrib; + return(0); + } + } + *attrib=0; + return(-1); +} + + +uint32 get_nw_attrib_dword(struct stat *stb, int voloptions) +/* returns full attrib_dword */ +{ + uint32 attrib=0; + int is_dir=S_ISDIR(stb->st_mode); + + if (!is_dir && (voloptions & VOL_OPTION_IS_PIPE)) + return(FILE_ATTR_SHARE|FILE_ATTR_A); + + if (voloptions & VOL_OPTION_READONLY) + return((is_dir)?FILE_ATTR_DIR|FILE_ATTR_R:FILE_ATTR_R); + + if (!get_attr_from_disk(stb->st_dev, stb->st_ino, &attrib)) { + if (is_dir) attrib |= FILE_ATTR_DIR; + else attrib &= (~FILE_ATTR_DIR); + } else { + if (is_dir) + attrib = FILE_ATTR_DIR; + else + attrib = FILE_ATTR_A; /* default archive flag */ + } + + if (act_uid) { + /* if not root */ + int acc=get_real_access(stb); + if (!(acc & W_OK)) { + attrib |= FILE_ATTR_R; /* RO */ + } + if (!(acc & R_OK)) { + attrib |= FILE_ATTR_H; /* We say hidden here */ + } + } + return(attrib); +} + +int set_nw_attrib_dword(struct stat *stb, int voloptions, uint32 attrib) +{ + int is_dir=S_ISDIR(stb->st_mode); + if (voloptions & VOL_OPTION_READONLY) + return(-0x8c); /* no modify rights */ + if (voloptions & VOL_OPTION_IS_PIPE) + return(0); + + if (!(get_real_access(stb) & W_OK)) + return(-0x8c); /* no modify rights */ + + if (is_dir) attrib |= 0x10; + else attrib &= ~0x10; + put_attr_to_disk(stb->st_dev, stb->st_ino, attrib); + return(0); +} + +int set_nw_attrib_byte(struct stat *stb, int voloptions, int battrib) +{ + int is_dir=S_ISDIR(stb->st_mode); + uint32 attrib,oldattrib; + if (voloptions & VOL_OPTION_READONLY) + return(-0x8c); /* no modify rights */ + if (voloptions & VOL_OPTION_IS_PIPE) + return(0); + + if (!(get_real_access(stb) & W_OK)) + return(-0x8c); /* no modify rights */ + + oldattrib=get_nw_attrib_dword(stb, voloptions); + attrib = (oldattrib & ~0xff); + attrib |= battrib; + if (is_dir) attrib |= 0x10; + else attrib &= ~0x10; + if (attrib != oldattrib) + put_attr_to_disk(stb->st_dev, stb->st_ino, attrib); + return(0); +} + +void set_nw_archive_bit(int dev, ino_t inode) +/* only called for files */ +{ + uint32 attrib; + if ( (!get_attr_from_disk(dev, inode, &attrib)) + && !(attrib & FILE_ATTR_A)) { + attrib|=FILE_ATTR_A; + put_attr_to_disk(dev, inode, attrib); + } +} + + +/* trustees */ +static void put_trustee_to_disk(int dev, ino_t inode, uint32 id, int trustee) +{ + char buf[255]; + char btrustee[255]; + int l; + uint8 buf_uc[4]; + U32_TO_BE32(inode, buf_uc); + l=sprintf(buf, "%s/%x/%x/%x/%x/%x.t", path_attributes, + dev, + (int) buf_uc[0], + (int) buf_uc[1], + (int) buf_uc[2], + (int) buf_uc[3]); + seteuid(0); + unx_xmkdir(buf, 0755); + sprintf(buf+l, "/%x", (unsigned int) id); + unlink(buf); + l=sprintf(btrustee, "%04x", (unsigned int) trustee); + symlink(btrustee, buf); + reseteuid(); +} + +static void free_trustees_from_disk(int dev, ino_t inode) +{ + char buf[255]; + uint8 buf_uc[4]; + U32_TO_BE32(inode, buf_uc); + sprintf(buf, "%s/%x/%x/%x/%x/%x.t", path_attributes, + dev, + (int) buf_uc[0], + (int) buf_uc[1], + (int) buf_uc[2], + (int) buf_uc[3]); + seteuid(0); + unx_xrmdir(buf); + reseteuid(); +} + +static int get_trustee_from_disk(int dev, ino_t inode, uint32 id) +{ + char buf[255]; + char btrustee[255]; + int l; + uint8 buf_uc[4]; + U32_TO_BE32(inode, buf_uc); + sprintf(buf, "%s/%x/%x/%x/%x/%x.t/%x", path_attributes, + dev, + (int) buf_uc[0], + (int) buf_uc[1], + (int) buf_uc[2], + (int) buf_uc[3], + (unsigned int) id); + seteuid(0); + l=readlink(buf, btrustee, 254); + reseteuid(); + if (l > 0) { + unsigned int utrustee=0; + btrustee[l]='\0'; + if (1 == sscanf(btrustee, "%x", &utrustee)) { + return((int)utrustee); + } + } + return(-1); +} + +static int scan_trustees_from_disk(int dev, ino_t inode, int *offset, + int max_trustees, uint32 *trustee_ids, int *trustees) +/* returns count of trustees if all ok */ +{ + char buf[255]; + int l; + int count=0; + uint8 buf_uc[4]; + DIR *d; + U32_TO_BE32(inode, buf_uc); + l=sprintf(buf, "%s/%x/%x/%x/%x/%x.t", path_attributes, + dev, + (int) buf_uc[0], + (int) buf_uc[1], + (int) buf_uc[2], + (int) buf_uc[3]); + seteuid(0); + d = opendir(buf); + if (NULL != d) { + uint8 *p=buf+l; + struct dirent *dirbuff; + *p++ = '/'; + l=0; + if ((unsigned int)(*offset) >= MAX_U16) + *offset=0; + while (count < max_trustees && + (dirbuff = readdir(d)) != (struct dirent*)NULL){ + if (l++ > *offset) { + if (dirbuff->d_ino) { + char btrustee[255]; + int len; + unsigned int id; + if (1 == sscanf(dirbuff->d_name, "%x", &id) && id > 0) { + strcpy(p, dirbuff->d_name); + len=readlink(buf, btrustee, 254); + if (len > 0) { + unsigned int utrustee=0; + btrustee[len]='\0'; + if (1 == sscanf(btrustee, "%x", &utrustee)) { + *trustee_ids++ = (uint32) id; + *trustees++ = (int) utrustee; + count++; + } + } + } + } + } + } + *offset=l; + closedir(d); + } + reseteuid(); + return(count); +} + +int get_own_trustee(int dev, ino_t inode, int look_for_trustee) +{ + if (act_obj_id == 1){ /* supervisor */ + if ( (look_for_trustee == TRUSTEE_S) || (look_for_trustee == TRUSTEE_M) + || (look_for_trustee == (TRUSTEE_S | TRUSTEE_M)) ) + return(look_for_trustee | TRUSTEE_S); + } + return(0); +} + +int set_nw_trustee(int dev, ino_t inode, uint32 id, int trustee) +{ + return(0); + +#if 0 + if (get_own_trustee(dev, inode, TRUSTEE_M) & (TRUSTEE_M | TRUSTEE_S)){ + + } else return(-0x8c); /* no modify privileges */ +#endif +} + + +void free_nw_ext_inode(int dev, ino_t inode) +/* removes all attrib or trustees entries for files or dirs */ +/* must be called after deleting nw file or dir */ +{ + free_attr_from_disk(dev, inode); + free_trustees_from_disk(dev, inode); +} diff --git a/nwattrib.h b/nwattrib.h new file mode 100644 index 0000000..0e24a85 --- /dev/null +++ b/nwattrib.h @@ -0,0 +1,16 @@ +/* nwattrib.h 01-Feb-98 */ + +#ifndef _NWATTRIB_H_ +#define _NWATTRIB_H_ + +extern uint32 get_nw_attrib_dword(struct stat *stb, int voloptions); +extern int set_nw_attrib_dword(struct stat *stb, int voloptions, uint32 attrib); +extern int set_nw_attrib_byte (struct stat *stb, int voloptions, int battrib); +extern void set_nw_archive_bit(int dev, ino_t inode); + +extern int set_nw_trustee(int dev, ino_t inode, uint32 id, int trustee); + + +extern void free_nw_ext_inode(int dev, ino_t inode); +#endif + diff --git a/nwbind.c b/nwbind.c index c519072..1ccce39 100644 --- a/nwbind.c +++ b/nwbind.c @@ -1,5 +1,5 @@ /* nwbind.c */ -#define REVISION_DATE "27-Nov-97" +#define REVISION_DATE "04-Feb-98" /* NCP Bindery SUB-SERVER */ /* authentification and some message handling */ diff --git a/nwconn.c b/nwconn.c index 8a289e1..9f3b4b5 100644 --- a/nwconn.c +++ b/nwconn.c @@ -53,7 +53,7 @@ static uint8 readbuff[IPX_MAX_DATA]; static uint8 saved_readbuff[IPX_MAX_DATA]; static int saved_sequence=-1; -static int rw_buffer_size = 512; /* default */ +static int rw_buffer_size = LOC_RW_BUFFERSIZE; /* default */ static NCPREQUEST *ncprequest = (NCPREQUEST*)readbuff; static uint8 *requestdata = readbuff + sizeof(NCPREQUEST); @@ -285,7 +285,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', memset(xdata, 0, sizeof(struct XDATA)); if ((result = nw_get_volume_name(volume, xdata->name))>-1){ struct fs_usage fsp; - if (!nw_get_fs_usage(xdata->name, &fsp, + if (!nw_get_fs_usage(xdata->name, &fsp, entry8_flags&0x40 )) { int sector_scale=1; while (fsp.fsu_blocks/sector_scale > 0xffff) @@ -472,7 +472,6 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', if (code) completition = (uint8) -code; } else if (*p == 0xd){ /* Add Trustees to DIR */ /******** AddTrustesstoDir ***************/ -#if 0 struct INPUT { uint8 header[7]; /* Requestheader */ uint8 div[3]; /* 0x0, dlen, ufunc */ @@ -480,11 +479,15 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', uint8 trustee_id[4]; /* Trustee Object ID */ uint8 trustee_right_mask; uint8 pathlen; - uint8 path; + uint8 path[2]; } *input = (struct INPUT *) (ncprequest); - /* TODO !!!!!!!!!!!!!!!!!!!! */ -#endif - do_druck++; + int result = nw_add_trustee( + input->dir_handle, + input->path, input->pathlen, + GET_BE32(input->trustee_id), + (int)input->trustee_right_mask, + 0); + if (result) completition = (uint8) -result; } else if (*p == 0xf){ /* rename dir */ /******** Rename DIR *********************/ int dir_handle = (int) *(p+1); @@ -544,7 +547,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', result = nw_get_volume_name(volume, xdata->name); if (result > -1) { struct fs_usage fsp; - if (!nw_get_fs_usage(xdata->name, &fsp, + if (!nw_get_fs_usage(xdata->name, &fsp, entry8_flags&0x40 )) { int sector_scale=1; while (fsp.fsu_blocks/sector_scale > 0xffff) @@ -695,8 +698,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', data_len = sizeof(struct XDATA); } else completition = 0x9c; /* no more trustees */ } else completition = (uint8) (-result); - } else if (*p == 0x27) { /* Add Ext Trustees to DIR */ -#if 0 + } else if (*p == 0x27) { /* Add Ext Trustees to DIR or File */ struct INPUT { uint8 header[7]; /* Requestheader */ uint8 div[3]; /* 0x0, dlen, ufunc */ @@ -704,11 +706,15 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', uint8 trustee_id[4]; /* Trustee Object ID */ uint8 trustee_rights[2]; /* low - high */ uint8 pathlen; - uint8 path; + uint8 path[2]; } *input = (struct INPUT *) (ncprequest); - /* TODO !!!!!!!!!!!!!!!!!!!! */ -#endif - do_druck++; + int result = nw_add_trustee( + input->dir_handle, + input->path, input->pathlen, + GET_BE32(input->trustee_id), + GET_16(input->trustee_rights), + 1); /* extended */ + if (result) completition = (uint8) -result; } else if (*p == 0x28){ /* Scan File Physical ??? */ struct INPUT { @@ -863,7 +869,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', /* uint8 len = *(requestdata+1); */ uint8 ufunc = *(requestdata+2); uint8 *rdata = requestdata+3; - + switch (ufunc) { #if FUNC_17_02_IS_DEBUG case 0x02 : { @@ -962,24 +968,24 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', break; case 0x64: { /* create queue */ -#if 0 +#if 0 int q_typ = GET_BE16(rdata); -#endif +#endif int q_name_len = *(rdata+2); #if 0 uint8 *q_name = rdata+3; -#endif +#endif uint8 *dirhandle = rdata+3+q_name_len; int pathlen = *(rdata+3+q_name_len+1); uint8 *path = rdata+3+q_name_len+2; uint8 new_path[257]; - int result = conn_get_full_path(*dirhandle, + int result = conn_get_full_path(*dirhandle, path, pathlen, new_path); if (result > -1) { int diffsize = result - pathlen; *dirhandle = 0; memcpy(path, new_path, result); - if (diffsize) + if (diffsize) requestlen+=diffsize; /* !!!!!! */ return(-1); /* nwbind must do the rest */ } else @@ -991,7 +997,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', case 0x79: /* create queue job and file */ return(-2); /* nwbind must do prehandling */ - + case 0x6C: { /* Get Queue Job Entry old */ uint32 q_id = GET_BE32(rdata); int job_id = GET_BE16(rdata+4); @@ -1000,7 +1006,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', requestlen+=6; /* !!!!!! */ } return(-1); /* nwbind must do the rest */ - + case 0x69: /* close file and start queue old ?? */ case 0x7f: { /* close file and start queue */ struct INPUT { @@ -1106,12 +1112,25 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', case 0x21 : { /* Negotiate Buffer Size, Packetsize */ uint8 *getsize=responsedata; - rw_buffer_size = min(LOC_RW_BUFFERSIZE, - (int) (GET_BE16((uint8*)requestdata))); + int buffer_size = (int) (GET_BE16((uint8*)requestdata)); + /* Der Novell-Client der PAM's Net/E-Ethernetkarte + für Atari ST/TT meldet ein Packetsize von 0 wenn + nwserv NACH dem Novell Client NET_S1.PRG + gestartet wird. Da 0 in jedem Falle ein unsinniger + Wert ist, wird rw_buffer_size nicht verwendet. + Hayo Schmidt <100305.1424@compuserve.com>, 7-Dec-97 + */ + if (buffer_size >= 512) { + rw_buffer_size = min(LOC_RW_BUFFERSIZE, buffer_size); + XDPRINTF((2,0, "Negotiate Buffer size = 0x%04x,(%d)", + (int) rw_buffer_size, (int) rw_buffer_size)); + } else { + XDPRINTF((1,0, "Invalid Packetsize = %d, " + "Negotiate Buffer Size is set to %d", + buffer_size, rw_buffer_size)); + } U16_TO_BE16(rw_buffer_size, getsize); data_len = 2; - XDPRINTF((2,0, "Negotiate Buffer size = 0x%04x,(%d)", - (int) rw_buffer_size, (int) rw_buffer_size)); } break; @@ -1389,7 +1408,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', uint8 data[2]; /* filename */ } *input = (struct INPUT *)ncprequest; completition = - (uint8) (-nw_chmod_datei((int)input->dir_handle, + (uint8) (-nw_set_file_attributes((int)input->dir_handle, input->data, (int)input->len, (int)input->attrib, (int)input->access)); @@ -1874,13 +1893,13 @@ static void handle_after_bind() int fnlen = (int) *(bindresponse + 3 * sizeof(int)); uint8 objname[48]; /* ncpserv have changed the structure */ - + if (ufunc==0x14) { xstrmaxcpy(objname, requestdata+6, (int) *(requestdata+5)); } else if (ufunc==0x18){ xstrmaxcpy(objname, requestdata+14, (int) *(requestdata+13)); } else objname[0]='\0'; - + set_nw_user(*((int*)bindresponse), /* gid */ *((int*)(bindresponse+sizeof(int))), /* uid */ *((uint32*)(bindresponse + 2 * sizeof(int))), /* id */ @@ -1905,10 +1924,10 @@ static void handle_after_bind() int result = creat_queue_job(q_id, qjob, responsedata, (ufunc == 0x68) ); - if (result > -1) + if (result > -1) data_len=result; else - completition = (uint8) -result; + completition = (uint8) -result; } break; @@ -1951,12 +1970,12 @@ static void handle_after_bind() uint32 q_id = GET_BE32(input->queue_id); uint8 *qjob = bindresponse; int result = service_queue_job(q_id, qjob, - responsedata, + responsedata, ufunc==0x71); - if (result > -1) + if (result > -1) data_len=result; else - completition = (uint8) -result; + completition = (uint8) -result; } break; @@ -2219,7 +2238,7 @@ int main(int argc, char **argv) while (fl_get_int >= 0) { int data_len = read(0, readbuff, sizeof(readbuff)); - + /* this read is a pipe or a socket read, * depending on CALL_NWCONN_OVER_SOCKET */ @@ -2256,10 +2275,10 @@ int main(int argc, char **argv) saved_sequence = -1; } else { /* this calls I must handle, it is a request */ time_t act_time=time(NULL); - - if (act_time > last_time+300 && saved_sequence == -1) { + + if (act_time > last_time+300 && saved_sequence == -1) { /* ca. 5 min. reset wdogs */ - call_nwbind(1); + call_nwbind(1); last_time=act_time; } diff --git a/nwfile.c b/nwfile.c index f6f56db..7d1f5e6 100644 --- a/nwfile.c +++ b/nwfile.c @@ -1,5 +1,5 @@ -/* nwfile.c 26-Nov-97 */ -/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany +/* nwfile.c 01-Feb-98 */ +/* (C)opyright (C) 1993,1998 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 @@ -27,7 +27,9 @@ #include "nwshare.h" #include "nwfile.h" #include "connect.h" +#include "nwattrib.h" #include "nwconn.h" +#include "unxfile.h" # include @@ -91,6 +93,7 @@ static int new_file_handle(uint8 *unixname, int task) fh->fd = -2; fh->offd = 0L; fh->tmodi = 0L; + fh->modified = 0; fh->st_ino = 0; strcpy((char*)fh->fname, (char*)unixname); fh->fh_flags = 0; @@ -116,8 +119,15 @@ static int free_file_handle(int fhandle) fh->size_mmap = 0; } close(fh->fd); - if (fh->st_ino) + if (fh->st_ino) { share_file(fh->st_dev, fh->st_ino, 0); + if (fh->modified) { + fh->modified=0; +#if NEW_ATTRIB_HANDLING + set_nw_archive_bit(fh->st_dev, fh->st_ino); +#endif + } + } } if (fh->tmodi > 0L && !(FH_IS_PIPE_COMMAND & fh->fh_flags) && !(FH_IS_READONLY & fh->fh_flags) ) { @@ -225,7 +235,11 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, ? get_real_access(stbuff) : -1; int did_grpchange = 0; - if (dowrite && (voloptions & VOL_OPTION_READONLY)) { + + if (dowrite && (acc > -1) && (acc & W_OK) && !(creatmode&0x8) && + (get_nw_attrib_dword(stbuff, voloptions) & FILE_ATTR_R)) + completition = -0x94; + else if (dowrite && (voloptions & VOL_OPTION_READONLY)) { completition = (creatmode&3) ? -0x84 : -0x94; } else if (acc > -1) { /* do exist */ @@ -516,8 +530,15 @@ int nw_close_file(int fhandle, int reset_reuse) fh->size_mmap = 0; } result=close(fh->fd); - if (fh->st_ino) + if (fh->st_ino) { share_file(fh->st_dev, fh->st_ino, 0); + if (fh->modified) { + fh->modified=0; +#if NEW_ATTRIB_HANDLING + set_nw_archive_bit(fh->st_dev, fh->st_ino); +#endif + } + } } fh->fd = -1; if (fh->tmodi > 0L && !(fh->fh_flags & FH_IS_PIPE) @@ -723,22 +744,16 @@ int nw_write_file(int fhandle, uint8 *data, int size, uint32 offset) if (fh->offd > -1L) { size = write(fh->fd, data, size); fh->offd+=(long)size; + if (!fh->modified) + fh->modified++; } else size = -1; return(size); } else { /* truncate FILE */ - int result; -#ifdef LINUX - result = ftruncate(fh->fd, offset); -#else - struct flock flockd; - flockd.l_type = 0; - flockd.l_whence = SEEK_SET; - flockd.l_start = offset; - flockd.l_len = 0; - result = fcntl(fh->fd, F_FREESP, &flockd); -#endif + int result = unx_ftruncate(fh->fd, offset); XDPRINTF((5,0,"File %s is truncated, result=%d", fh->fname, result)); fh->offd = -1L; + if (!fh->modified) + fh->modified++; return(result); } } @@ -763,6 +778,8 @@ int nw_server_copy(int qfhandle, uint32 qoffset, if (lseek(fhq->fd, qoffset, SEEK_SET) > -1L && lseek(fhz->fd, zoffset, SEEK_SET) > -1L) { retsize = 0; + if (size && !fhz->modified) + fhz->modified++; while (size) { int xsize = read(fhq->fd, buff, min(size, (uint32)sizeof(buff))); if (xsize > 0){ @@ -875,20 +892,26 @@ int get_nwfd(int fhandle) int nw_unlink(int volume, char *name) { struct stat stbuff; - if (get_volume_options(volume) & VOL_OPTION_IS_PIPE) + int voloptions=get_volume_options(volume); + if (voloptions & VOL_OPTION_IS_PIPE) return(0); /* don't delete 'pipe commands' */ else if (get_volume_options(volume) & VOL_OPTION_READONLY) return(-0x8a); /* don't delete 'readonly' */ if (stat(name, &stbuff)) return(-0x9c); /* wrong path */ + if (get_nw_attrib_dword(&stbuff, voloptions) & FILE_ATTR_R) + return(-0x8a); /* don't delete 'readonly' */ if ( -1 == share_file(stbuff.st_dev, stbuff.st_ino, 0x12|0x8) || ( !(entry8_flags&0x10) && -1 == share_file(stbuff.st_dev, stbuff.st_ino, 0x11|0x4)) ) - return(-0x8a); /* NO Delete Privileges */ - if (!unlink(name)) + return(-0x8a); /* NO Delete Privileges, file is shared open */ + if (!unlink(name)) { + free_nw_ext_inode(stbuff.st_dev, stbuff.st_ino); return(0); + } return(-0x8a); /* NO Delete Privileges */ } + diff --git a/nwfile.h b/nwfile.h index 535b4ff..85b315e 100644 --- a/nwfile.h +++ b/nwfile.h @@ -1,4 +1,4 @@ -/* nwfile.h 21-Jul-97 */ +/* nwfile.h 09-Feb-98 */ #ifndef _NWFILE_H_ #define _NWFILE_H_ #include "extpipe.h" @@ -10,6 +10,7 @@ typedef struct { uint8 *p_mmap; /* for use with mmap */ int size_mmap; time_t tmodi; /* modification TIME */ + int modified; /* is file modified / written */ FILE_PIPE *f; /* for PIPE */ int fh_flags; /* 2 = PIPE */ /* 4 = don't reuse after close */ diff --git a/nwroute.c b/nwroute.c index 4687f6e..dbed9d5 100644 --- a/nwroute.c +++ b/nwroute.c @@ -1,5 +1,5 @@ -/* nwroute.c 17-Jul-97 */ -/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany +/* nwroute.c 08-Feb-98 */ +/* (C)opyright (C) 1993,1998 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 @@ -699,14 +699,19 @@ static int look_for_interfaces(void); void send_sap_rip_broadcast(int mode) -/* mode=0, standard broadcast */ -/* mode=1, first trie */ -/* mode=2, shutdown */ -/* mode=3, update routes */ -/* mode=4, resend to net */ +/* mode=0, standard broadcast */ +/* mode=1, first trie */ +/* mode=2, shutdown */ +/* mode=3, update routes */ +/* mode=4, resend to net */ +/* mode=5, force update routes */ { static int flipflop=1; int force_print_routes=(mode == 1) ? 1 : 0; + if (mode == 5) { + force_print_routes++; + mode = 3; + } if (auto_detect_interfaces) force_print_routes += look_for_interfaces(); if (mode) { diff --git a/nwserv.c b/nwserv.c index 0fbeac6..c29bad1 100644 --- a/nwserv.c +++ b/nwserv.c @@ -1,7 +1,7 @@ -/* nwserv.c 08-Oct-97 */ +/* nwserv.c 08-Feb-98 */ /* MAIN Prog for NWSERV + NWROUTED */ -/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany +/* (C)opyright (C) 1993,1998 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 @@ -1120,11 +1120,11 @@ static void close_all(void) #ifdef LINUX # if INTERNAL_RIP_SAP -#if 0 +#if 1 if (!(ipx_flags&1)) { for (j=0; jis_up) { + if (nd->is_up==1) { /* only no auto interfaces */ XDPRINTF((1, 0, "Close Device=%s, frame=%d", nd->devname, nd->frame)); exit_dev(nd->devname, nd->frame); @@ -1165,7 +1165,7 @@ static void sig_chld(int rsig) } #endif -static int fl_get_int=0; +static int fl_get_int=0; /* 1 .. 8 */ static void sig_quit(int rsig) { signal(rsig, SIG_IGN); @@ -1196,12 +1196,24 @@ static void handle_usr1_request(void) send_sap_rip_broadcast(3); } +static void handle_usr2_request(void) +{ + XDPRINTF((2,0, "Got USR2, force sending rip/sap")); + send_sap_rip_broadcast(5); +} + static void sig_usr1(int rsig) { fl_get_int|=4; signal(rsig, sig_usr1); } +static void sig_usr2(int rsig) +{ + fl_get_int|=8; + signal(rsig, sig_usr2); +} + static void set_sigs(int mode) { signal(SIGPIPE, SIG_IGN); @@ -1211,12 +1223,14 @@ static void set_sigs(int mode) signal(SIGINT, SIG_IGN); signal(SIGHUP, SIG_IGN); signal(SIGUSR1, SIG_IGN); + signal(SIGUSR2, SIG_IGN); } else { signal(SIGTERM, sig_quit); signal(SIGQUIT, sig_quit); signal(SIGINT, sig_quit); signal(SIGHUP, sig_hup); signal(SIGUSR1, sig_usr1); + signal(SIGUSR2, sig_usr2); } } @@ -1225,12 +1239,17 @@ static int server_is_down=0; static int usage(char *prog) { #if !IN_NWROUTED - fprintf(stderr, "usage:\t%s [-V|-h|-u|-k[q]|y]\n", prog); + fprintf(stderr, "usage:\t%s [-V|-h|-f|-u|-k[q]|y]\n", prog); + fprintf(stderr, "or:\t%s -a device frame netnum\n", prog); + fprintf(stderr, "or:\t%s -d device frame\n", prog); #else fprintf(stderr, "usage:\t%s [-V|-h|-u|-k[q]]\n", prog); #endif fprintf(stderr, "\t-V: print version\n"); + fprintf(stderr, "\t-a: add interface, frames = '802.2' '802.3' 'etherii' 'snap'\n"); + fprintf(stderr, "\t-d: delete interface.\n"); fprintf(stderr, "\t-h: send HUP to main process\n"); + fprintf(stderr, "\t-f: force send rip/sap and update routing int. table\n"); fprintf(stderr, "\t-u: update int. routing table\n"); fprintf(stderr, "\t-k: stop main process, wait for it.\n"); fprintf(stderr, "\t-kq: don't wait till stop of main process\n"); @@ -1254,9 +1273,51 @@ int main(int argc, char **argv) if (*a == '-') { while (*(++a)) { switch (*a) { + case 'a' : + case 'd' : + if ( (*a == 'a' && argc - j == 4) + || (*a == 'd' && argc - j == 3) ) { + int result; + int frame=-1; + uint32 netnum=0L; + char buf[256]; + strcpy(buf, argv[j+2]); + upstr(buf); + if (!strcmp(buf, "802.3")) + frame=IPX_FRAME_8023; + else if (!strcmp(buf, "802.2")) + frame=IPX_FRAME_8022; + else if (!strcmp(buf, "SNAP")) + frame=IPX_FRAME_SNAP; + else if (!strcmp(buf, "ETHERNET_II")) + frame=IPX_FRAME_ETHERII; + else if (!strcmp(buf, "ETHERII")) + frame=IPX_FRAME_ETHERII; +# ifdef IPX_FRAME_TR_8022 + else if (!strcmp(buf, "TOKEN")) + frame=IPX_FRAME_TR_8022; +# endif + + if (*a == 'a' && frame > -1) { + char dummy; + if (sscanf(argv[j+3], "%ld%c", &netnum, &dummy) != 1) + sscanf(argv[j+3], "%lx", &netnum); + } + if (netnum > 0) + result=add_device_net(argv[j+1], frame, netnum); + else if ( *a == 'd') { + exit_dev(argv[j+1], frame); + result=0; + } else + return(usage(argv[0])); + return((result<0) ? 1 : 0); + } else + return(usage(argv[0])); + case 'h' : init_mode = 1; break; case 'k' : init_mode = 2; break; case 'u' : init_mode = 3; break; + case 'f' : init_mode = 5; break; case 'q' : if (init_mode == 2) init_mode=4; break; case 'v' : case 'V' : fprintf(stderr, "\n%s:Version %d.%d.pl%d\n", @@ -1369,8 +1430,10 @@ int main(int argc, char **argv) if (fl_get_int) { if (fl_get_int & 1) handle_hup_reqest(); - else if (fl_get_int & 4) + if (fl_get_int & 4) handle_usr1_request(); + if (fl_get_int & 8) + handle_usr2_request(); if (fl_get_int & 2) down_server(); fl_get_int=0; diff --git a/nwvolume.c b/nwvolume.c index 5a9591a..27fa964 100644 --- a/nwvolume.c +++ b/nwvolume.c @@ -1,5 +1,5 @@ -/* nwvolume.c 28-Nov-97 */ -/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany +/* nwvolume.c 01-Feb-98 */ +/* (C)opyright (C) 1993,1998 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 @@ -38,6 +38,7 @@ int loaded_namespaces=0; uint8 *home_dir=NULL; int home_dir_len=0; char *path_vol_inodes_cache=NULL; +char *path_attributes=NULL; static int max_nw_vols=MAX_NW_VOLS; @@ -82,6 +83,7 @@ void nw_init_volumes(FILE *f) used_nw_volumes = 0; loaded_namespaces = 0; new_str(path_vol_inodes_cache, "/var/spool/nwserv/.volcache"); + new_str(path_attributes, "/var/lib/nwserv/attrib"); while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))) { if ( what == 1 && used_nw_volumes < max_nw_vols && strlen((char*)buff) > 3){ uint8 sysname[256]; @@ -183,6 +185,8 @@ void nw_init_volumes(FILE *f) } } else if (what==40) { /* path for vol/dev/inode->path cache */ new_str(path_vol_inodes_cache, buff); + } else if (what==46) { /* path for attribute handling */ + new_str(path_attributes, buff); } } /* while */ } diff --git a/nwvolume.h b/nwvolume.h index 54e088f..4f6142a 100644 --- a/nwvolume.h +++ b/nwvolume.h @@ -1,5 +1,5 @@ -/* nwvolume.h 28-Nov-97 */ -/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany +/* nwvolume.h 01-Feb-98 */ +/* (C)opyright (C) 1993,1998 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 @@ -80,6 +80,7 @@ extern int loaded_namespaces; extern uint8 *home_dir; extern int home_dir_len; extern char *path_vol_inodes_cache; /* for namespace routines */ +extern char *path_attributes; /* for attribute handling */ extern void nw_init_volumes(FILE *f); extern void nw_setup_vol_opts(int act_gid, int act_uid, diff --git a/tools.c b/tools.c index 8b80e4c..1c478f3 100644 --- a/tools.c +++ b/tools.c @@ -1,5 +1,5 @@ -/* tools.c 26-Nov-97 */ -/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany +/* tools.c 08-Feb-98 */ +/* (C)opyright (C) 1993,1998 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 @@ -444,6 +444,8 @@ void init_tools(int module, int options) sig = SIGTERM; } else if (options == 3) { /* update tables */ sig = SIGUSR1; + } else if (options == 5) { /* force update tables */ + sig = SIGUSR2; } else { errorp(11, "INIT", "Program pid=%d already running and pidfn=%s exists" , kill_pid, pidfn); @@ -466,12 +468,12 @@ void init_tools(int module, int options) fprintf(stderr, "\n%s not yet stopped!\n", get_modstr()); exit(1); } else if (sig == SIGUSR1 || sig == SIGTERM) { /* we try twice */ - sleep(2); + sleep(2); kill(kill_pid, sig); } } exit(0); - } else if (options == 1 || options == 2 || options == 3 || options == 4) { + } else if (options == 1 || options == 2 || options == 3 || options == 4|| options==5) { errorp(11, "INIT", "Program not yet running." ); exit(1); } diff --git a/unxfile.c b/unxfile.c index fcdfb09..2063d03 100644 --- a/unxfile.c +++ b/unxfile.c @@ -1,6 +1,6 @@ -/* unxfile.c: 09-Jul-97*/ +/* unxfile.c: 05-Feb-98*/ -/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany +/* (C)opyright (C) 1993,1998 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 @@ -18,6 +18,7 @@ */ #include "net.h" +#include #include "unxfile.h" int unx_mvdir(uint8 *oldname, uint8 *newname) @@ -67,6 +68,30 @@ int unx_xmkdir(char *unixname, int mode) return(-1); } +int unx_xrmdir(char *unixname) +/* removes complete directory if possible */ +{ + DIR *d = opendir(unixname); + if (NULL != (d = opendir(unixname))) { + struct dirent *dirbuff; + int len = strlen(unixname); + char *buf = xmalloc(len + 300); + char *p = buf+len; + memcpy(buf, unixname, len); + *p++ = '/'; + while ((dirbuff = readdir(d)) != (struct dirent*)NULL){ + if (dirbuff->d_ino) { + strcpy(p, dirbuff->d_name); + if (unlink(buf) && unx_xrmdir(buf)) + break; + } + } + xfree(buf); + closedir(d); + } + return(rmdir(unixname)); +} + #if 0 int unx_mvdir(uint8 *oldname, uint8 *newname) { @@ -80,3 +105,17 @@ int unx_mvdir(uint8 *oldname, uint8 *newname) } #endif +int unx_ftruncate(int fd, uint32 size) +{ +#ifdef LINUX + return(ftruncate(fd, size)); +#else + struct flock flockd; + flockd.l_type = 0; + flockd.l_whence = SEEK_SET; + flockd.l_start = size; + flockd.l_len = 0; + result = fcntl(fd, F_FREESP, &flockd); +#endif +} + diff --git a/unxfile.h b/unxfile.h index 0bd6e70..1afd846 100644 --- a/unxfile.h +++ b/unxfile.h @@ -1,5 +1,5 @@ -/* unxfile.h: 09-Jul-97*/ -/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany +/* unxfile.h: 05-Feb-98 */ +/* (C)opyright (C) 1993,1998 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 @@ -21,5 +21,8 @@ extern int unx_mvdir(uint8 *oldname, uint8 *newname); extern int unx_mvfile(uint8 *oldname, uint8 *newname); extern int unx_mvfile_or_dir(uint8 *oldname, uint8 *newname); extern int unx_xmkdir(char *unixname, int mode); +extern int unx_xrmdir(char *unixname); + +extern int unx_ftruncate(int fd, uint32 size); #endif