diff --git a/CHANGES b/CHANGES index 60a652e..8b0aa94 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,5 @@ Sorry, this is in German only. :-( -Aenderungen in mars_nwe bis zum : 02-Jan-96 +Aenderungen in mars_nwe bis zum : 22-Jan-96 -------------------------------- Erste 'oeffentliche' Version ^^^^^^^^^^ VERSION 0.94 ^^^^^^^^ @@ -59,3 +59,6 @@ Erste 'oeffentliche' Version - Es kann nun gesteuert werden (nw.ini:310), dass wdogs zu einer connection nur gesendet werden, falls der client ueber eine device net < angebbarer anzahl tics ist. (z.B. fuer IPX ueber ISDN) +- Verarbeitung von 'PIPE Jobs' eingebaut. +- Bug beim Drucken korrigiert. (nprint funktionierte nicht) + diff --git a/README b/README index 46ddf01..5f825a7 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -(C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany +(C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany to compile and install, please read INSTALL ! @@ -65,7 +65,7 @@ Have luck with trying. :) BTW: The kick to make mars_nwe public was the publication of linware ( lwared ), the Novell-Server-Emulator from Ales Dryak (A.Dryak@sh.cvut.cz). -I hope both products kann make profit from each other. +I hope both products can make profit from each other. -----> SuperNOS ala Linux ;-) Novell don't want to make it anymore. :-( diff --git a/README.ger b/README.ger index eb4d7d2..3d4c98a 100644 --- a/README.ger +++ b/README.ger @@ -1,4 +1,4 @@ -(C)opyright (C) 1993,1995 Martin Stover, Marburg +(C)opyright (C) 1993,1996 Martin Stover, Marburg Hilfe zum Kompilieren bzw. Installieren siehe in 'INSTALL' ! diff --git a/connect.c b/connect.c index e8d3959..2bd9288 100644 --- a/connect.c +++ b/connect.c @@ -1,4 +1,4 @@ -/* connect.c 13-Jan-96 */ +/* connect.c 22-Jan-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -33,13 +33,11 @@ extern int errno; static int default_uid=-1; static int default_gid=-1; +#include "nwvolume.h" #include "connect.h" -#define MAX_NW_DIRS 255 -static NW_DIR dirs[MAX_NW_DIRS]; -static int used_dirs=0; -static NW_VOL vols[MAX_NW_VOLS]; -static int used_vols=0; +NW_DIR dirs[MAX_NW_DIRS]; +int used_dirs=0; static int connect_is_init = 0; @@ -62,20 +60,20 @@ static char *build_unix_name(NW_PATH *nwpath, int modus) static char unixname[300]; /* must be big enouugh */ int volume = nwpath->volume; char *p, *pp; - if (volume < 0 || volume >= used_vols) { + if (volume < 0 || volume >= used_nw_volumes) { fprintf(stderr, "build_unix_name volume=%d not ok\n", volume); strcpy(unixname, "ZZZZZZZZZZZZ"); /* vorsichthalber */ return(unixname); } - strcpy(unixname, vols[volume].unixname); /* first UNIXNAME VOLUME */ + strcpy(unixname, nw_volumes[volume].unixname); /* first UNIXNAME VOLUME */ p = pp = unixname+strlen(unixname); strcpy(p, nwpath->path); /* now the path */ p += strlen(nwpath->path); if ( (!(modus & 1)) && nwpath->fn[0]) - strcpy(p, nwpath->fn); /* und jetzt fn */ + strcpy(p, nwpath->fn); /* and now fn */ else if ((modus & 2) && (*(p-1) == '/')) *(p-1) = '\0'; - if (vols[volume].options & 1) downstr((uint8*)pp); + if (nw_volumes[volume].options & 1) downstr((uint8*)pp); return(unixname); } @@ -84,11 +82,11 @@ static int new_file_handle(void) int rethandle = -1; FILE_HANDLE *fh=NULL; while (++rethandle < anz_fhandles) { - if (file_handles[rethandle].fd < 0) { /* empty slot */ - fh = &(file_handles[rethandle]); + FILE_HANDLE *fh=&(file_handles[rethandle]); + if (fh->fd == -1 && !(fh->flags & 4)) { /* empty slot */ rethandle++; break; - } + } else fh=NULL; } if (fh == NULL) { if (anz_fhandles < MAX_FILEHANDLES) { @@ -97,36 +95,48 @@ static int new_file_handle(void) } else return(0); /* no free handle anymore */ } /* init handle */ - fh->fd = -1; + fh->fd = -2; fh->offd = 0L; fh->tmodi = 0L; fh->name[0] = '\0'; + fh->flags = 0; + fh->f = NULL; + XDPRINTF((5, 0, "new_file_handle=%d, anz_fhandles=%d", + rethandle, anz_fhandles)); return(rethandle); } static int free_file_handle(int fhandle) { + int result=-0x88; if (fhandle > 0 && (fhandle <= anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle-1]); if (fh->fd > -1) { - close(fh->fd); - fh->fd = -1; - if (fh->tmodi > 0L) { + if (fh->flags & 2) { + if (fh->f) pclose(fh->f); + fh->f = NULL; + } else close(fh->fd); + if (fh->tmodi > 0L && !(fh->flags & 2)) { /* now set date and time */ struct utimbuf ut; ut.actime = ut.modtime = fh->tmodi; utime(fh->name, &ut); + fh->tmodi = 0L; } } - if (fhandle == anz_fhandles) { + fh->fd = -1; + if (fhandle == anz_fhandles && !(fh->flags & 4)) { /* was last */ anz_fhandles--; - while (anz_fhandles && file_handles[anz_fhandles-1].fd < 0) + while (anz_fhandles && file_handles[anz_fhandles-1].fd == -1 + && !(file_handles[anz_fhandles-1].flags & 4) ) anz_fhandles--; } - return(0); + result=0; } - return(-0x88); /* wrong filehandle */ + XDPRINTF((5, 0, "free_file_handle=%d, anz_fhandles=%d, result=%d", + fhandle, anz_fhandles, result)); + return(result); /* wrong filehandle */ } static int new_dir_handle(ino_t inode, NW_PATH *nwpath) @@ -174,7 +184,7 @@ static int new_dir_handle(ino_t inode, NW_PATH *nwpath) if ((fh->f = opendir(fh->unixname)) != (DIR*) NULL){ fh->kpath = fh->unixname + strlen(fh->unixname); fh->volume = nwpath->volume; - fh->vol_options = vols[fh->volume].options; + fh->vol_options = nw_volumes[fh->volume].options; fh->inode = inode; fh->timestamp = akttime; } else { @@ -223,14 +233,14 @@ void set_guid(int gid, int uid) } else XDPRINTF((5,0,"SET GID=%d, UID=%d OK", gid, uid)); } -char *conn_get_nwpath_name(NW_PATH *p) +static char *conn_get_nwpath_name(NW_PATH *p) /* for debugging */ { static char nwpathname[300]; char volname[100]; - if (p->volume < 0 || p->volume >= used_vols) { + if (p->volume < 0 || p->volume >= used_nw_volumes) { sprintf(volname, "<%d=NOT-OK>", (int)p->volume); - } else strcpy(volname, vols[p->volume].sysname); + } else strcpy(volname, nw_volumes[p->volume].sysname); sprintf(nwpathname, "%s:%s%s", volname, p->path, p->fn); return(nwpathname); } @@ -262,25 +272,13 @@ static int x_str_match(uint8 *s, uint8 *p) break; case '.' : -#if 0 - if (!*s && !*p) return(1); /* point at end */ -#else if (!*s && (!*p || *p == '*' || *p == '?')) return(1); -#endif if (pc != *s++) return(0); if (*p == '*') return(1); break; case '*' : -#if 0 - if (!*p) { - uint8 *ss=s; - while (*ss) if (*ss++ == '.') return(0); - return(1); /* last star */ - } -#else if (!*p) return(1); -#endif while (*s){ if (x_str_match(s, p) == 1) return(1); ++s; @@ -330,14 +328,14 @@ static int x_str_match(uint8 *s, uint8 *p) return ( (*s) ? 0 : 1); } -static int str_match(uint8 *s, uint8 *p, uint8 options) +int fn_match(uint8 *s, uint8 *p, uint8 options) { uint8 *ss=s; int len=0; int pf=0; for (; *ss; ss++){ if (*ss == '.') { - if (pf++) return(0); /* Kein 2. Punkt */ + if (pf++) return(0); /* no 2. pouint */ len=0; } else { if ((pf && len > 3) || len > 8) return(0); @@ -372,8 +370,8 @@ static int func_search_entry(NW_PATH *nwpath, int attrib, FUNC_SEARCH fs_local; if (!fs) fs = &fs_local; fs->attrib = attrib; - if (volume < 0 || volume >= used_vols) return(-1); /* something wrong */ - else soptions = vols[volume].options; + if (volume < 0 || volume >= used_nw_volumes) return(-1); /* something wrong */ + else soptions = nw_volumes[volume].options; strcpy(entry, nwpath->fn); if (soptions & 1) downstr(entry); /* now downshift chars */ nwpath->fn[0] = '\0'; @@ -391,7 +389,7 @@ static int func_search_entry(NW_PATH *nwpath, int attrib, okflag = (name[0] != '.' && ( (entry[0] == '*' && entry[1] == '\0') || (!strcmp(name, entry)) - || str_match(name, entry, soptions))); + || fn_match(name, entry, soptions))); if (okflag) { *kpath = '\0'; strcpy(kpath, name); @@ -430,8 +428,8 @@ static int get_dir_entry(NW_PATH *nwpath, uint8 entry[256]; int volume = nwpath->volume; uint8 soptions; - if (volume < 0 || volume >= used_vols) return(0); /* something wrong */ - else soptions = vols[volume].options; + if (volume < 0 || volume >= used_nw_volumes) return(0); /* something wrong */ + else soptions = nw_volumes[volume].options; strcpy(entry, nwpath->fn); if (soptions & 1) downstr(entry); /* now downshift chars */ @@ -453,7 +451,7 @@ static int get_dir_entry(NW_PATH *nwpath, okflag = (name[0] != '.' && ( (entry[0] == '*' && entry[1] == '\0') || (!strcmp(name, entry)) - || str_match(name, entry, soptions))); + || fn_match(name, entry, soptions))); if (okflag) { *kpath = '\0'; strcpy(kpath, name); @@ -506,7 +504,7 @@ static int get_dh_entry(DIR_HANDLE *dh, okflag = (name[0] != '.' && ( (!strcmp(name, entry)) || (entry[0] == '*' && entry[1] == '\0') - || str_match(name, entry, dh->vol_options))); + || fn_match(name, entry, dh->vol_options))); if (okflag) { strcpy(dh->kpath, name); @@ -600,9 +598,9 @@ static int build_path( NW_PATH *path, if (only_dir) path->fn[0] = '\0'; if (vol[0]) { /* there is a volume in path */ - int j = used_vols; + int j = used_nw_volumes; while (j--) { - if (!strcmp(vols[j].sysname, vol)) { + if (!strcmp(nw_volumes[j].sysname, vol)) { path->volume = j; break; } @@ -733,7 +731,7 @@ int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle, return(completition); } -static uint16 un_date_2_nw(time_t time, uint8 *d) +uint16 un_date_2_nw(time_t time, uint8 *d) { struct tm *s_tm=localtime(&time); uint16 xdate=s_tm->tm_year - 80; @@ -745,7 +743,7 @@ static uint16 un_date_2_nw(time_t time, uint8 *d) return(xdate); } -static time_t nw_2_un_time(uint8 *d, uint8 *t) +time_t nw_2_un_time(uint8 *d, uint8 *t) { uint16 xdate = GET_BE16(d); uint16 xtime = (t != (uint8*) NULL) ? GET_BE16(t) : 0; @@ -766,7 +764,7 @@ static time_t nw_2_un_time(uint8 *d, uint8 *t) return(mktime(&s_tm)); } -static uint16 un_time_2_nw(time_t time, uint8 *d) +uint16 un_time_2_nw(time_t time, uint8 *d) { struct tm *s_tm=localtime(&time); uint16 xdate=s_tm->tm_hour; @@ -831,7 +829,7 @@ int nw_creat_open_file(int dir_handle, uint8 *data, int len, { int fhandle=new_file_handle(); - if (fhandle){ + if (fhandle > 0){ FILE_HANDLE *fh=&(file_handles[fhandle-1]); NW_PATH nwpath; int completition = conn_get_kpl_path(&nwpath, dir_handle, data, len, 0); @@ -845,60 +843,76 @@ int nw_creat_open_file(int dir_handle, uint8 *data, int len, } } #endif - if (completition > -1) { struct stat stbuff; completition = -0xff; /* no File Found */ strcpy(fh->name, build_unix_name(&nwpath, 0)); - - if (creatmode) { /* creat File */ - if (creatmode & 0x2) { /* creatnew */ - if (!stat(fh->name, &stbuff)) { - XDPRINTF((5,0,"CREAT File exist!! :%s:", fh->name)); - fh->fd = -1; - completition = -0x85; /* No Priv */ + if (get_volume_options(nwpath.volume, 1) & VOL_OPTION_IS_PIPE) { + /* this is a PIPE Dir */ + int statr = stat(fh->name, &stbuff); + if (!statr && (stbuff.st_mode & S_IFMT) != S_IFDIR) { + char pipecommand[300]; + char *pipeopen = (creatmode || (access & 2)) ? "w" : "r"; + char *topipe = "READ"; + if (creatmode) topipe = "CREAT"; + else if (access & 2) topipe = "WRITE"; + sprintf(pipecommand, "%s %s", fh->name, topipe); + fh->f = popen(pipecommand, pipeopen); + fh->fd = (fh->f) ? fileno(fh->f) : -1; + if (fh->fd > -1) { + fh->flags |= 2; + get_file_attrib(info, &stbuff, &nwpath); + return(fhandle); + } + } + } else { + if (creatmode) { /* creat File */ + if (creatmode & 0x2) { /* creatnew */ + if (!stat(fh->name, &stbuff)) { + XDPRINTF((5,0,"CREAT File exist!! :%s:", fh->name)); + fh->fd = -1; + completition = -0x85; /* No Priv */ + } else { + XDPRINTF((5,0,"CREAT FILE:%s: Handle=%d", fh->name, fhandle)); + fh->fd = creat(fh->name, 0777); + if (fh->fd < 0) completition = -0x84; /* no create Rights */ + } } else { - XDPRINTF((5,0,"CREAT FILE:%s: Handle=%d", fh->name, fhandle)); - fh->fd = creat(fh->name, 0777); - if (fh->fd < 0) completition = -0x84; /* no create Rights */ + XDPRINTF((5,0,"CREAT FILE, ever with attrib:0x%x, access:0x%x, fh->name:%s: handle:%d", + attrib, access, fh->name, fhandle)); + fh->fd = open(fh->name, O_CREAT|O_TRUNC|O_RDWR, 0777); + if (fh->fd < 0) completition = -0x85; /* no delete /create Rights */ + } + if (fh->fd > -1) { + close(fh->fd); + fh->fd = open(fh->name, O_RDWR); + fh->offd = 0L; + stat(fh->name, &stbuff); } } else { - XDPRINTF((5,0,"CREAT FILE, ever with attrib:0x%x, access:0x%x, fh->name:%s: handle:%d", - attrib, access, fh->name, fhandle)); - fh->fd = open(fh->name, O_CREAT|O_TRUNC|O_RDWR, 0777); - if (fh->fd < 0) completition = -0x85; /* no delete /create Rights */ + int statr = stat(fh->name, &stbuff); + int acm = (access & 2) ? (int) O_RDWR /*|O_CREAT*/ : (int)O_RDONLY; + if ( (!statr && (stbuff.st_mode & S_IFMT) != S_IFDIR) + || (statr && (acm & O_CREAT))){ + XDPRINTF((5,0,"OPEN FILE with attrib:0x%x, access:0x%x, fh->name:%s: fhandle=%d",attrib,access, fh->name, fhandle)); + fh->fd = open(fh->name, acm, 0777); + fh->offd = 0L; + if (fh->fd > -1) { + if (statr) stat(fh->name, &stbuff); + } else completition = -0x9a; + } + } if (fh->fd > -1) { - close(fh->fd); - fh->fd = open(fh->name, O_RDWR); - fh->offd = 0L; - stat(fh->name, &stbuff); - } - } else { - int statr = stat(fh->name, &stbuff); - int acm = (access & 2) ? (int) O_RDWR /*|O_CREAT*/ : (int)O_RDONLY; - if ( (!statr && (stbuff.st_mode & S_IFMT) != S_IFDIR) - || (statr && (acm & O_CREAT))){ - XDPRINTF((5,0,"OPEN FILE with attrib:0x%x, access:0x%x, fh->name:%s: fhandle=%d",attrib,access, fh->name, fhandle)); - fh->fd = open(fh->name, acm, 0777); - fh->offd = 0L; - if (fh->fd > -1) { - if (statr) stat(fh->name, &stbuff); - } else completition = -0x9a; - } - - } - - if (fh->fd > -1) { - get_file_attrib(info, &stbuff, &nwpath); + get_file_attrib(info, &stbuff, &nwpath); #ifdef TEST_FNAME - if (got_testfn) test_handle = fhandle; + if (got_testfn) test_handle = fhandle; #endif - return(fhandle); - } + return(fhandle); + } + } /* else (NOT DEVICE) */ } - XDPRINTF((5,0,"OPEN FILE not OK ! fh->name:%s: fhandle=%d",fh->name, fhandle)); free_file_handle(fhandle); #ifdef TEST_FNAME @@ -916,6 +930,8 @@ static int do_delete_file(NW_PATH *nwpath, FUNC_SEARCH *fs) char unname[256]; strcpy(unname, build_unix_name(nwpath, 0)); XDPRINTF((5,0,"DELETE FILE unname:%s:", unname)); + if (get_volume_options(nwpath->volume, 1) & VOL_OPTION_IS_PIPE) + return(0); /* don't delete 'pipe commands' */ if (!unlink(unname)) return(0); return(-0x8a); /* NO Delete Privileges */ } @@ -956,12 +972,21 @@ int nw_close_datei(int fhandle) if (fhandle > 0 && (fhandle <= anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle-1]); if (fh->fd > -1) { - close(fh->fd); + int result = 0; + int result2; + if (fh->flags & 2) { + if (fh->f) { + result=pclose(fh->f); + if (result) result = -1; + } + fh->f = NULL; + } else result=close(fh->fd); fh->fd = -1; - if (fh->tmodi > 0L) { + if (fh->tmodi > 0L && !(fh->flags&2)) { struct utimbuf ut; ut.actime = ut.modtime = fh->tmodi; utime(fh->name, &ut); + fh->tmodi = 0L; } #ifdef TEST_FNAME if (fhandle == test_handle) { @@ -969,8 +994,9 @@ int nw_close_datei(int fhandle) nw_debug = -99; } #endif - return(free_file_handle(fhandle)); - } + result2=free_file_handle(fhandle); + return((result == -1) ? -0xff : result2); + } else return(free_file_handle(fhandle)); } return(-0x88); /* wrong filehandle */ } @@ -1149,6 +1175,13 @@ int mv_file(int qdirhandle, uint8 *q, int qlen, int completition=conn_get_kpl_path(&quellpath, qdirhandle, q, qlen, 0); if (!completition > -1){ completition=conn_get_kpl_path(&zielpath, zdirhandle, z, zlen, 0); + if (completition > -1) { + if (get_volume_options(quellpath.volume, 1) & + VOL_OPTION_IS_PIPE || + get_volume_options(zielpath.volume, 1) & + VOL_OPTION_IS_PIPE) + completition = -0x9c; + } if (completition > -1){ char unquelle[256]; char unziel[256]; @@ -1203,10 +1236,11 @@ int nw_init_connect(void) uint8 *login = (uint8*) "LOGIN/"; NW_PATH nwlogin; FILE *f= open_nw_ini(); + if (f != (FILE*) NULL){ uint8 buff[256]; struct stat stbuff; - int what; + int what; int k = MAX_NW_DIRS; NW_DIR *d = &(dirs[0]); strcpy(nwlogin.path, login); @@ -1222,58 +1256,31 @@ int nw_init_connect(void) d->drive = 0; d++; } - if (!connect_is_init) { - k = -1; - connect_is_init++; - while (++k < MAX_NW_VOLS) { - vols[k].unixname = NULL; - vols[k].sysname = NULL; - vols[k].options = 0; - } - } else { + + if (connect_is_init) { k = 0; while (k++ < anz_fhandles) free_file_handle(k); k = 0; while (k++ < anz_dirhandles) free_dir_handle(k); - } - used_vols = 0; + } else connect_is_init++; + while (0 != (what = get_ini_entry(f, 0, (char*)buff, sizeof(buff)))) { - if ( what == 1 && used_vols < MAX_NW_VOLS && strlen(buff) > 3){ - uint8 sysname[256]; - uint8 unixname[256]; - char optionstr[256]; - char *p; - int len; - int founds = sscanf((char*)buff, "%s %s %s",sysname, unixname, optionstr); - if (founds > 1) { - new_str(vols[used_vols].sysname, sysname); - len = strlen(unixname); - if (unixname[len-1] != '/') { - unixname[len++] = '/'; - unixname[len] = '\0'; - } - vols[used_vols].options = 0; - new_str(vols[used_vols].unixname, unixname); - if (founds > 2) { - for (p=optionstr; *p; p++) { - switch (*p) { - case 'k' : vols[used_vols].options |= 1; - default : break; - } - } - } - used_vols++; - } - } else if (what == 10) { /* GID */ + if (what == 10) { /* GID */ default_gid = atoi(buff); } else if (what == 11) { /* UID */ default_uid = atoi(buff); } else if (what == 103) { /* Debug */ nw_debug = atoi(buff); } - } + } /* while */ + nw_init_volumes(f); fclose(f); + if (used_nw_volumes < 1) { + errorp(0, "No Volumes defined. Look at ini file entry 1, Abort !!", NULL); + return(-1); + } + if (stat(build_unix_name(&nwlogin, 0), &stbuff)) { errorp(0, "Stat error LOGIN Directory, Abort !!", "UnixPath=`%s`", build_unix_name(&nwlogin, 0)); @@ -1500,8 +1507,8 @@ int nw_get_directory_path(int dir_handle, uint8 *name) name[0] = '\0'; if (dir_handle > 0 && --dir_handle < (int)used_dirs) { int volume = dirs[dir_handle].volume; - if (volume > -1 && volume < used_vols){ - result=sprintf((char*)name, "%s:%s", vols[volume].sysname, dirs[dir_handle].path); + if (volume > -1 && volume < used_nw_volumes){ + result=sprintf((char*)name, "%s:%s", nw_volumes[volume].sysname, dirs[dir_handle].path); if (name[result-1] == '/') name[--result] = '\0'; } else result = -0x98; } @@ -1515,54 +1522,12 @@ int nw_get_vol_number(int dir_handle) int result = -0x9b; /* wrong handle */ if (dir_handle > 0 && --dir_handle < (int)used_dirs) { result = dirs[dir_handle].volume; - if (result < 0 || result >= used_vols) result = -0x98; /* wrong volume */ + if (result < 0 || result >= used_nw_volumes) result = -0x98; /* wrong volume */ } XDPRINTF((5,0,"nw_get_vol_number:0x%x: von Handle=%d", result, dir_handle+1)); return(result); } -int nw_get_volume_number(uint8 *volname, int namelen) -/* Get Volume Number with name */ -/* returns Volume Nummer or if error < 0 */ -{ - int result = -0x98; /* Volume not exist */ - uint8 vname[255]; - int j = used_vols; - strmaxcpy((char*)vname, (char*)volname, namelen); - upstr(vname); - while (j--) { - if (!strcmp(vols[j].sysname, vname)) { - result = j; - break; - } - } - XDPRINTF((5,0,"GET_VOLUME_NUMBER of:%s: result = 0x%x", vname, result)); - return(result); -} - -int nw_get_volume_name(int volnr, uint8 *volname) -/* returns < 0 if error, else len of volname */ -{ - int result = -0x98; /* Volume not exist */; - if (volnr < used_vols) { - if (volname != NULL) { - strcpy(volname, vols[volnr].sysname); - result = strlen(volname); - } else result= strlen(vols[volnr].sysname); - } else { - if (NULL != volname) *volname = '\0'; - if (volnr < MAX_NW_VOLS) result=0; - } - if (nw_debug > 4) { - char xvolname[10]; - if (!volname) { - volname = xvolname; - *volname = '\0'; - } - XDPRINTF((5,0,"GET_VOLUME_NAME von:%d = %s: ,result=0x%x", volnr, volname, result)); - } - return(result); -} int nw_get_eff_dir_rights(int dir_handle, uint8 *data, int len, int modus) /* modus 0=only_dir, 1=dirs and files */ @@ -1676,23 +1641,6 @@ int nw_scan_dir_info(int dir_handle, uint8 *data, int len, uint8 *subnr, subname, subdatetime, owner, dirname)); } -int nw_get_fs_usage(char *volname, struct fs_usage *fsu) -/* returns 0 if OK, else errocode < 0 */ -{ - int volnr = nw_get_volume_number(volname, strlen(volname)); - return((volnr>-1 && !get_fs_usage(vols[volnr].unixname, fsu)) ? 0 : -1); -} - -int nw_get_vol_info(int volnr) -/* returns >= 0 if OK, else errocode < 0 */ -{ - int result = -0x98; /* Volume not exist */; - if (volnr > -1 && volnr < used_vols) { - result =0; - } - XDPRINTF((5,0,"NW_GET_VOL_INFO von VOLNR:%d, result=0x%x", volnr, result)); - return(result); -} typedef struct { uint8 time[2]; @@ -1718,13 +1666,13 @@ typedef struct { uint8 reserved_2[28]; } NW_DOS_FILE_INFO; -static void xun_date_2_nw(time_t time, uint8 *d) +void xun_date_2_nw(time_t time, uint8 *d) { uint16 i = un_date_2_nw(time, NULL); memcpy(d, &i, 2); } -static void xun_time_2_nw(time_t time, uint8 *d) +void xun_time_2_nw(time_t time, uint8 *d) { uint16 i = un_time_2_nw(time, NULL); memcpy(d, &i, 2); @@ -1845,11 +1793,6 @@ int nw_scan_a_root_dir(uint8 *rdata, } else return(completition); /* wrong path */ } - - - - - /* <======================================================================> */ /* minimal queue handling to enable very simple printing */ /* qick and dirty !!!!!!!!!!!!!!! */ @@ -1859,7 +1802,7 @@ static int anz_jobs=0; typedef struct { uint32 fhandle; - int old_job; /* is old structure */ + int old_job; /* is old structure */ union { QUEUE_JOB n; QUEUE_JOB_OLD o; @@ -1901,8 +1844,12 @@ static void free_queue_job(int q_id) { if (q_id > 0 && q_id <= anz_jobs) { INT_QUEUE_JOB **pp=&(queue_jobs[q_id-1]); - uint32 fhandle = (*pp)->fhandle; - if (fhandle > 0) nw_close_datei(fhandle); + uint32 fhandle = (*pp)->fhandle; + if (fhandle > 0) { + FILE_HANDLE *fh=&(file_handles[fhandle-1]); + fh->flags &= (~4); + nw_close_datei(fhandle); + } if (q_id == anz_jobs) { xfree(*pp); --anz_jobs; @@ -1944,6 +1891,11 @@ static int create_queue_file(char *job_file_name, (int) *job_file_name, &fnfo, 0x6, 0x6, 1); + if (result > 0){ + FILE_HANDLE *fh=&(file_handles[result-1]); + fh->flags = 4; /* don't reuse after close */ + } + XDPRINTF((5,0,"creat queue file bez=`%s` handle=%d", job_bez, result)); return(result); @@ -1979,7 +1931,7 @@ int nw_creat_queue(int connection, uint8 *queue_id, uint8 *queue_job, jo->q.o.job_bez); if (result > -1) { - jo->fhandle = (uint32) result; + jo->fhandle = (uint32) result; U32_TO_BE32(jo->fhandle, jo->q.o.job_file_handle); U16_TO_BE16(0, jo->q.o.job_file_handle+4); result = 0; @@ -2049,6 +2001,7 @@ int nw_close_file_queue(uint8 *queue_id, FILE *f=NULL; strmaxcpy(unixname, fh->name, sizeof(unixname)-1); strmaxcpy(printcommand, prc, prc_len); + fh->flags &= (~4); nw_close_datei(fhandle); jo->fhandle = 0L; if (NULL != (f = fopen(unixname, "r"))) { @@ -2059,12 +2012,14 @@ 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, fout)) is_ok=0; + if (1 != fwrite(buff, k, 1, fout)) { + XDPRINTF((1,0,"Cannot write to pipe `%s`", printcommand)); + is_ok=0; + } } pclose(fout); } else - XDPRINTF((1,0,"Cannot open pipe `%s`", "lpr")); - + XDPRINTF((1,0,"Cannot open pipe `%s`", printcommand)); fclose(f); if (is_ok) { unlink(unixname); @@ -2072,7 +2027,7 @@ int nw_close_file_queue(uint8 *queue_id, } } else XDPRINTF((1,0,"Cannot open queue-file `%s`", unixname)); } else - XDPRINTF((2,0,"nw_close_file_queue fhandle=%d", fhandle)); + XDPRINTF((2,0,"fhandle=%d NOT OK anz_fhandles=%d", fhandle, anz_fhandles)); free_queue_job(jo_id); } return(result); diff --git a/connect.h b/connect.h index 224a82d..4362bcb 100644 --- a/connect.h +++ b/connect.h @@ -1,9 +1,12 @@ -/* connect.h 08-Jan-96 */ +/* connect.h 21-Jan-96 */ typedef struct { int fd; /* von System bei Open bzw. Create */ long offd; /* aktueller File Offset */ time_t tmodi; /* modification TIME */ + FILE *f; /* for PIPE */ + int flags; /* 2 = PIPE */ + /* 4 = don't reuse after close */ char name[256]; /* UNIX Dateiname */ } FILE_HANDLE; @@ -17,12 +20,6 @@ typedef struct { uint8 volume; /* Volume Number */ } DIR_HANDLE; -typedef struct { - uint8 *sysname; /* VOL_NAME */ - uint8 *unixname; /* UNIX-Verzeichnis */ - uint8 options; /* *_1_* alles in Kleinbuchstaben */ -} NW_VOL; - typedef struct { uint8 path[256]; /* directory */ uint8 fn[256]; /* file */ @@ -40,11 +37,14 @@ typedef struct { uint8 task; /* actual task */ } NW_DIR; +#define MAX_NW_DIRS 255 +extern NW_DIR dirs[MAX_NW_DIRS]; +extern int used_dirs; + + extern int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle, uint8 *data, int len, int only_dir) ; -extern char *conn_get_nwpath_name(NW_PATH *p); - extern void set_default_guid(void); extern void set_guid(int gid, int uid); @@ -60,6 +60,8 @@ extern int nw_scan_a_root_dir(uint8 *rdata, int dirhandle); +extern int fn_match(uint8 *s, uint8 *p, uint8 options); + /* queues */ extern int nw_creat_queue(int connection, uint8 *queue_id, uint8 *queue_job, @@ -69,3 +71,13 @@ extern int nw_close_file_queue(uint8 *queue_id, uint8 *job_id, uint8 *prc, int prc_len); + + +extern uint16 un_date_2_nw(time_t time, uint8 *d); +extern time_t nw_2_un_time(uint8 *d, uint8 *t); +extern uint16 un_time_2_nw(time_t time, uint8 *d); + +extern void xun_date_2_nw(time_t time, uint8 *d); +extern void xun_time_2_nw(time_t time, uint8 *d); + + diff --git a/emutli.c b/emutli.c index c9e04e8..760c152 100644 --- a/emutli.c +++ b/emutli.c @@ -1,4 +1,4 @@ -/* emutli.c 08-Jan-96 */ +/* emutli.c 22-Jan-96 */ /* * One short try to emulate TLI with SOCKETS. */ @@ -457,21 +457,71 @@ int t_rcvudata(int fd, struct t_unitdata *ud, int *flags) ud->addr.len = sizeof(ipxAddr_t); return(result); } +#define HAVE_IPX_SEND_BUG 0 +#if HAVE_IPX_SEND_BUG +static int last_fd; +static int new_try; + +static void sig_alarm(int rsig) +{ + struct sockaddr_ipx ipxs; + int maxplen=sizeof(struct sockaddr_ipx); + signal(rsig, SIG_IGN); + XDPRINTF((1, 0, "GOT ALARM SIGNAL in sendto")); + memset((char*)&ipxs, 0, sizeof(struct sockaddr_ipx)); + ipxs.sipx_family=AF_IPX; + if (getsockname(last_fd, (struct sockaddr*)&ipxs, &maxplen) != -1){ + int sock; + int i = 5; + while (close(last_fd) == -1 && i--) sleep(1); + sleep(2); + sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX); + if (bind(sock, (struct sockaddr*)&ipxs, sizeof(struct sockaddr_ipx))==-1) { + errorp(0, "TLI-BIND", "socket Nr:0x%x", (int)GET_BE16(&(ipxs.sipx_port))); + exit(1); + } + if (sock != last_fd) { + dup2(sock, last_fd); + close(sock); + } + new_try++; + } else + errorp(0, "getsockname", NULL); +} +#endif int t_sndudata(int fd, struct t_unitdata *ud) { int result; struct sockaddr_ipx ipxs; + if (ud->addr.len != sizeof(ipxAddr_t)) return(-1); + +#if HAVE_IPX_SEND_BUG + { + int anz_tries=3; + do { + void (*old_sig)(int rsig) = signal(SIGALRM, sig_alarm); + new_try = 0; + alarm(2); + last_fd = fd; +#endif + memset(&ipxs, 0, sizeof(struct sockaddr_ipx)); ipxs.sipx_family=AF_IPX; - - if (ud->addr.len != sizeof(ipxAddr_t)) return(-1); ipx2sockadr(&ipxs, (ipxAddr_t*) (ud->addr.buf)); ipxs.sipx_type = (ud->opt.len) ? (uint8) *((uint8*)(ud->opt.buf)) : 0; result = sendto(fd,(void *)ud->udata.buf, ud->udata.len, 0, (struct sockaddr *) &ipxs, sizeof(ipxs)); + +#if HAVE_IPX_SEND_BUG + alarm(0); + signal(SIGALRM, old_sig); + } while (new_try && anz_tries--); + } +#endif + return(result); } diff --git a/examples/README.patch b/examples/README.patch new file mode 100644 index 0000000..5db3794 --- /dev/null +++ b/examples/README.patch @@ -0,0 +1,27 @@ +this kernelpatch for kernels 1.3.56,57,58, ?? makes 3 things. + +- removes the ipx-send bug. BIG THANKS to Volker Lendecke. + the problem was that sometimes the sendto function hung. + +- ipx rip/sap packets comming from internal net must change + there source address from internal net/node to the + device net/node. + The problem was: + By configuring mars_nwe at the internal network, the rip/sap + socket gets the network and node address of the internal + net. Then, by sending rip/sap packets over this socket to the + several devices the rip/sap packets don't have the device net/node, + but the internal net/node. + +- an existing route should never be overwritten by an route + over the internal net. + The problem was: + By running dosemu at the same workstation as mars_nwe the + dosemu automaticly changes the route to a nearby server + to route over the internal network and this destroyed + the real route over a device to this server. + +You must be supervisor and then you must start './patchme' . + + + Martin Stover diff --git a/examples/config.h b/examples/config.h index 2390cb2..e298b8a 100644 --- a/examples/config.h +++ b/examples/config.h @@ -1,4 +1,4 @@ -/* config.h: 14-Jan-96 */ +/* config.h: 22-Jan-96 */ /* some of this config is needed by make, others by cc */ #define FILENAME_NW_INI "/etc/nwserv.conf" /* full name of ini (conf) file */ #define PATHNAME_PROGS "/sbin" /* path location of progs */ @@ -9,8 +9,8 @@ #define MAX_NW_VOLS 10 /* max. Volumes */ -#define MAX_NET_DEVICES 1 /* max. Netdevices, frames */ -#define IPX_DATA_GR_546 1 /* allow ipx packets > 546+30 Byte */ +#define MAX_NET_DEVICES 5 /* max. Netdevices, frames */ +#define IPX_DATA_GR_546 1 /* allow ipx packets > 546+30 Byte */ #define MAX_NW_ROUTES 50 /* max. networks (internal + external) */ #define MAX_NW_SERVERS 40 /* max. count of servers */ diff --git a/examples/kpatch1.3.56 b/examples/kpatch1.3.56 index 5c01fd2..f71bff3 100644 --- a/examples/kpatch1.3.56 +++ b/examples/kpatch1.3.56 @@ -1,6 +1,30 @@ ---- ORG/af_ipx.c Sat Jan 6 13:54:59 1996 -+++ af_ipx.c Thu Jan 11 14:36:21 1996 -@@ -994,7 +994,9 @@ +--- af_ipx.c Sat Jan 6 13:54:59 1996 ++++ af_ipx.c Sun Jan 21 20:36:36 1996 +@@ -507,8 +507,10 @@ + /* + * Don't charge sender + */ +- if(skb->sk) ++ if(skb->sk) { + skb->sk->wmem_alloc-=skb->truesize; ++ skb->sk = NULL; ++ } + /* + * Will charge receiver + */ +@@ -519,8 +521,10 @@ + */ + if (memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0) + { +- if (!send_to_wire && skb->sk) ++ if (!send_to_wire && skb->sk) { + skb->sk->wmem_alloc-=skb->truesize; ++ skb->sk = NULL; ++ } + ipxitf_demux_socket(intrfc, skb, send_to_wire); + if (!send_to_wire) + return 0; +@@ -994,7 +998,9 @@ return -EAGAIN; rt->ir_next=ipx_routes; ipx_routes=rt; @@ -11,7 +35,7 @@ rt->ir_net = network; rt->ir_intrfc = intrfc; -@@ -1108,9 +1110,15 @@ +@@ -1108,9 +1114,15 @@ ipx->ipx_tctrl=0; ipx->ipx_type=usipx->sipx_type; skb->h.raw = (unsigned char *)ipx; diff --git a/examples/nw.ini b/examples/nw.ini index 4cf3502..a651669 100644 --- a/examples/nw.ini +++ b/examples/nw.ini @@ -1,12 +1,12 @@ # (C)opyright 1993, 1995, Martin Stover, Softwareentwicklung, Marburg -# last change: 14-Jan-96 +# last change: 22-Jan-96 # MAR.S NW-Server Emulator # Einfache Konfiguration, alles ab # ist Kommentar. # Jeder Eintrag beginnt mit einer Zahl und dann folgt der Inhalt. # simple configuration, all after # is ignored. # every entry begins with a number and then the meet follows. # entry 1 VOLUMES (max. 5) entry 1 -# Volumename Volumepath Options (k=lowercase) +# Volumename Volumepath Options (k=lowercase,p=pipe) 1 SYS /u3/SYS/ # SYS 1 #################################### # Die folgenden Volumes sind optional. @@ -14,6 +14,7 @@ #1 SYS1 /u3/SYS1/ # SYS 2 upshift #1 TMP /tmp/ k # TMP downshift #1 CD /cdrom k # CDROM downshift +#1 PIPES /u3/pipes kp # pipecommands # Falls lowercase nicht gesetzt ist, werden GROSSBUCHSTABEN erwartet. # If lowercase is not set then all filenames are upshift. # SYS, der Name darf auch anders lauten, muss @@ -28,19 +29,20 @@ # will be taken. #2 MAR1 # Servername ###################################### -# next entry for later use, not yet supported !! -# the ipx kernel code must changed first, to do good routing !! -# If you have mars_nwe V > 0.96pl4 and the small ipx-kpatch -# you can use Internal Net and Routing. +# next entry for configure mars_nwe to use the internal net +# If you have mars_nwe V > 0.96pl5 and the small ipx-kpatch +# from the examples dir you can use Internal Net and Routing. # INTERNAL NET [NODE] ###3 0x999999 1 # Node default 1 ###################################### # entry 4: # for DEVICE(S) # if your ipx is allready up, then entry 4 must be removed. # NETWORK NUMBER, DEVICE, Frame-Typ TICS (default 1) -4 0x10 eth0 802.3 1 +4 0x10 eth0 802.3 1 +#4 0x22 eth0 ethernet_ii 1 +#4 0x33 eth0 802.2 1 +#4 0x55 isdn2 ethernet_ii 7 # Frames=ethernet_ii, 802.2, 802.3, SNAP (default 802.3) -# testet with 802.3 5 0 # don't = 0, do = 1, save ipx-routes after server is down. ###################################### # some clients are running better, if the server tells diff --git a/examples/patchme b/examples/patchme new file mode 100755 index 0000000..3dd6677 --- /dev/null +++ b/examples/patchme @@ -0,0 +1,19 @@ +#!/bin/sh +ACT_DIR=`pwd` +PATCHFILE=kpatch1.3.56 +LINUXDIR=/usr/src/linux +IPXDIR=$LINUXDIR/net/ipx +IPXFILE=af_ipx.c + +if [ -r $IPXDIR/$IPXFILE ] ; then + if [ -r $IPXDIR/P1 ] ; then + echo "patch was allready made: $IPXDIR/P1 exist" + else + cd $IPXDIR && cp -a $IPXFILE $IPXFILE.org && \ + patch < $ACT_DIR/$PATCHFILE && echo "$PATCHFILE" > $IPXDIR/P1 + echo "please rebuild the kernel" + fi +else + echo "linuxdir $LINUXDIR perhaps wrong ?" +fi + diff --git a/makefile.unx b/makefile.unx index 3c0186a..3ad14e6 100644 --- a/makefile.unx +++ b/makefile.unx @@ -1,4 +1,4 @@ -# makefile.unx 12-Jan-96 +# makefile.unx 15-Jan-96 VPATH=.. O=.o C=.c @@ -6,7 +6,7 @@ C=.c DEBUG=-DDB V_H=0 V_L=96 -P_L=6 +P_L=7 #define D_P_L 1 DISTRIB=mars_nwe #if D_P_L @@ -71,7 +71,6 @@ NSLLIB=-lnsl PROGS=$(PROG1) $(PROG2) $(PROG3) $(PROG4) $(PROG5) - #include "config.h" #ifdef FILENAME_NW_INI M_FILENAME_NW_INI=FILENAME_NW_INI @@ -87,11 +86,12 @@ M_PATHNAME_PROGS="." OBJ1= $(EMUTLIOBJ) net1$(O) tools$(O) OBJ2= $(OBJ1) nwroute$(O) -OBJ3= $(OBJ1) connect$(O) namspace$(O) +OBJ3= $(OBJ1) connect$(O) namspace$(O) nwvolume$(O) OBJ4= $(OBJ1) nwdbm$(O) nwcrypt$(O) OBJ5= $(OBJ1) -OBJS= net1$(O) tools$(O) connect$(O) nwdbm$(O) \ +OBJS= net1$(O) tools$(O) connect$(O) nwdbm$(O) nwroute$(O) \ + namspace$(O) nwvolume$(O) \ $(PROG2)$(O) $(PROG3)$(O) $(PROG4)$(O) $(PROG5)$(O) HOBJ3= $(PROG3)$(O) connect$(O) namspace$(O) @@ -113,10 +113,8 @@ $(PROG4): $(PROG4)$(O) $(OBJ4) $(PROG5): $(PROG5)$(O) $(OBJ5) $(CC) -o ../$(PROG5) $(PROG5)$(O) $(OBJ5) $(NSLLIB) -$(PROG3)$(O): namspace.h connect.h -connect$(O): namspace.h connect.h -namspace$(O): namspace.h connect.h -$(OBJS): net.h config.h +$(HOBJ3): namspace.h connect.h nwvolume.h +$(OBJS): net.h config.h $(C)$(O): $(CC) -c $(CFLAGS) $(HOSTCFLAGS) $(DEBUG)\ diff --git a/mars_nwe.lsm b/mars_nwe.lsm index 01f019e..e3b8a23 100644 --- a/mars_nwe.lsm +++ b/mars_nwe.lsm @@ -1,7 +1,7 @@ Begin3 Title: mars_nwe -Version: 0.96pl6 -Entered-date: 14-Jan-96 +Version: 0.96pl7 +Entered-date: 22-Jan-96 Description: full novell-server-emulator (src),beta file-services, bindery-services, printing-services needs no kernelchanges, usefull for testing ipx @@ -9,7 +9,7 @@ Keywords: novell, netware, server, ipx, ncp, tli Author: mstover@freeway.de (Martin Stover) Maintained-by: mstover@freeway.de (Martin Stover) Primary-site: linux01.gwdg.de /pub/ncpfs - 100kB mars_nwe-0.96.pl4.tgz + 120kB mars_nwe-0.96.pl7.tgz Alternate-site: ftp.uni-duisburg.de /pub/linux/ipxware Platforms: Linux (1.2.xx, 1.3.32, 1.3.55 tested, others should work) Copying-policy: GNU diff --git a/ncpserv.c b/ncpserv.c index ef5354a..8305b71 100644 --- a/ncpserv.c +++ b/ncpserv.c @@ -1,5 +1,5 @@ /* ncpserv.c */ -#define REVISION_DATE "14-Jan-96" +#define REVISION_DATE "22-Jan-96" /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify diff --git a/net.h b/net.h index 2e17103..32189b5 100644 --- a/net.h +++ b/net.h @@ -1,4 +1,4 @@ -/* net.h 08-Jan-96 */ +/* net.h 22-Jan-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * @@ -58,28 +58,36 @@ #endif #define U16_TO_BE16(u, b) { uint16 a=(u); \ - *( (uint8*) (b) ) = *( ((uint8*) (&a)) +1); \ - *( ((uint8*) (b)) +1) = *( (uint8*) (&a)); } + *( (uint8*) (b) ) = *( ((uint8*) (&a)) +1); \ + *( ((uint8*) (b)) +1) = *( (uint8*) (&a)); } #define U32_TO_BE32(u, ar) { uint32 a= (u); uint8 *b= ((uint8*)(ar))+3; \ - *b-- = (uint8)a; a >>= 8; \ - *b-- = (uint8)a; a >>= 8; \ - *b-- = (uint8)a; a >>= 8; \ - *b = (uint8)a; } + *b-- = (uint8)a; a >>= 8; \ + *b-- = (uint8)a; a >>= 8; \ + *b-- = (uint8)a; a >>= 8; \ + *b = (uint8)a; } #define U16_TO_16(u, b) { uint16 a=(u); memcpy(b, &a, 2); } #define U32_TO_32(u, b) { uint32 a=(u); memcpy(b, &a, 4); } #define GET_BE16(b) ( (int) *(((uint8*)(b))+1) \ - | ( ( (int) *( (uint8*)(b) ) << 8) ) ) + | ( ( (int) *( (uint8*)(b) ) << 8) ) ) #define GET_BE32(b) ( (uint32) *(((uint8*)(b))+3) \ - | ( ((uint32) *(((uint8*)(b))+2)) << 8) \ - | ( ((uint32) *(((uint8*)(b))+1)) << 16) \ - | ( ((uint32) *( (uint8*)(b) ) << 24) ) ) + | ( ((uint32) *(((uint8*)(b))+2) ) << 8) \ + | ( ((uint32) *(((uint8*)(b))+1) ) << 16) \ + | ( ((uint32) *( (uint8*)(b) ) ) << 24) ) +#define GET_16(b) ( (int) *( (uint8*)(b) ) \ + | ( ( (int) *(((uint8*)(b))+1) << 8) ) ) + +#define GET_32(b) ( (uint32) *( (uint8*)(b) ) \ + | ( ((uint32) *(((uint8*)(b))+1) ) << 8) \ + | ( ((uint32) *(((uint8*)(b))+2) ) << 16) \ + | ( ((uint32) *(((uint8*)(b))+3) ) << 24) ) + #define MAX_U32 ((uint32)0xffffffffL) #define MAX_U16 ((uint16)0xffff) @@ -131,34 +139,34 @@ typedef union { struct S_SIP { /* Server Identification Packet, siehe auch SAP */ uint8 response_type[2]; /*hi-lo */ - /* 2 periodic bzw. Shutdown */ - /* bzw. General Service Response */ - /* 4 nearest Service Response */ + /* 2 periodic bzw. Shutdown */ + /* bzw. General Service Response */ + /* 4 nearest Service Response */ uint8 server_type[2]; /*hi-lo */ - /* 0x0 unknown */ - /* 0x1 user */ - /* 0x2 user/group */ - /* 0x3 Print Queue */ - /* 0x4 File Server */ - /* 0x5 Job Server */ - /* 0x6 Gateway */ - /* 0x7 Printserver */ - /* 0x9 Archive Server */ - /* 0x24 Remote Bridge Server */ - /* 0x47 Advertising Print Server */ - /* 0x107 Netware 386 */ - /* 0xFFFF (-1) WILD */ + /* 0x0 unknown */ + /* 0x1 user */ + /* 0x2 user/group */ + /* 0x3 Print Queue */ + /* 0x4 File Server */ + /* 0x5 Job Server */ + /* 0x6 Gateway */ + /* 0x7 Printserver */ + /* 0x9 Archive Server */ + /* 0x24 Remote Bridge Server */ + /* 0x47 Advertising Print Server */ + /* 0x107 Netware 386 */ + /* 0xFFFF (-1) WILD */ uint8 server_name[MAX_SERVER_NAME]; ipxAddr_t server_adr; uint8 intermediate_networks[2]; /* hi-lo */ - /* normal 0 */ - /* down 16 */ + /* normal 0 */ + /* down 16 */ } sip; /* Server Identifikation Packet */ struct S_SQP { /* Service Query Packet */ uint8 query_type[2]; /* hi low */ - /* 1 general Service Query */ - /* 3 nearest Server Query */ + /* 1 general Service Query */ + /* 3 nearest Server Query */ uint8 server_type[2]; /* hi low s.o. */ } sqp; struct S_SAP { @@ -259,7 +267,7 @@ typedef struct S_NCPREQUEST NCPREQUEST; #define PACKT_ERROR 3 /* Error Packet */ #define PACKT_EXCH 4 /* Packet Exchange Packet */ #define PACKT_SPX 5 /* SPX Packet */ - /* 16 - 31 Experimental */ + /* 16 - 31 Experimental */ #define PACKT_CORE 17 /* Core Protokoll (NCP) */ @@ -302,7 +310,7 @@ typedef struct { uint8 target_id[4]; /* 0xff, 0xff, 0xff, 0xff */ uint8 target_execute_time[6]; /* all 0xff */ - uint8 job_entry_time[6]; /* all zero */ + uint8 job_entry_time[6]; /* all zero */ uint8 job_id[4]; /* ?? alles 0 HI-LOW */ uint8 job_typ[2]; /* z.B. Printform HI-LOW */ uint8 job_position[2]; /* ?? alles 0 low-high ? */ @@ -328,7 +336,7 @@ typedef struct { uint8 client_id[4]; uint8 target_id[4]; /* 0xff, 0xff, 0xff, 0xff */ uint8 target_execute_time[6]; /* all 0xff */ - uint8 job_entry_time[6]; /* all zero */ + uint8 job_entry_time[6]; /* all zero */ uint8 job_id[2]; /* ?? alles 0 HI-LOW */ uint8 job_typ[2]; /* z.B. Printform HI-LOW */ uint8 job_position; /* zero */ @@ -353,14 +361,14 @@ typedef struct { uint8 tabsize; /* normal 0x8 */ uint8 anz_copies[2]; /* copies 0x0, 0x01 */ uint8 print_flags[2]; /* 0x0, 0xc0 z.B. with banner */ - uint8 max_lines[2]; /* 0x0, 0x42 */ - uint8 max_chars[2]; /* 0x0, 0x84 */ - uint8 form_name[16]; /* "UNKNOWN" */ - uint8 reserved[6]; /* all zero */ - uint8 banner_user_name[13]; /* "SUPERVISOR" */ - uint8 bannner_file_name[13]; /* "LST:" */ + uint8 max_lines[2]; /* 0x0, 0x42 */ + uint8 max_chars[2]; /* 0x0, 0x84 */ + uint8 form_name[16]; /* "UNKNOWN" */ + uint8 reserved[6]; /* all zero */ + uint8 banner_user_name[13]; /* "SUPERVISOR" */ + uint8 bannner_file_name[13]; /* "LST:" */ uint8 bannner_header_file_name[14]; /* all zero */ - uint8 file_path_name[80]; /* all zero */ + uint8 file_path_name[80]; /* all zero */ } QUEUE_PRINT_AREA; @@ -368,7 +376,7 @@ extern int nw_init_connect(void); extern int nw_free_handles(int task); extern int nw_creat_open_file(int dir_handle, uint8 *data, int len, - NW_FILE_INFO *info, int attrib, int access, int mode); + NW_FILE_INFO *info, int attrib, int access, int mode); extern int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset); extern int nw_seek_datei(int fhandle, int modus); @@ -377,31 +385,31 @@ extern int nw_lock_datei(int fhandle, int offset, int size, int do_lock); extern int nw_close_datei(int fhandle); extern int nw_server_copy(int qfhandle, uint32 qoffset, - int zfhandle, uint32 zoffset, - uint32 size); + int zfhandle, uint32 zoffset, + uint32 size); extern int nw_delete_datei(int dir_handle, uint8 *data, int len); extern int nw_chmod_datei(int dir_handle, uint8 *data, int len, int modus); extern int mv_file(int qdirhandle, uint8 *q, int qlen, - int zdirhandle, uint8 *z, int zlen); + int zdirhandle, uint8 *z, int zlen); extern int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode); extern int nw_search(uint8 *info, - int dirhandle, int searchsequence, - int search_attrib, uint8 *data, int len); + int dirhandle, int searchsequence, + int search_attrib, uint8 *data, int len); extern int nw_dir_search(uint8 *info, - int dirhandle, int searchsequence, - int search_attrib, uint8 *data, int len); + int dirhandle, int searchsequence, + int search_attrib, uint8 *data, int len); extern int nw_find_dir_handle( int dir_handle, - uint8 *data, /* zus„tzlicher Pfad */ - int len); /* L„nge Pfad */ + uint8 *data, /* zus„tzlicher Pfad */ + int len); /* L„nge Pfad */ extern int nw_alloc_dir_handle( int dir_handle, /* Suche ab Pfad dirhandle */ @@ -414,8 +422,8 @@ extern int nw_alloc_dir_handle( extern int nw_open_dir_handle( int dir_handle, - uint8 *data, /* zus„tzlicher Pfad */ - int len, /* L„nge DATA */ + uint8 *data, /* zus„tzlicher Pfad */ + int len, /* L„nge DATA */ int *volume, /* Volume */ int *dir_id, /* „hnlich Filehandle */ int *searchsequence); @@ -424,26 +432,22 @@ extern int nw_open_dir_handle( int dir_handle, extern int nw_free_dir_handle(int dir_handle); extern int nw_set_dir_handle(int targetdir, int dir_handle, - uint8 *data, int len, int task); + uint8 *data, int len, int task); extern int nw_get_directory_path(int dir_handle, uint8 *name); extern int nw_get_vol_number(int dir_handle); -extern int nw_get_volume_number(uint8 *volname, int namelen); -extern int nw_get_volume_name(int volnr, uint8 *volname); - extern int nw_get_eff_dir_rights(int dir_handle, uint8 *data, int len, int modus); extern int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit); extern int nw_scan_dir_info(int dir_handle, uint8 *data, int len, - uint8 *subnr, uint8 *subname, - uint8 *subdatetime, uint8 *owner); + uint8 *subnr, uint8 *subname, + uint8 *subdatetime, uint8 *owner); #include "tools.h" -extern int nw_get_fs_usage(char *volname, struct fs_usage *fsu); #endif diff --git a/nwconn.c b/nwconn.c index 5e8032e..aaa79a2 100644 --- a/nwconn.c +++ b/nwconn.c @@ -20,6 +20,7 @@ #include "net.h" #include +#include "nwvolume.h" #include "connect.h" #include "namspace.h" @@ -1289,6 +1290,16 @@ static void sig_hup(int rsig) signal(SIGHUP, sig_hup); } +#if 0 +static void sig_child(int isig) +{ + int status; + int pid=wait(&status); + if (pid > -1) kill(pid, SIGKILL); /* evtl Toechter killen */ + signal(SIGCHLD, sig_child); +} +#endif + static void set_sig(void) { signal(SIGTERM, sig_quit); @@ -1296,6 +1307,7 @@ static void set_sig(void) signal(SIGHUP, sig_hup); signal(SIGINT, SIG_IGN); signal(SIGPIPE, SIG_IGN); + /* signal(SIGCHLD, sig_child); */ } int main(int argc, char **argv) diff --git a/nwvolume.c b/nwvolume.c new file mode 100644 index 0000000..b938d14 --- /dev/null +++ b/nwvolume.c @@ -0,0 +1,240 @@ +/* nwvolume.c 15-Jan-96 */ +/* (C)opyright (C) 1993,1995 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 +#include + +#include "nwvolume.h" + +NW_VOL nw_volumes[MAX_NW_VOLS]; +int used_nw_volumes=0; + +void nw_init_volumes(FILE *f) +/* f = inifile Pointer, must be opened !! */ +{ + static int volumes_is_init=0; + int what; + uint8 buff[256]; + int k = -1; + if (!volumes_is_init) { + volumes_is_init++; + while (++k < MAX_NW_VOLS) memset(&(nw_volumes[k]), 0, sizeof(NW_VOL)); + } else { + while (++k < MAX_NW_VOLS) { + int i = -1; + while (++i < nw_volumes[k].maps_count) + xfree(nw_volumes[k].dev_namespace_maps[i]); + nw_volumes[k].maps_count = 0; + } + } + rewind(f); + used_nw_volumes = 0; + while (0 != (what = get_ini_entry(f, 0, (char*)buff, sizeof(buff)))) { + if ( what == 1 && used_nw_volumes < MAX_NW_VOLS && strlen(buff) > 3){ + uint8 sysname[256]; + uint8 unixname[256]; + char optionstr[256]; + char *p; + int len; + int founds = sscanf((char*)buff, "%s %s %s",sysname, unixname, optionstr); + if (founds > 1) { + new_str(nw_volumes[used_nw_volumes].sysname, sysname); + len = strlen(unixname); + if (unixname[len-1] != '/') { + unixname[len++] = '/'; + unixname[len] = '\0'; + } + nw_volumes[used_nw_volumes].unixnamlen = len; + nw_volumes[used_nw_volumes].options = 0; + new_str(nw_volumes[used_nw_volumes].unixname, unixname); + if (founds > 2) { + for (p=optionstr; *p; p++) { + switch (*p) { + case 'k' : nw_volumes[used_nw_volumes].options + |= VOL_OPTION_DOWNSHIFT; break; + + case 'p' : nw_volumes[used_nw_volumes].options + |= VOL_OPTION_IS_PIPE; break; + + default : break; + } + } + } + used_nw_volumes++; + } + } + } /* while */ +} + + +static int look_name_space_map(int volume, DEV_NAMESPACE_MAP *dnm, + int do_insert) +{ + int result=-1; + if (volume > -1 && volume < used_nw_volumes) { + NW_VOL *v= &(nw_volumes[volume]); + DEV_NAMESPACE_MAP *mp; + int k=-1; + while (++k < v->maps_count) { + mp=v->dev_namespace_maps[k]; + if (mp->dev == dnm->dev && mp->namespace == dnm->namespace) + return(k); + } + if (do_insert && v->maps_count < MAX_DEV_NAMESPACE_MAPS) { + /* now do insert the new map */ + mp = v->dev_namespace_maps[v->maps_count++] = + (DEV_NAMESPACE_MAP*) xmalloc(sizeof(DEV_NAMESPACE_MAP)); + memcpy(mp, dnm, sizeof(DEV_NAMESPACE_MAP)); + return(k); + } + } + return(result); +} + +uint32 nw_vol_inode_to_handle(int volume, ino_t inode, + DEV_NAMESPACE_MAP *dnm) +{ + if (inode > 0 && inode < 0x1000000) { + int result = look_name_space_map(volume, dnm, 1); + if (result > -1) { + uint32 handle = (((uint32)result) << 28) | (uint32) inode; + XDPRINTF((3,0, "Handle map inode=%d, dev=%d, namespace=%d to handle 0x%x", + inode, dnm->dev, dnm->namespace, handle)); + return(handle); + } + } + XDPRINTF((1,0, "Cannot map inode=%d, dev=%d, namespace=%d to handle", + inode, dnm->dev, dnm->namespace)); + return(0L); +} + +ino_t nw_vol_handle_to_inode(int volume, uint32 handle, + DEV_NAMESPACE_MAP *dnm) +/* converts volume, handle to dev->inode->namespace */ +{ + if (handle > 0 && volume > -1 && volume < used_nw_volumes) { + NW_VOL *v= &(nw_volumes[volume]); + int entry = (int) ((handle >> 28) & 0xFF); + if (entry > -1 && entry < v->maps_count) { + if (dnm) memcpy(dnm, v->dev_namespace_maps[entry], + sizeof(DEV_NAMESPACE_MAP)); + + XDPRINTF((1, 0, "vol=%d, handle=0x%x to ino=%d, dev=%d, namespace=%d", + volume, handle, (int)(handle & 0xFFFFFF), + v->dev_namespace_maps[entry]->dev, + v->dev_namespace_maps[entry]->namespace)); + return((ino_t) (handle & 0xFFFFFF)); + } + } + XDPRINTF((1, 0, "Can't vol=%d, handle=0x%x to inode", volume, handle)); + return(-1); +} + +int nw_get_volume_number(uint8 *volname, int namelen) +/* Get Volume Number with name */ +/* returns Volume Nummer or if error < 0 */ +{ + int result = -0x98; /* Volume not exist */ + uint8 vname[255]; + int j = used_nw_volumes; + strmaxcpy((char*)vname, (char*)volname, namelen); + upstr(vname); + while (j--) { + if (!strcmp(nw_volumes[j].sysname, vname)) { + result = j; + break; + } + } + XDPRINTF((5,0,"GET_VOLUME_NUMBER of:%s: result = 0x%x", vname, result)); + return(result); +} + +int nw_get_volume_name(int volnr, uint8 *volname) +/* returns < 0 if error, else len of volname */ +{ + int result = -0x98; /* Volume not exist */; + if (volnr > -1 && volnr < used_nw_volumes) { + if (volname != NULL) { + strcpy(volname, nw_volumes[volnr].sysname); + result = strlen(volname); + } else result= strlen(nw_volumes[volnr].sysname); + } else { + if (NULL != volname) *volname = '\0'; + if (volnr < MAX_NW_VOLS) result=0; + } + if (nw_debug > 4) { + char xvolname[10]; + if (!volname) { + volname = xvolname; + *volname = '\0'; + } + XDPRINTF((5,0,"GET_VOLUME_NAME von:%d = %s: ,result=0x%x", volnr, volname, result)); + } + return(result); +} + + +/* next is stolen from GNU-fileutils */ +static long adjust_blocks (long blocks, int fromsize, int tosize) +{ + if (fromsize == tosize) /* E.g., from 512 to 512. */ + return blocks; + else if (fromsize > tosize) /* E.g., from 2048 to 512. */ + return blocks * (fromsize / tosize); + else /* E.g., from 256 to 512. */ + return (blocks + (blocks < 0 ? -1 : 1)) / (tosize / fromsize); +} + +static int get_fs_usage(char *path, struct fs_usage *fsp) +{ + struct statfs fsd; + if (statfs (path, &fsd) < 0) return (-1); + XDPRINTF((3, 0, + "blocks=%d, bfree=%d, bavail=%d, files=%d, ffree=%d, bsize=%d", + fsd.f_blocks, fsd.f_bfree, fsd.f_bavail, + fsd.f_files, fsd.f_ffree, fsd.f_bsize)); +#define convert_blocks(b) adjust_blocks ((b), fsd.f_bsize, 512) + fsp->fsu_blocks = convert_blocks (fsd.f_blocks); + fsp->fsu_bfree = convert_blocks (fsd.f_bfree); + fsp->fsu_bavail = convert_blocks (fsd.f_bavail); + fsp->fsu_files = fsd.f_files; + fsp->fsu_ffree = fsd.f_ffree; + return(0); +} + +int nw_get_fs_usage(char *volname, struct fs_usage *fsu) +/* returns 0 if OK, else errocode < 0 */ +{ + int volnr = nw_get_volume_number(volname, strlen(volname)); + return((volnr>-1 && !get_fs_usage(nw_volumes[volnr].unixname, fsu)) ? 0 : -1); +} + +int get_volume_options(int volnr, int mode) +/* returns >= 0 (options) if OK, else errocode < 0 */ +/* if mode > 0 and errcode then errorcode = 0 (nooptions) */ +{ + int result = (mode) ? 0 : -0x98; /* Volume not exist */; + if (volnr > -1 && volnr < used_nw_volumes) + result = nw_volumes[volnr].options; + XDPRINTF((5,0,"get_volume_options of VOLNR:%d, result=0x%x", volnr, result)); + return(result); +} + diff --git a/nwvolume.h b/nwvolume.h new file mode 100644 index 0000000..abaa397 --- /dev/null +++ b/nwvolume.h @@ -0,0 +1,68 @@ +/* nwvolume.h 15-Jan-96 */ +/* (C)opyright (C) 1993,1995 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. + */ + +#define MAX_DEV_NAMESPACE_MAPS 256 + +typedef struct { + int dev; + int namespace; +} DEV_NAMESPACE_MAP; + +/* + * This is inserted for namespace calls, to can map an + * volume->dev->inode->namespace to an uint32 basehandle + * without loosing too many places. + */ + +typedef struct { + uint8 *sysname; /* VOL_NAME */ + uint8 *unixname; /* UNIX-Verzeichnis */ + int unixnamlen; /* len of unixname */ + DEV_NAMESPACE_MAP *dev_namespace_maps[MAX_DEV_NAMESPACE_MAPS]; + int maps_count; /* count of dev_namespace_maps */ + uint8 options; /* *_1_* alles in Kleinbuchstaben */ +} NW_VOL; + +#define VOL_OPTION_DOWNSHIFT 1 +#define VOL_OPTION_IS_PIPE 2 /* Volume has only pipes */ + + +/* stolen from GNU-fileutils */ +/* Space usage statistics for a filesystem. Blocks are 512-byte. */ +struct fs_usage { + long fsu_blocks; /* Total blocks. */ + long fsu_bfree; /* Free blocks available to superuser. */ + long fsu_bavail; /* Free blocks available to non-superuser. */ + long fsu_files; /* Total file nodes. */ + long fsu_ffree; /* Free file nodes. */ +}; + +extern NW_VOL nw_volumes[MAX_NW_VOLS]; +extern int used_nw_volumes; + +extern void nw_init_volumes(FILE *f); +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(char *volname, struct fs_usage *fsu); +extern int get_volume_options(int volnr, int mode); + +extern uint32 nw_vol_inode_to_handle(int volume, ino_t inode, + DEV_NAMESPACE_MAP *dnm); + +extern ino_t nw_vol_handle_to_inode(int volume, uint32 handle, + DEV_NAMESPACE_MAP *dnm); diff --git a/tools.c b/tools.c index 3deb989..b64e956 100644 --- a/tools.c +++ b/tools.c @@ -1,4 +1,4 @@ -/* tools.c 07-Jan-96 */ +/* tools.c 22-Jan-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -18,7 +18,6 @@ #include "net.h" #include -#include int nw_debug=0; FILE *logfile=stdout; @@ -201,6 +200,14 @@ void get_ini_debug(int module) if (debug > -1) nw_debug = debug; } +static void sig_segv(int isig) +{ + char *s= "PANIC signal SIGSEGV" ; + XDPRINTF((0, 0, s)); + fprintf(stderr, s); + exit(99); +} + void init_tools(int module) { char buff[300]; @@ -244,6 +251,7 @@ void init_tools(int module) XDPRINTF((1, 0, "Starting Version: %d.%02dpl%d", _VERS_H_, _VERS_L_, _VERS_P_ )); } + signal(SIGSEGV, sig_segv); } void exit_tools(int what) @@ -292,30 +300,3 @@ uint8 *downstr(uint8 *s) return(s); } -/* next is stolen from GNU-fileutils */ -static long adjust_blocks (long blocks, int fromsize, int tosize) -{ - if (fromsize == tosize) /* E.g., from 512 to 512. */ - return blocks; - else if (fromsize > tosize) /* E.g., from 2048 to 512. */ - return blocks * (fromsize / tosize); - else /* E.g., from 256 to 512. */ - return (blocks + (blocks < 0 ? -1 : 1)) / (tosize / fromsize); -} - -int get_fs_usage(char *path, struct fs_usage *fsp) -{ - struct statfs fsd; - if (statfs (path, &fsd) < 0) return (-1); - XDPRINTF((3, 0, - "blocks=%d, bfree=%d, bavail=%d, files=%d, ffree=%d, bsize=%d", - fsd.f_blocks, fsd.f_bfree, fsd.f_bavail, - fsd.f_files, fsd.f_ffree, fsd.f_bsize)); -#define convert_blocks(b) adjust_blocks ((b), fsd.f_bsize, 512) - fsp->fsu_blocks = convert_blocks (fsd.f_blocks); - fsp->fsu_bfree = convert_blocks (fsd.f_bfree); - fsp->fsu_bavail = convert_blocks (fsd.f_bavail); - fsp->fsu_files = fsd.f_files; - fsp->fsu_ffree = fsd.f_ffree; - return(0); -} diff --git a/tools.h b/tools.h index 64b303e..04e39a8 100644 --- a/tools.h +++ b/tools.h @@ -1,4 +1,4 @@ -/* tools.h : 07-Jan-96 */ +/* tools.h : 15-Jan-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * @@ -48,18 +48,6 @@ extern uint8 *downstr(uint8 *s); extern uint8 *upstr(uint8 *s); -/* stolen from GNU-fileutils */ -/* Space usage statistics for a filesystem. Blocks are 512-byte. */ -struct fs_usage { - long fsu_blocks; /* Total blocks. */ - long fsu_bfree; /* Free blocks available to superuser. */ - long fsu_bavail; /* Free blocks available to non-superuser. */ - long fsu_files; /* Total file nodes. */ - long fsu_ffree; /* Free file nodes. */ -}; -extern int get_fs_usage(char *path, struct fs_usage *fsp); - - extern int nw_debug; #ifdef DB # define DPRINTF(x) dprintf x