From da30e32a016f531bd0987bca0aed13e4b18f8e26 Mon Sep 17 00:00:00 2001 From: Mario Fetka Date: Sun, 13 Nov 2011 00:38:56 +0100 Subject: [PATCH] mars_nwe-0.97.pl03 --- Makefile | 5 +- README | 4 + connect.c | 329 +++---------- connect.h | 94 +--- doc/CHANGES | 23 +- doc/FAQS | 14 + doc/FRAGEN | 34 ++ doc/FRAGEN.erik | 100 ++++ doc/INSTALL | 19 +- doc/INSTALL.ger | 25 +- doc/NEWS | 17 + doc/PIPE-FS | 70 +++ doc/PIPE-FS.ger | 69 +++ doc/mars_nwe.lsm | 10 +- emutli.c | 271 +---------- emutli.h | 36 +- emutli1.c | 391 +++++++++++++++ emutli1.h | 40 ++ examples/README.kpatch1.2.13 | 7 + ...EADME.kpatch1.3.72 => README.kpatch1.3.7x} | 4 +- examples/config.h | 34 +- examples/kpatch1.2.13 | 122 +++++ examples/kpatch1.3.78 | 74 +++ examples/mk.li | 7 +- examples/nw.ini | 63 ++- examples/patchme | 1 + makefile.unx | 39 +- namspace.c | 447 +++++++++++++----- namspace.h | 9 +- ncpserv.c | 21 +- net.h | 80 +++- net1.c | 4 + nwbind.c | 171 +++++-- nwconn.c | 85 +++- nwdbm.c | 86 ++-- nwdbm.h | 13 +- nwfile.c | 123 +++-- nwfile.h | 3 +- nwqueue.c | 408 ++++++++++++++++ nwqueue.h | 92 ++++ nwroute.c | 351 ++++++++++---- nwroute1.c | 5 + nwrouted.c | 4 + nwserv.c | 143 ++++-- nwserv.h | 30 +- nwvolume.c | 110 +++-- nwvolume.h | 25 +- tools.c | 173 +++++-- tools.h | 15 +- unxfile.c | 54 +++ unxfile.h | 22 + unxlog.c | 77 +++ unxlog.h | 5 + 53 files changed, 3233 insertions(+), 1225 deletions(-) create mode 100644 doc/FAQS create mode 100644 doc/FRAGEN create mode 100644 doc/FRAGEN.erik create mode 100644 doc/PIPE-FS create mode 100644 doc/PIPE-FS.ger create mode 100644 emutli1.c create mode 100644 emutli1.h create mode 100644 examples/README.kpatch1.2.13 rename examples/{README.kpatch1.3.72 => README.kpatch1.3.7x} (84%) create mode 100644 examples/kpatch1.2.13 create mode 100644 examples/kpatch1.3.78 create mode 100644 nwqueue.c create mode 100644 nwqueue.h create mode 100644 nwrouted.c create mode 100644 unxfile.c create mode 100644 unxfile.h create mode 100644 unxlog.c create mode 100644 unxlog.h diff --git a/Makefile b/Makefile index d41af0b..4731d40 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ VPATH= V_VPATH=.. OBJDIR=obj -all: rmeflag mk.li config.h nw.ini +all: rmeflag mk.li config.h nw.ini @if [ -r .eflag ] ; then \ echo ""; \ echo "********************************************************"; \ @@ -26,6 +26,9 @@ all: rmeflag mk.li config.h nw.ini echo "********************************************************" ; \ echo ""; echo "" ; fi ) fi +routed: + ./mk.li $@ + install: ./mk.li $@ diff --git a/README b/README index bd92245..a9be0a6 100644 --- a/README +++ b/README @@ -23,3 +23,7 @@ Topics for the list: You can subscribe to the list by sending command "add linware" in mail message body to address: "listserv@sh.cvut.cz". Your list postings should be sent to address: "linware@sh.cvut.cz". + + + + diff --git a/connect.c b/connect.c index 749191a..c3f0896 100644 --- a/connect.c +++ b/connect.c @@ -1,4 +1,4 @@ -/* connect.c 20-Mar-96 */ +/* connect.c 04-May-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -17,13 +17,11 @@ */ #include "net.h" +#include "unxfile.h" #include #include -#include -extern int errno; - /* #define TEST_FNAME "PRINT.000" */ #ifdef TEST_FNAME @@ -61,9 +59,10 @@ 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_nw_volumes) { - fprintf(stderr, "build_unix_name volume=%d not ok\n", volume); - strcpy(unixname, "ZZZZZZZZZZZZ"); /* vorsichthalber */ + if (volume < 0 || volume >= used_nw_volumes + || !nw_volumes[volume].unixnamlen) { + errorp(0, "build_unix_name", "volume=%d not ok\n", volume); + strcpy(unixname, "Z/Z/Z/Z"); /* */ return(unixname); } strcpy(unixname, (char*)nw_volumes[volume].unixname); /* first UNIXNAME VOLUME */ @@ -73,8 +72,14 @@ static char *build_unix_name(NW_PATH *nwpath, int modus) p += strlen((char*)nwpath->path); if ( (!(modus & 1)) && nwpath->fn[0]) strcpy(p, (char*)nwpath->fn); /* and now fn */ - else if ((modus & 2) && (*(p-1) == '/')) *(p-1) = '\0'; - if (nw_volumes[volume].options & 1) downstr((uint8*)pp); + else if ((modus & 2) && (*(p-1) == '/')) { + if (p > unixname+1) *(--p) = '\0'; + else { + *p++ = '.'; + *p = '\0'; + } + } + if (nw_volumes[volume].options & VOL_OPTION_DOWNSHIFT) downstr((uint8*)pp); return(unixname); } @@ -201,7 +206,7 @@ static int x_str_match(uint8 *s, uint8 *p) switch (state){ case 0 : switch (pc) { - case 255: if (*p == '*' || *p == '?') continue; + case 255: if (*p == '*' || *p == '?' || *p==0xaa || *p==0xae) continue; break; case '\\': /* beliebiges Folgezeichen */ @@ -273,7 +278,7 @@ static int x_str_match(uint8 *s, uint8 *p) return ( (*s) ? 0 : 1); } -int fn_match(uint8 *s, uint8 *p, uint8 options) +int fn_match(uint8 *s, uint8 *p, int options) { uint8 *ss=s; int len=0; @@ -284,7 +289,7 @@ int fn_match(uint8 *s, uint8 *p, uint8 options) len=0; } else { if ((pf && len > 3) || len > 8) return(0); - if (options & 1){ /* only downshift chars */ + if (options & VOL_OPTION_DOWNSHIFT){ /* only downshift chars */ if (*ss >= 'A' && *ss <= 'Z') return(0); } else { /* only upshift chars */ if (*ss >= 'a' && *ss <= 'z') return(0); @@ -312,7 +317,7 @@ static int func_search_entry(NW_PATH *nwpath, int attrib, char xkpath[256]; uint8 entry[256]; int volume = nwpath->volume; - uint8 soptions; + int soptions; FUNC_SEARCH fs_local; if (!fs) { fs = &fs_local; @@ -322,7 +327,7 @@ static int func_search_entry(NW_PATH *nwpath, int attrib, if (volume < 0 || volume >= used_nw_volumes) return(-1); /* something wrong */ else soptions = nw_volumes[volume].options; strcpy((char*)entry, (char*)nwpath->fn); - if (soptions & 1) downstr(entry); /* now downshift chars */ + if (soptions & VOL_OPTION_DOWNSHIFT) downstr(entry); /* now downshift chars */ nwpath->fn[0] = '\0'; strcpy(xkpath, build_unix_name(nwpath, 1|2)); @@ -347,7 +352,7 @@ static int func_search_entry(NW_PATH *nwpath, int attrib, || ( ( (fs->statb.st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10))); if (okflag){ strcpy((char*)nwpath->fn, (char*)name); - if (soptions & 1) upstr(nwpath->fn); + if (soptions & VOL_OPTION_DOWNSHIFT) upstr(nwpath->fn); XDPRINTF((5,0,"FOUND=:%s: attrib=0x%x", nwpath->fn, fs->statb.st_mode)); result = (*fs_func)(nwpath, fs); if (result < 0) break; @@ -376,11 +381,11 @@ static int get_dir_entry(NW_PATH *nwpath, char xkpath[256]; uint8 entry[256]; int volume = nwpath->volume; - uint8 soptions; + int soptions; if (volume < 0 || volume >= used_nw_volumes) return(0); /* something wrong */ else soptions = nw_volumes[volume].options; strcpy((char*)entry, (char*)nwpath->fn); - if (soptions & 1) downstr(entry); /* now downshift chars */ + if (soptions & VOL_OPTION_DOWNSHIFT) downstr(entry); /* now downshift chars */ nwpath->fn[0] = '\0'; strcpy(xkpath, build_unix_name(nwpath, 1|2)); @@ -409,7 +414,7 @@ static int get_dir_entry(NW_PATH *nwpath, || ( ( (statb->st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10))); if (okflag){ strcpy((char*)nwpath->fn, (char*)name); - if (soptions & 1) upstr(nwpath->fn); + if (soptions & VOL_OPTION_DOWNSHIFT) upstr(nwpath->fn); XDPRINTF((5,0,"FOUND=:%s: attrib=0x%x", nwpath->fn, statb->st_mode)); break; /* ready */ } @@ -457,7 +462,7 @@ static int get_dh_entry(DIR_HANDLE *dh, uint8 entry[256]; strmaxcpy(entry, search, 255); - if (dh->vol_options & 1) downstr(entry); + if (dh->vol_options & VOL_OPTION_DOWNSHIFT) downstr(entry); if ( (uint16)*sequence == MAX_U16) *sequence = 0; seekdir(f, (long) *sequence); @@ -483,7 +488,7 @@ static int get_dh_entry(DIR_HANDLE *dh, || (((statb->st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10))); if (okflag){ strcpy((char*)search, (char*)name); - if (dh->vol_options & 1) upstr(search); + if (dh->vol_options & VOL_OPTION_DOWNSHIFT) upstr(search); break; /* ready */ } } else okflag = 0; @@ -907,7 +912,7 @@ int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode) d++; } completition = 0; - } else if (errno & EEXIST) + } else if (errno == EEXIST) completition = -0xa0; /* dir not empty */ else completition = -0x8a; /* No privilegs */ } @@ -942,9 +947,9 @@ int mv_file(int qdirhandle, uint8 *q, int qlen, unlink(unziel); } } else { - if (errno & EEXIST) - completition=-0x91; /* allready exist */ - else if (errno & EXDEV) + if (errno == EEXIST) + completition=-0x92; /* allready exist */ + else if (errno == EXDEV) completition=-0x9a; /* cross devices */ else completition=-0x9c; /* wrong path */ } @@ -953,6 +958,42 @@ int mv_file(int qdirhandle, uint8 *q, int qlen, return(completition); } +int mv_dir(int dir_handle, uint8 *q, int qlen, + uint8 *z, int zlen) +{ + NW_PATH quellpath; + NW_PATH zielpath; + int completition=conn_get_kpl_path(&quellpath, dir_handle, q, qlen, 0); + if (!completition > -1){ + memcpy(&zielpath, &quellpath, sizeof(NW_PATH)); + strmaxcpy(zielpath.fn, z, zlen); + if (completition > -1) { + if (get_volume_options(quellpath.volume, 1) & + VOL_OPTION_IS_PIPE) + completition = -0x9c; + } + if (completition > -1){ + int result; + char unquelle[256]; + char unziel[256]; + strcpy(unquelle, build_unix_name(&quellpath, 0)); + strcpy(unziel, build_unix_name(&zielpath, 0)); + result = unx_mvdir((uint8 *)unquelle, (uint8 *)unziel); + XDPRINTF((2,0, "rendir result=%d, '%s'->'%s'", + result, unquelle, unziel)); + if (!result) + completition = 0; + else { + if (result == EEXIST) + completition=-0x92; /* allready exist */ + else if (result == EXDEV) + completition=-0x9a; /* cross devices */ + else completition=-0x9c; /* wrong path */ + } + } + } + return(completition); +} static int change_dir_entry( NW_DIR *dir, int volume, uint8 *path, ino_t inode, @@ -1077,7 +1118,7 @@ int nw_free_handles(int task) return(0); } -int insert_new_dir(NW_PATH *nwpath, int inode, int drive, int is_temp, int task) +int xinsert_new_dir(int volume, uint8 *path, int inode, int drive, int is_temp, int task) { int j = 0; time_t lowtime = time(NULL); @@ -1088,7 +1129,7 @@ int insert_new_dir(NW_PATH *nwpath, int inode, int drive, int is_temp, int task) for (j = 0; j < (int)used_dirs; j++) { NW_DIR *d = &(dirs[j]); if (d->inode && !is_temp && !d->is_temp && (int)d->drive == drive) { - (void)change_dir_entry(d, nwpath->volume, nwpath->path, inode, drive, is_temp, 1, task); + (void)change_dir_entry(d, volume, path, inode, drive, is_temp, 1, task); return(++j); } else if (!d->inode) freehandle = j+1; else if (d->is_temp && d->timestamp < lowtime) { @@ -1100,13 +1141,20 @@ int insert_new_dir(NW_PATH *nwpath, int inode, int drive, int is_temp, int task) if (!freehandle) freehandle = timedhandle; if (freehandle){ (void)change_dir_entry(&(dirs[freehandle-1]), - nwpath->volume, nwpath->path, inode, + volume, path, 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) +{ + return(xinsert_new_dir(nwpath->volume, nwpath->path, + inode, drive, is_temp, task)); +} + + int nw_search(uint8 *info, int dirhandle, int searchsequence, int search_attrib, uint8 *data, int len) @@ -1556,232 +1604,5 @@ int nw_scan_a_root_dir(uint8 *rdata, } else return(completition); /* wrong path */ } -/* <======================================================================> */ -/* minimal queue handling to enable very simple printing */ -/* qick and dirty !!!!!!!!!!!!!!! */ - -#define MAX_JOBS 5 /* max. open queue jobs for one connection */ -static int anz_jobs=0; - -typedef struct { - uint32 fhandle; - int old_job; /* is old structure */ - union { - QUEUE_JOB n; - QUEUE_JOB_OLD o; - } q; -} INT_QUEUE_JOB; - -INT_QUEUE_JOB *queue_jobs[MAX_JOBS]; - -static INT_QUEUE_JOB *give_new_queue_job(int old_job) -{ - int k=-1; - while (++k < anz_jobs) { - INT_QUEUE_JOB *p=queue_jobs[k]; - if (!p->fhandle) { /* free slot */ - memset(p, 0, sizeof(INT_QUEUE_JOB)); - p->old_job = old_job; - if (old_job) - p->q.o.job_id[0] = k+1; - else - p->q.n.job_id[0] = k+1; - return(p); - } - } - if (anz_jobs < MAX_JOBS) { - INT_QUEUE_JOB **pp=&(queue_jobs[anz_jobs++]); - *pp = (INT_QUEUE_JOB *) xmalloc(sizeof(INT_QUEUE_JOB)); - memset(*pp, 0, sizeof(INT_QUEUE_JOB)); - (*pp)->old_job = old_job; - if (old_job) - (*pp)->q.o.job_id[0] = anz_jobs; - else - (*pp)->q.n.job_id[0] = anz_jobs; - return(*pp); - } - return(NULL); -} - -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, 1); - if (q_id == anz_jobs) { - xfree(*pp); - --anz_jobs; - } else (*pp)->fhandle=0L; - } -} - -static void set_entry_time(uint8 *entry_time) -{ - struct tm *s_tm; - time_t timer; - time(&timer); - s_tm = localtime(&timer); - entry_time[0] = (uint8) s_tm->tm_year; - entry_time[1] = (uint8) s_tm->tm_mon+1; - entry_time[2] = (uint8) s_tm->tm_mday; - entry_time[3] = (uint8) s_tm->tm_hour; - entry_time[4] = (uint8) s_tm->tm_min; - entry_time[5] = (uint8) s_tm->tm_sec; -} - -static int create_queue_file(uint8 *job_file_name, - uint32 q_id, - int jo_id, - int connection, - uint8 *dirname, - int dir_nam_len, - uint8 *job_bez) - -{ - int result; - NW_FILE_INFO fnfo; - *job_file_name - = sprintf((char*)job_file_name+1, "%07lX%d.%03d", q_id, jo_id, connection); - - result=nw_alloc_dir_handle(0, dirname, dir_nam_len, 99, 2, 1); - if (result > -1) - result = nw_creat_open_file(result, job_file_name+1, - (int) *job_file_name, - &fnfo, 0x6, 0x6, 1 | 4); - - XDPRINTF((5,0,"creat queue file bez=`%s` handle=%d", - job_bez, result)); - return(result); -} - - -int nw_creat_queue(int connection, uint8 *queue_id, uint8 *queue_job, - uint8 *dirname, int dir_nam_len, int old_call) -{ - INT_QUEUE_JOB *jo = give_new_queue_job(old_call); - uint32 q_id = GET_BE32(queue_id); - int result = -0xff; - XDPRINTF((5,0,"NW_CREAT_Q:dlen=%d, dirname=%s", dir_nam_len, dirname)); - - if (NULL != jo) { - int jo_id = 0; - if (jo->old_job) { - jo_id = (int) jo->q.o.job_id[0]; - memcpy(&(jo->q.o), queue_job, sizeof(QUEUE_JOB_OLD)); - jo->q.o.job_id[0] = (uint8) jo_id; - jo->q.o.client_connection = (uint8)connection; - jo->q.o.client_task = (uint8)0xfe; /* ?? */ - U32_TO_BE32(1, jo->q.o.client_id); /* SU */ - set_entry_time(jo->q.o.job_entry_time); - jo->q.o.job_typ[0] = 0x0; /* 0xd0;*/ - jo->q.o.job_typ[1] = 0x0; - jo->q.o.job_position = 0x1; - jo->q.o.job_control_flags |= 0x20; - - result = create_queue_file(jo->q.o.job_file_name, - q_id, jo_id, connection, - dirname, dir_nam_len, - jo->q.o.job_bez); - - if (result > -1) { - jo->fhandle = (uint32) result; - U16_TO_BE16(0, jo->q.o.job_file_handle); - U32_TO_BE32(jo->fhandle, jo->q.o.job_file_handle+2); - result = 0; - } - jo->q.o.server_station = 0; - jo->q.o.server_task = 0; - U32_TO_BE32(0, jo->q.o.server_id); - if (!result) memcpy(queue_job, &(jo->q.o), sizeof(QUEUE_JOB_OLD)); - } else { - jo_id = (int) jo->q.n.job_id[0]; - memcpy(&(jo->q.n), queue_job, sizeof(QUEUE_JOB)); - jo->q.n.job_id[0] = (uint8) jo_id; - - U16_TO_BE16(0xffff, jo->q.n.record_in_use); - U32_TO_BE32(0x0, jo->q.n.record_previous); - U32_TO_BE32(0x0, jo->q.n.record_next); - memset(jo->q.n.client_connection, 0, 4); - jo->q.n.client_connection[0] = (uint8)connection; - memset(jo->q.n.client_task, 0, 4); - jo->q.n.client_task[0] = (uint8)0xfe; /* ?? */ - U32_TO_BE32(1, jo->q.n.client_id); /* SU */ - set_entry_time(jo->q.n.job_entry_time); - - jo->q.n.job_typ[0] = 0x0; /* 0xd0;*/ - jo->q.n.job_typ[1] = 0x0; - jo->q.n.job_position[0] = 0x1; - jo->q.n.job_position[1] = 0x0; - jo->q.n.job_control_flags[0] |= 0x20; - jo->q.n.job_control_flags[1] = 0x0; - - result = create_queue_file(jo->q.n.job_file_name, - q_id, jo_id, connection, - dirname, dir_nam_len, - jo->q.n.job_bez); - - if (result > -1) { - jo->fhandle = (uint32) result; - U32_TO_BE32(jo->fhandle, jo->q.n.job_file_handle); - result = 0; - } - U32_TO_BE32(0, jo->q.n.server_station); - U32_TO_BE32(0, jo->q.n.server_task); - U32_TO_BE32(0, jo->q.n.server_id); - if (!result) memcpy(queue_job, &(jo->q.n), sizeof(QUEUE_JOB)); - } - if (result) free_queue_job(jo_id); - } - return(result); -} - -int nw_close_file_queue(uint8 *queue_id, - uint8 *job_id, - uint8 *prc, int prc_len) -{ - int result = -0xff; - int jo_id = (int) *job_id; /* ever only the first byte */ - XDPRINTF((5,0,"nw_close_file_queue JOB=%d", jo_id)); - if (jo_id > 0 && jo_id <= anz_jobs){ - INT_QUEUE_JOB *jo=queue_jobs[jo_id-1]; - int fhandle = (int)jo->fhandle; - char unixname[300]; - strmaxcpy((uint8*)unixname, (uint8*)file_get_unix_name(fhandle), sizeof(unixname)-1); - XDPRINTF((5,0,"nw_close_file_queue fhandle=%d", fhandle)); - if (*unixname) { - char printcommand[256]; - FILE *f=NULL; - strmaxcpy((uint8*)printcommand, prc, prc_len); - nw_close_datei(fhandle, 1); - jo->fhandle = 0L; - if (NULL != (f = fopen(unixname, "r"))) { - int is_ok = 0; - FILE *fout = popen(printcommand, "w"); - if (fout) { - char buff[1024]; - int k; - is_ok++; - while ((k = fread(buff, 1, sizeof(buff), f)) > 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`", printcommand)); - fclose(f); - if (is_ok) { - unlink(unixname); - result=0; - } - } else XDPRINTF((1,0,"Cannot open queue-file `%s`", unixname)); - } else - XDPRINTF((2,0,"fhandle=%d NOT OK !", fhandle)); - free_queue_job(jo_id); - } - return(result); -} diff --git a/connect.h b/connect.h index 4c42287..3f60cca 100644 --- a/connect.h +++ b/connect.h @@ -1,4 +1,4 @@ -/* connect.h 10-Mar-96 */ +/* connect.h 04-May-96 */ #ifndef _CONNECT_H_ #define _CONNECT_H_ typedef struct { @@ -7,8 +7,8 @@ typedef struct { ino_t inode; /* Unix Inode */ time_t timestamp; /* fr letzte Allocierung */ char *kpath; /* Ein Zeichen nach unixname */ - uint8 vol_options; /* Suchoptions */ - uint8 volume; /* Volume Number */ + int vol_options; /* Suchoptions */ + int volume; /* Volume Number */ } DIR_HANDLE; typedef struct { @@ -69,7 +69,8 @@ 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); - +extern int mv_dir(int dir_handle, uint8 *q, int qlen, + uint8 *z, int zlen); extern int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode); @@ -86,6 +87,9 @@ extern int nw_find_dir_handle( int dir_handle, uint8 *data, /* zustzlicher Pfad */ int len); /* Lnge Pfad */ +extern int xinsert_new_dir(int volume, uint8 *path, + int inode, int drive, int is_temp, int task); + extern int nw_alloc_dir_handle( int dir_handle, /* Suche ab Pfad dirhandle */ uint8 *data, /* zustzl. Pfad */ @@ -145,87 +149,7 @@ extern int nw_scan_a_root_dir(uint8 *rdata, int dirhandle); -extern int fn_match(uint8 *s, uint8 *p, uint8 options); - - -/* queues */ -typedef struct { - uint8 record_in_use[2]; - uint8 record_previous[4]; - uint8 record_next[4]; - uint8 client_connection[4]; - uint8 client_task[4]; - 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_id[4]; /* ?? alles 0 HI-LOW */ - uint8 job_typ[2]; /* z.B. Printform HI-LOW */ - uint8 job_position[2]; /* ?? alles 0 low-high ? */ - uint8 job_control_flags[2]; /* z.B 0x10, 0x00 */ - /* 0x80 operator hold flag */ - /* 0x40 user hold flag */ - /* 0x20 entry open flag */ - /* 0x10 service restart flag */ - /* 0x08 autostart flag */ - - uint8 job_file_name[14]; /* len + DOS filename */ - uint8 job_file_handle[4]; - uint8 server_station[4]; - uint8 server_task[4]; - uint8 server_id[4]; - uint8 job_bez[50]; /* "LPT1 Catch" */ - uint8 client_area[152]; -} QUEUE_JOB; - -typedef struct { - uint8 client_connection; - uint8 client_task; - 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_id[2]; /* ?? alles 0 HI-LOW */ - uint8 job_typ[2]; /* z.B. Printform HI-LOW */ - uint8 job_position; /* zero */ - uint8 job_control_flags; /* z.B 0x10 */ - /* 0x80 operator hold flag */ - /* 0x40 user hold flag */ - /* 0x20 entry open flag */ - /* 0x10 service restart flag */ - /* 0x08 autostart flag */ - - uint8 job_file_name[14]; /* len + DOS filename */ - uint8 job_file_handle[6]; - uint8 server_station; - uint8 server_task; - uint8 server_id[4]; - uint8 job_bez[50]; /* "LPT1 Catch" */ - uint8 client_area[152]; -} QUEUE_JOB_OLD; /* before 3.11 */ - -typedef struct { - uint8 version; /* normal 0x0 */ - 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 bannner_header_file_name[14]; /* all zero */ - uint8 file_path_name[80]; /* all zero */ -} QUEUE_PRINT_AREA; - -extern int nw_creat_queue(int connection, uint8 *queue_id, uint8 *queue_job, - uint8 *dirname, int dir_nam_len, int old_call); - -extern int nw_close_file_queue(uint8 *queue_id, - uint8 *job_id, - uint8 *prc, int prc_len); +extern int fn_match(uint8 *s, uint8 *p, int options); extern uint16 un_date_2_nw(time_t time, uint8 *d); diff --git a/doc/CHANGES b/doc/CHANGES index 57aa177..95fbc3e 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -1,5 +1,5 @@ -Sorry, this is in German only. :-( -Aenderungen in mars_nwe bis zum : 21-Mar-96 +Sorry, this is in German only. +Aenderungen in mars_nwe bis zum : 07-May-96 -------------------------------- Erste 'oeffentliche' Version ^^^^^^^^^^ VERSION 0.94 ^^^^^^^^ @@ -102,5 +102,22 @@ Erste 'oeffentliche' Version OS/2 Client u. evtl. auch andere (Win95 ?) erwarten es. ! - Password Schema leicht veraendert/erweitert. modus '8' -> modus '7', neuer modus '8'. -- neue Routine 0x17, 0x10 (set file information) codiert. +- neue Routine 0x17, 0x10 (set file information) kodiert. +- ftruncate unter Linux fuer das Verkuerzen von Dateien eingebaut. +- neuen Volumetyp HOME Dir eingebaut. +- Fehler beim Mappen von Volumes auf UNIX Root '/' korrigiert. +- Fehler ftruncate beseitigt, offset statt 0. (Eduardo Crosclaude) +- Token Ring Frame eingebaut. (Guntram Blohm) +- einfache Zugriffrechte fuer Bindery eingebaut. +- Nur noch der Supervisor (OBJ_ID=1) kann root access erlangen. +- RIP/SAP Routinen ueberarbeitet. +- automatisches Anlegen von IPX-Devices ermoeglicht. +- Routine rename dir 0x16,0xf kodiert. +- 16-Bit get Volinfo Routinen korrigiert. +- Volume Flag 'o' eingefuehrt fuer filesysteme die + Inodes > 0xfffffff liefern. (namespace-services) +- utmp und wtmp werden nun gefuellt. +- Parameter -k fuer SIGTERM und -h fuer SIGHUP eingebaut. +- eigene 'pipe' Routine fuer Druck Queue Aufruf eingebaut. +- namespace services call rename file/dir eingebaut. diff --git a/doc/FAQS b/doc/FAQS new file mode 100644 index 0000000..6f9f76d --- /dev/null +++ b/doc/FAQS @@ -0,0 +1,14 @@ +Q: I don't exaclty understand the meaning of some ponits in nw.ini: + 12,13 + What will happen if I will not put PASSWORD here? Will it take it from + /etc/passwd? I want it to be so. + +A: This passwords will be stored (crypted) into bindery to can handle + the crypted login call from a standarrd Novell client. + +Q: What role plays: 15? + What if I will no supply passwd here? +A: This is for automatic inserting UNIX Users as mars_nwe users. + All of these automatic inserted users will get the password + as the crypted bindery password. + diff --git a/doc/FRAGEN b/doc/FRAGEN new file mode 100644 index 0000000..7013d9e --- /dev/null +++ b/doc/FRAGEN @@ -0,0 +1,34 @@ +Sorry, this is in German only. +einige Fragen und Antworten. + +F: Welche original Novell DOS Tools brauche ich. +A: Fuer eine Minimalkonfiguration ist nur das LOGIN.EXE + Programm notwendig. + folgende weitere Programme sind sinnvoll einsetzbar. + MAP.EXE : Zuweisung von Laufwerken. + CAPTURE.EXE : Zuweisung von Druckern. + SYSCON.EXE : Verwaltungstool + + es ist z.Z. auch ein DOS Client Programm in Entwicklung, welches + es erlaubt, mars_nwe ohne original NOVELL DOS Tools zu + verwenden. + +F: Wird '/dev/ipx' benoetigt. Ich finde Verweise in mars_nwe. +A: Unter Linux Nein. Diese Verweise betreffen nur Systeme mit + TLI-Interfaces. z.B. UnixWare (tm). + +F: Ich verstehe Eintrag '12,13' aus der ini/conf Datei nicht. + Was passiert, falls ich hier kein Passwort eintrage ? + Wird es aus der '/etc/passwd' verwendet. +A: Dieses Passwort wird verschluesselt in die Bindery eingetragen. + Passwoerter aus der '/etc/passwd' werden nur verwendet, falls + mit 'unencryted login calls' gearbeitet wird. + +F: Welche Rolle spielt Eintrag '15'. +A: Dieser Eintrag steht fuer das Passwort, welches bei + dem automatischen Umwandeln Unix -> mars_nwe User allen *neu* + eingetragenen mars_nwe Benutzern als default zugewiesen + wird. + + + diff --git a/doc/FRAGEN.erik b/doc/FRAGEN.erik new file mode 100644 index 0000000..e02e6c0 --- /dev/null +++ b/doc/FRAGEN.erik @@ -0,0 +1,100 @@ +Sorry, this is in German only. +folgende Fragen/Antworten stammen von Erik Thiele. + +> Heisst das, dass mars_nwe die Novell-Partition lesen kann? + ________ + * NEIN * dafuer benutzt du ncpfs oder einen neuen HACKER-KERNEL + ^^^^^^^^ + Novell-Volume +1. 1.2.xx Kernel + NCPFS Packet client +2. 1.3.xx Kernel mit integriertem NCPFS client +3. diverse Kernel u. MARS_NWE server +4. diverse Kernel + patches u. linware server + +wobei sich mars_nwe und ncpfs gleichzeitig miteinander vertragen. + +> wie funktioniert das Drucken + +*** SWITCHING TO THE DOS/NOVELL WORLD *** +das Drucken funktioniert bei Novell so: + +jemand druckt in eine PRINT-QUEUE auf einem NOVELL-SERVER. + +nun gibt es QUEUE-SERVERs. ein QUEUE-SERVER managed eine +oder mehrere PRINT-QUEUEs. Er kann den Inhalt einer PRINT-QUEUE auf eine +parallele Schnittstelle rausdrucken, oder an einen REMOTE-PRINTER schicken. + +QUEUE-SERVER laufen auf DOS als alleiniger systemblockierender Prozess, +d.h. der PC kann derweil nix anderes machen, oder auf einem NOVELL-SERVER, +dort natuerlich nicht blockierenderweisse, iss ja schliesslich Multitasking. + +ein REMOTE-PRINTER ist KEIN drucker der ans ethernet angeschlossen ist, sondern +ein auf einer DOS-kiste laufendes TSR (hintergrundprogramm), das ankommende +Bytes auf die parallele schnittstelle schiebt. Der PC kann derweil noch anderes +tun (oder sich aufhaengen *grins* ) + +*** BACK TO LINUX *** +wenn man nun in eine PRINT-QUEUE drucken will, benutzt man "nprint" aus dem +ncpfs packet. da gibt man den namen der PRINT-QUEUE sowie den Namen des +NOVELL-SERVERS an, auf dem die PRINT-QUEUE rumliegt. + +will man einen drucker an eine linux kiste hinhaengen und ihn ins novell-netz +integrieren (ich hab einen DIN A0 Tintenklekser der an einer HP-workstation +haengt ueber einen LINUX rechner ins NOVELL-NETZ integriert...), so muss man +sich zunaechst entscheiden, ob die PRINT-QUEUE auf dem echten NOVELL-SERVER +sein soll, oder auf dem mars_nwe NOVELL-SERVER. Letzteres bringt probleme mit +sich bei software, die nicht in der lage ist auf eine print-queue zu drucken, +die NICHT auf dem benutzten NOVELL-FILE-SERVER ist. (Wordperfect hat das +bei mir nicht kapiert. man kann es nur so konfigurieren, dass es auf +PRINT-QUEUES druckt, die auch auf dem aktuellen NOVELL-FILE-SERVER sind.) +(Anmerkung: mittels capture funktioniert es aber immer.) +also iss es besser, die QUEUE auf dem bereits existierenden NOVELL-SERVER zu +installieren. dann laesst man noch den QUEUE-SERVER auf dem NOVELL-SERVER laufen +(pconsole), da es einen solchigen fuer Linux nicht gibt. nun muss man auf einer +linux-kiste nur noch das aequivalent zum REMOTE-PRINTER starten. ich weiss +leider nicht mehr, wie das heisst, oder wo es ist, aber ich glaube es ist +in ncpfs... (ich bin zuhause...) + +(will man die PRINT-QUEUE aufm mars_nwe installieren, ist man in 3 sekunden +fertig, lies die mars_nwe dokus) + +naja das ganze iss gar net soooooo schwierig :-) man muss nur kraeftig docus +lesen. und FTP starten :-) +saug dir einfach alle IPX-tools und NETWARE-speziefischen sachen vom sunsite. + +>Ich habe mir mal vor kurzem mars_nwe angesehen, leider ist kein Readme dabei, +>welches die Features beschreibt. +stimmt absolut nicht !!! (schau dir mal die configurationsdatei an :-)))) + +>Kann mars_nwe auch bootserver spielen? Da in unserem Schulrechnerraum nur +>ein einziger >386"-er Rechner da ist, wollte ich unter Linux die restlichen +>10 286'er booten lassen. Kann mars_nwe sich hierbei komplett wie der echte +>Novellserver verhalten? + +ich habe aehnliches problem, allerdings vertagt. BOOT-ROM rechner machen unter +umstaenden ein paar calls, die der mars_nwe noch nicht vertraegt. aber +ansonsten loggen sie sich einfach auf dem ding ein und laden dateien +an definierten positionen. -> mars_nwe muesste das auch koennen. +wenn es nicht geht, liegt das an eben diesen calls. + +es gibt einen der heisst SAP_GET_NEAREST_SERVER. +diesen kann man beim NEUEN mars_nwe ausschalten, damit nur noch der Original +Novell-server auf diesen call reagiert. wenn man naemlich auf der DOS-kiste +den NETX.COM laedt, dann loggt sich das teil automatisch auf dem server ein, +der als ersten den call beantwortet. (der novell server gewinnt immer das +rennen, aber wenn er mal ein bischen busy ist,.... man weiss ja nie !) +abhilfe schafft da eben die option, den call abzuschaffen, oder bei +NETX die option /PS=eumel hinzufuegen, dann loggt er sich nur auf dem "eumel" +ein. +WENN MAN ABER DEN CALL ABSCHAFFT, DANN KOENNEN DIE BOOT-ROM RECHNER EINEN +NICHT MEHR IM NETZ FINDEN !!!! DAS ist ein saudummes problem. +der author sagte aber er wolle es beheben, durch eine liste von +rechnern im configurationsfile, die den call beantwortet kriegen, und +solche, die ihn nicht beantwortet kriegen. allerdings ist wie oben gesagt +der Novell-server immer schneller, so dass der Novell-server hardwaremaessig +von den boot-rom kisten getrennt werden muss, und dann bringt auch die liste +nix mehr... + + + + diff --git a/doc/INSTALL b/doc/INSTALL index 0a882b5..68f5048 100644 --- a/doc/INSTALL +++ b/doc/INSTALL @@ -7,8 +7,25 @@ You can configure mars_nwe in two ways. of mars_nwe, dosemu, ncpfs or Caldera's nwclient was tested. -> you must use kernel < 1.3.60 or use kernel >= 1.3.60 and compile your kernel with IPX-option CONFIG_IPX_INTERN=N + This do NOT mean 'no internal net' but 'no *full* internal net'. In mars_nwe/config.h there must exist the following line: #define INTERNAL_RIP_SAP 1 + If you have other IPX/NCP servers in your net you can let + your external nets configured automaticly. + To do this you must use internal net: entry '3' must be filled + with a *UNIQUE* NetNumber and you must place minimal one + entry '4' with '0' as networknumber, device = '*' and frame=auto. + example for conf/ini file: (see also examples/nw.ini): + 3 0x77777 # UNIQUE network number for internal net. + 4 0x0 * AUTO # autocreat Interfaces + + + If there is no other IPX/NCP Server on your net then + network number in entry '4' can be any number. + 4 0x10 eth0 ethernet_ii # eth0 device with network number '0x10' + # and frame ETHERNET_II. + 4 0x20 eth0 802.3 # eth0 device with network number '0x20' + # und frame ETHERNET_802.3. 2. You want to run mars_nwe only as a fileserver and use special tools to configure ipx and rip/sap routers. @@ -34,7 +51,7 @@ of mars_nwe and make the needed changes to your =========> start programs call nwserv ( as root !! ) -tested with Linux Version 1.2.13 and 1.3.32 +tested with Linux Version 1.2.13 and 1.3.32 and higher the linux-kernel must be configured with IPX=Y. ipx-interface and ipx-routes are setup by the program if the entry 4 (devices) in the nw.ini file is filled. diff --git a/doc/INSTALL.ger b/doc/INSTALL.ger index d15c25e..41460e0 100644 --- a/doc/INSTALL.ger +++ b/doc/INSTALL.ger @@ -1,5 +1,5 @@ =========> !! wichtiger HINWEIS !! -Mars_nwe kann auf Arten konfiguriert werden. +Mars_nwe kann auf 2 Arten konfiguriert werden. 1. Mars_nwe soll die IPX-Routen automatisch setzen, die IPX-Interfaces per ini/conf Datei konfigurieren und als RIP/SAP Router arbeiten. @@ -10,10 +10,31 @@ Mars_nwe kann auf Arten konfiguriert werden. dosemu, ncpfs oder Caldera's nwclient getestet. -> Es muss ein Kernel < 1.3.60 oder aber ein Kernel >= 1.3.60, kompiliert mit IPX-Option CONFIG_IPX_INTERN=N, verwendet werden. + Diese IPX-Kernel Option bedeutet NICHT 'internal net' sondern + 'full internal net'. In mars_nwe/config.h muss folgende Zeile vorhanden sein. #define INTERNAL_RIP_SAP 1 + In einer Umgebung mit anderen IPX/NCP Servern koennen bei + mars_nwe die Devices automatisch konfiguriert werden. + Hierzu muss mars_nwe mit internal net konfiguriert sein: + Eintrag '3' der 'ini/conf Datei' muss eine im Netz eindeutige + Netwerknummer erhalten. + Es muss ein Eintrag '4' mit Netzwerk Nummer = 0, + Device = '*' und Frame = 'auto' fuer ein 'autocreat' Interface + vorhanden sein. + Beispiel fuer conf/ini Datei: (siehe auch: examples/nw.ini) + 3 0x77777 # eindeutige Netzwerk Nummer fuer internal net. + 4 0x0 * AUTO # autocreat Interfaces -2. Mars_nwe soll nur als File Server Verwendung finden. + Falls kein anderer IPX/NCP Server im Netz vorhanden ist + kann im Eintrag '4' eine beliebige Netzwerknummer verwendet werden. + 4 0x10 eth0 ethernet_ii # eth0 Device mit Netznummer '0x10' + # und Frame ETHERNET_II. + 4 0x20 eth0 802.3 # eth0 Device mit Netznummer '0x20' + # und Frame ETHERNET_802.3. + +2. Mars_nwe soll nur als File Server Verwendung finden, d.h. + Routing usw. soll von anderen Programmen erledigt werden. -> Die IPX-Interfaces muessen durch andere Programme/Tools wie 'ipx-configure' oder aehnliche eingerichtet werden und es muss ein rip/sap router/daemon eingerichtet sein. diff --git a/doc/NEWS b/doc/NEWS index 04afd2a..8900356 100644 --- a/doc/NEWS +++ b/doc/NEWS @@ -1,4 +1,21 @@ # in this files are important notes for user of mars_nwe. +------05-May-96--- 0.97.pl3 ---------- +Now nwserv can be called with parameter '-h' to send SIGHUP +to the main nwserv program or with '-k' to send SIGTERM +to the main nwserv program. + +Updating utmp/wtmp files. + +Automatic creat of ixp-interfaces in a NetWare +environment enabled. + +Entry 1 for volumes enhanced. +Now you can make entries like: + +1 HOME ~ k # Unixusers HOME + +This means (path = '~') that this will be a volume +which allways point to the actual users homedir. ------21-Mar-96--- 0.97.pl2 ---------- Entry '7' in ini/conf file modified. Old mode '8' is now mode '7' and mode '8' diff --git a/doc/PIPE-FS b/doc/PIPE-FS new file mode 100644 index 0000000..e65674e --- /dev/null +++ b/doc/PIPE-FS @@ -0,0 +1,70 @@ +The PIPE filesystem arose in answer to the question: how can I save +all or part of a Linux system onto/ via a DOS computer or a Novell +fileserver? The PIPE filesystem was designed as a quick attempt to +solve this problem + +In the PIPE filesystem either shell scripts or Linux programs can be +stored. These programs are treated on the client side (eg DOS) like +simple files. Opening these files via the client causes a popen of the +programs. The server passes as the first parameter either CREAT READ +or WRITE, depending on the mode of the corresponding openfile +operation. This allows the PIPE filesystem to provide a direct +interface between client applications and Linux programs. + +The problem stated above could then be solved with the following +simple shell script, which was stored in the PIPE-filesystem: + +#!/bin/sh +case "$1" in +'CREAT') + ;; +'WRITE') + cd /u3 && tar -xf - 2>> /tmp/tar.in + # restore directory /u3/mar + ;; +'READ') + cd /u3 && tar -cf - mar 2> /dev/null + # save directory /u3/mar + ;; +*) + ;; +esac + + +Under DOS this 'Pipe File' can now be 'copied' into a local file using +the Copy command (->save), or the local file can be copied into this +'Pipe File' (->restore). + +A simple print operation can be achieved with the following script: + +#!/bin/sh +case "$1" in +'WRITE') + /usr/bin/lpr + ;; +*) + ;; +esac + + + +Various unix programs can be invoked with the following script, after +it has been linked with the required program name. + +#!/bin/sh +case "$1" in +'READ') + /usr/bin/`basename $0` + ;; +*) + ;; +esac + + +I would appreciate hearing about further documented applications of +the PIPE filesystem or suggestions for other ways of using it. + +Martin + +(translated by Michael Beddow) + diff --git a/doc/PIPE-FS.ger b/doc/PIPE-FS.ger new file mode 100644 index 0000000..9abd9c1 --- /dev/null +++ b/doc/PIPE-FS.ger @@ -0,0 +1,69 @@ +/* PIPE- Filesystem */ +das 'PIPE Filesystem' entstand urspruenglich aus der Frage heraus: +Wie kann ich ein Linux System oder Teile davon ueber/auf einen +DOS-Rechner oder Novell Fileserver sichern. +Ein schneller Loesungsansatz ergab das 'PIPE Filesystem'. + +In dem Pipe Filesystem koennen Shell Scripte oder +Linux Programme hinterlegt werden. +Diese Programme werden bei dem Client (z.B. DOS) wie einfache +Dateien behandelt. +Ein Oeffnen dieser Dateien ueber den Client bewirkt +einen popen dieser Programme. Der Server uebergibt +als 1. Parameter entweder 'CREAT', 'READ' oder 'WRITE' +je nach Modus der jeweiligen Openfile Operation. +Das 'PIPE-Filesystem' bietet damit eine direkte Schnittstelle +zwischen Client Anwendungen und Linux Programmen. + +Die Loesung des obigen Problems ergab sich dann mit folgendem einfachen +Shell Script, welches im PIPE-Filesystem hinterlegt wurde. + +#!/bin/sh +case "$1" in +'CREAT') + ;; +'WRITE') + cd /u3 && tar -xf - 2>> /tmp/tar.in + # restore directory /u3/mar + ;; +'READ') + cd /u3 && tar -cf - mar 2> /dev/null + # save directory /u3/mar + ;; +*) + ;; +esac + +Unter DOS kann nun diese 'Pipe Datei' mit dem Copy Befehl in eine +lokale Datei 'kopiert' werden ( -> Sichern ) bzw. es +kann die lokale Datei auf diese 'Pipe Datei' kopiert werden. +( -> Ruecksichern ) + +Ein einfaches Drucken kann z.B. mit folgendem Script realisiert werden. +#!/bin/sh +case "$1" in +'WRITE') + /usr/bin/lpr + ;; +*) + ;; +esac + +Der Aufruf diverser Unix Programme kann mit folgenden Script +erfolgen das auf die entsprechenden Programmnamen gelinkt wurde. + +#!/bin/sh +case "$1" in +'READ') + /usr/bin/`basename $0` + ;; +*) + ;; +esac + + +Ueber weitere dokumentierte Anwendungen bzw. Anregungen zu dem +PIPE-Filesystem wuerde ich mich freuen. + +Martin + diff --git a/doc/mars_nwe.lsm b/doc/mars_nwe.lsm index 36d755d..f78010f 100644 --- a/doc/mars_nwe.lsm +++ b/doc/mars_nwe.lsm @@ -1,16 +1,16 @@ Begin3 Title: mars_nwe -Version: 0.97.pl2 -Entered-date: 21-Mar-96 +Version: 0.97.pl3 +Entered-date: 07-May-96 Description: full novell-server-emulator (src),beta supports file-services, bindery-services, printing-services, routing-services 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 - 120kB mars_nwe-0.97.pl2.tgz +Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs + 140kB mars_nwe-0.97.pl3.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) +Platforms: Linux (1.2.xx, 1.3.xx), UnixWare 2.0x Copying-policy: GNU End diff --git a/emutli.c b/emutli.c index ad2e49c..87ae528 100644 --- a/emutli.c +++ b/emutli.c @@ -1,4 +1,4 @@ -/* emutli.c 07-Feb-96 */ +/* emutli.c 28-Apr-96 */ /* * One short try to emulate TLI with SOCKETS. */ @@ -20,13 +20,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Some of the Code in this module is stolen from the following - * Programms: ipx_interface, ipx_route, ipx_configure, which were - * written by Greg Page, Caldera, Inc. - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - */ #include #include #include @@ -42,32 +35,27 @@ #include #include +static int locipxdebug=0; -#ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) -#endif -#ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif +void set_locipxdebug(int debug) +{ + locipxdebug = debug; +} -static int locipxdebug=0; -static int have_ipx_started=0; - - -static void set_sock_debug(int sock) +void set_sock_debug(int sock) { if (setsockopt(sock, SOL_SOCKET, SO_DEBUG, &locipxdebug, sizeof(int))==-1){ errorp(0, "setsockopt SO_DEBUG", NULL); } } -static void sock2ipxadr(ipxAddr_t *i, struct sockaddr_ipx *so) +void sock2ipxadr(ipxAddr_t *i, struct sockaddr_ipx *so) { memcpy(i->net, &so->sipx_network, IPX_NET_SIZE + IPX_NODE_SIZE); memcpy(i->sock, &so->sipx_port, 2); } -static void ipx2sockadr(struct sockaddr_ipx *so, ipxAddr_t *i) +void ipx2sockadr(struct sockaddr_ipx *so, ipxAddr_t *i) { memcpy(&so->sipx_network, i->net, IPX_NET_SIZE + IPX_NODE_SIZE); memcpy(&so->sipx_port, i->sock, 2); @@ -79,241 +67,6 @@ void set_emu_tli() if (i > -1) locipxdebug = i; } -static int x_ioctl(int sock, int mode, void *id) -{ - int result; - int i = 0; - do { - result = ioctl(sock, mode, id); - i++; - } while ((i < 5) && (result < 0) && (errno == EAGAIN)); - return(result); -} - - -static void del_special_net(int special, char *devname, int frame) -/* specials = */ -/* IPX_SPECIAL_NONE */ -/* IPX_INTERNAL */ -/* IPX_PRIMARY */ -/* devname + frame only if not IPX_INTERNAL */ -{ - int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (sock > -1) { - struct ifreq id; - struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr; - memset(&id, 0, sizeof(struct ifreq)); - - sipx->sipx_network = 0L; - sipx->sipx_special = special; - sipx->sipx_family = AF_IPX; - if (special == IPX_PRIMARY) { - FILE *f=fopen("/proc/net/ipx_interface", "r"); - if (f) { - char buff[200]; - char buff1[200]; - char buff2[200]; - char buff3[200]; - char buff4[200]; - char buff5[200]; - while (fgets((char*)buff, sizeof(buff), f) != NULL){ - if (sscanf(buff, "%s %s %s %s %s", - buff1, buff2, buff3, buff4, buff5) == 5) { - int len = strlen(buff5); - if (!len) continue; - switch (*(buff5+len-1)) { - case '2' : sipx->sipx_type = IPX_FRAME_8022; break; - case '3' : sipx->sipx_type = IPX_FRAME_8023; break; - case 'P' : sipx->sipx_type = IPX_FRAME_SNAP; break; - case 'I' : sipx->sipx_type = IPX_FRAME_ETHERII; break; - default : continue; - } - upstr(buff3); - if (!strcmp(buff3, "YES")) { /* primary */ - strcpy(id.ifr_name, buff4); - break; - } - } - } - fclose(f); - } - } else if (special != IPX_INTERNAL) { - if (devname && *devname) strcpy(id.ifr_name, devname); - sipx->sipx_type = frame; - } - sipx->sipx_action = IPX_DLTITF; - x_ioctl(sock, SIOCSIFADDR, &id); - close(sock); - } -} - -#define del_internal_net() \ - del_special_net(IPX_INTERNAL, NULL, 0) -#define del_interface(devname, frame) \ - del_special_net(IPX_SPECIAL_NONE, (devname), (frame)) -#define del_primary_net() \ - del_special_net(IPX_PRIMARY, NULL, 0) - -static void add_special_net(int special, - char *devname, int frame, uint32 netnum, uint32 node) -{ - int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (sock > -1) { - struct ifreq id; - struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr; - memset(&id, 0, sizeof(struct ifreq)); - if (special != IPX_INTERNAL){ - if (devname && *devname) strcpy(id.ifr_name, devname); - sipx->sipx_type = frame; - } else { - uint32 xx=htonl(node); - memcpy(sipx->sipx_node+2, &xx, 4); - } - sipx->sipx_network = htonl(netnum); - sipx->sipx_special = special; - sipx->sipx_family = AF_IPX; - sipx->sipx_action = IPX_CRTITF; - x_ioctl(sock, SIOCSIFADDR, &id); - close(sock); - } -} -#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 init_ipx(uint32 network, uint32 node, int ipx_debug) -{ - int result=-1; - int sock=sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (socket < 0) { - errorp(1, "EMUTLI:init_ipx", NULL); - exit(1); - } else { - set_sock_debug(sock); - result=0; - /* makes new internal net */ - if (network) { - struct sockaddr_ipx ipxs; - memset((char*)&ipxs, 0, sizeof(struct sockaddr_ipx)); - ipxs.sipx_port = htons(SOCK_NCP); - ipxs.sipx_family = AF_IPX; - if (bind(sock, (struct sockaddr*)&ipxs, - sizeof(struct sockaddr_ipx))==-1) { - if (errno == EEXIST || errno == EADDRINUSE) result = -1; - } else result =-1; - close(sock); - if (result) { - errorp(1, "EMUTLI:init_ipx socket 0x451", NULL); - exit(1); - } - del_internal_net(); - add_internal_net(network, node); - have_ipx_started++; - } else { - close(sock); - } - } - return(result); -} - -void exit_ipx(int full) -{ - int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (sock > -1) { - /* Switch DEBUG off */ - locipxdebug = 0; - set_sock_debug(sock); - close(sock); - } - if (have_ipx_started && full) del_internal_net(); -} - -int init_dev(char *devname, int frame, uint32 network) -{ - if (!network) return(0); - del_interface(devname, frame); - if (!have_ipx_started) { - have_ipx_started++; - del_primary_net(); - add_primary_net(devname, frame, network); - } else - add_device_net(devname, frame, network); - return(0); -} - -void exit_dev(char *devname, int frame) -{ - del_interface(devname, frame); -} - -void ipx_route_add(uint32 dest_net, - uint32 route_net, - uint8 *route_node) -{ - struct rtentry rd; - int result; - int sock; - /* Router */ - struct sockaddr_ipx *sr = (struct sockaddr_ipx *)&rd.rt_gateway; - /* Target */ - struct sockaddr_ipx *st = (struct sockaddr_ipx *)&rd.rt_dst; - - rd.rt_flags = RTF_GATEWAY; - - st->sipx_network = htonl(dest_net); - sr->sipx_network = htonl(route_net); - memcpy(sr->sipx_node, route_node, IPX_NODE_SIZE); - - if ( (sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX)) < 0){ - errorp(0, "EMUTLI:ipx_route_add", NULL); - return; - } - sr->sipx_family = st->sipx_family = AF_IPX; - - if ( 0 != (result = x_ioctl(sock, SIOCADDRT, &rd))) { - switch (errno) { - case ENETUNREACH: - errorp(0, "ROUTE ADD", "Router network (%08X) not reachable.\n", - htonl(sr->sipx_network)); - break; - - case EEXIST: - case EADDRINUSE: - break; - - default: - errorp(0, "ROUTE ADD", NULL); - break; - } - } - close(sock); -} - -void ipx_route_del(uint32 net) -{ - struct rtentry rd; - int sock; - /* Router */ - struct sockaddr_ipx *sr = (struct sockaddr_ipx *)&rd.rt_gateway; - /* Target */ - struct sockaddr_ipx *st = (struct sockaddr_ipx *)&rd.rt_dst; - rd.rt_flags = RTF_GATEWAY; - st->sipx_network = htonl(net); - if ( (sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX)) < 0){ - errorp(0, "EMUTLI:ipx_route_del", NULL); - return; - } - sr->sipx_family = st->sipx_family = AF_IPX; - x_ioctl(sock, SIOCDELRT, &rd); - close(sock); -} - - int t_open(char *name, int open_mode, char * p) { int opt=1; @@ -421,8 +174,8 @@ int poll( struct pollfd *fds, unsigned long nfds, int timeout) p = fds; while (k--){ if (p->fd > -1 && FD_ISSET(p->fd, &readfs)){ - p->revents = POLLIN; - if (! --rest) break; /* ready */ + p->revents = POLLIN; + if (! --rest) break; /* ready */ } p++; } @@ -506,7 +259,7 @@ int t_sndudata(int fd, struct t_unitdata *ud) 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)); + ud->udata.len, 0, (struct sockaddr *) &ipxs, sizeof(ipxs)); #if HAVE_IPX_SEND_BUG alarm(0); diff --git a/emutli.h b/emutli.h index 547aaba..6049e45 100644 --- a/emutli.h +++ b/emutli.h @@ -1,4 +1,4 @@ -/* emutli.h 30-Jan-96 */ +/* emutli.h 28-Apr-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * @@ -92,6 +92,12 @@ struct pollfd { #define TOUTSTATE 6 /* out of state */ +extern void set_locipxdebug(int debug); +extern void set_sock_debug(int sock); +extern void sock2ipxadr(ipxAddr_t *i, struct sockaddr_ipx *so); +extern void ipx2sockadr(struct sockaddr_ipx *so, ipxAddr_t *i); +extern void set_emu_tli(void); + extern int poll(struct pollfd *fds, unsigned long nfds, int timeout); extern int t_open(char *name, int open_mode, char *p); extern int t_bind(int sock, struct t_bind *a_in, struct t_bind *a_out); @@ -103,39 +109,21 @@ extern int t_rcvuderr(int fd, struct t_uderr *ud); extern int t_sndudata(int fd, struct t_unitdata *ud); -extern int init_ipx(uint32 network, uint32 node, int ipx_debug); -extern void exit_ipx(int full); - -extern int init_dev(char *devname, int frame, uint32 network); -extern void exit_dev(char *devname, int frame); - -#if 0 -extern int get_ipx_addr(ipxAddr_t *addr); -#endif - -extern void ipx_route_add(uint32 dest_net, - uint32 route_net, - uint8 *route_node); - -extern void ipx_route_del(uint32 net); - -extern void set_emu_tli(void); - #ifndef IPX_FRAME_8022 -#define OLD_KERNEL_IPX 1 -#define IPX_FRAME_8022 IPX_RT_8022 +# define OLD_KERNEL_IPX 1 +# define IPX_FRAME_8022 IPX_RT_8022 #endif #ifndef IPX_FRAME_8023 -#define IPX_FRAME_8023 0 +# define IPX_FRAME_8023 0 #endif #ifndef IPX_FRAME_SNAP -#define IPX_FRAME_SNAP IPX_RT_SNAP +# define IPX_FRAME_SNAP IPX_RT_SNAP #endif #ifndef IPX_FRAME_ETHERII -#define IPX_FRAME_ETHERII IPX_RT_BLUEBOOK +# define IPX_FRAME_ETHERII IPX_RT_BLUEBOOK #endif #endif diff --git a/emutli1.c b/emutli1.c new file mode 100644 index 0000000..7710716 --- /dev/null +++ b/emutli1.c @@ -0,0 +1,391 @@ +/* emutli1.c 28-Apr-96 */ +/* + * One short try to emulate TLI with SOCKETS. + */ + +/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * Some of the Code in this module is stolen from the following + * Programms: ipx_interface, ipx_route, ipx_configure, which were + * written by Greg Page, Caldera, Inc. + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ +#include +#include +#include +#include +#include +#include +#include +#include "net.h" +#include +#include +#include +#include +#include +#include + +static int have_ipx_started=0; +static int auto_interfaces=0; +static int org_auto_interfaces=0; + +static int x_ioctl(int sock, int mode, void *id) +{ + int result; + int i = 0; + do { + result = ioctl(sock, mode, id); + i++; + } while ((i < 5) && (result < 0) && (errno == EAGAIN)); + return(result); +} + +static int interface_data(uint8* data, uint32 *rnet, uint8 *node, + int *flags, uint8 *name) + +/* returns frame or if error < 0 */ +{ + uint32 snet; + int frame=-1; + int xflags =0; + uint8 buff1[200]; + uint8 buff2[200]; + uint8 buff3[200]; + uint8 buff4[200]; + if (!rnet) rnet =&snet; + if (!flags) flags=&xflags; + else *flags=0; + if (sscanf(data, "%lx %s %s %s %s", + rnet, buff1, buff2, buff3, buff4) == 5 ) { + int len = strlen(buff4); + if (!len) return(-1); + switch (*(buff4+len-1)) { + case '2' : frame = IPX_FRAME_8022; break; + case '3' : frame = IPX_FRAME_8023; break; + case 'P' : frame = IPX_FRAME_SNAP; break; + case 'I' : frame = IPX_FRAME_ETHERII; break; +#ifdef IPX_FRAME_TR_8022 + case 'R' : frame = IPX_FRAME_TR_8022; break; +#endif + default : return(-2); + } + if (node) strmaxcpy(node, buff1, 12); + + upstr(buff2); + if (!strcmp(buff2, "YES")) /* primary */ + *flags |= 1; + + if (name) strmaxcpy(name, buff3, 20); + upstr(buff3); + if (!strcmp(buff2, "INTERNAL")) /* internal net */ + *flags |= 2; + + } + return(frame); +} + +int get_interface_frame_name(char *name, uint32 net) +/* returns frame and name of Device of net */ +{ + int frame = -1; + FILE *f=fopen("/proc/net/ipx_interface", "r"); + if (f) { + char buff[200]; + while (fgets((char*)buff, sizeof(buff), f) != NULL){ + uint32 rnet; + uint8 dname[25]; + int fframe = interface_data((uint8*) buff, &rnet, NULL, NULL, dname); + if (fframe < 0) continue; + if (rnet == net) { + if (name) strcpy(name, dname); + frame = fframe; + break; + } + } + fclose(f); + } + return(frame); +} + +static void del_special_net(int special, char *devname, int frame) +/* specials = */ +/* IPX_SPECIAL_NONE */ +/* IPX_INTERNAL */ +/* IPX_PRIMARY */ +/* devname + frame only if not IPX_INTERNAL */ +{ + int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX); + if (sock > -1) { + struct ifreq id; + struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr; + memset(&id, 0, sizeof(struct ifreq)); + + sipx->sipx_network = 0L; + sipx->sipx_special = special; + sipx->sipx_family = AF_IPX; + if (special == IPX_PRIMARY) { + FILE *f=fopen("/proc/net/ipx_interface", "r"); + if (f) { + char buff[200]; + uint8 name[25]; + while (fgets((char*)buff, sizeof(buff), f) != NULL){ + int flags = 0; + int frame = interface_data((uint8*) buff, NULL, NULL, + &flags, name); + if (frame < 0) continue; + sipx->sipx_type = frame; + if (flags & 1) { /* primary */ + strcpy(id.ifr_name, name); + break; + } + } + fclose(f); + } + } else if (special != IPX_INTERNAL) { + if (devname && *devname) strcpy(id.ifr_name, devname); + sipx->sipx_type = frame; + } + sipx->sipx_action = IPX_DLTITF; + x_ioctl(sock, SIOCSIFADDR, &id); + close(sock); + } +} + +#define del_internal_net() \ + del_special_net(IPX_INTERNAL, NULL, 0) +#define del_interface(devname, frame) \ + del_special_net(IPX_SPECIAL_NONE, (devname), (frame)) +#define del_primary_net() \ + del_special_net(IPX_PRIMARY, NULL, 0) + +static int add_special_net(int special, + char *devname, int frame, uint32 netnum, uint32 node) +{ + int result = -1; + int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX); + if (sock > -1) { + struct ifreq id; + struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr; + memset(&id, 0, sizeof(struct ifreq)); + if (special != IPX_INTERNAL){ + if (devname && *devname) strcpy(id.ifr_name, devname); + sipx->sipx_type = frame; + } else { + uint32 xx=htonl(node); + memcpy(sipx->sipx_node+2, &xx, 4); + } + sipx->sipx_network = htonl(netnum); + sipx->sipx_special = special; + sipx->sipx_family = AF_IPX; + sipx->sipx_action = IPX_CRTITF; + result = x_ioctl(sock, SIOCSIFADDR, &id); + close(sock); + } + return(result); +} +#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 get_frame_name(uint8 *framename, int frame) +{ + char *frname=0; + switch (frame) { + case -1 : frname = "AUTO"; break; +#ifdef IPX_FRAME_TR_8022 + case IPX_FRAME_TR_8022 : frname = "TOKEN"; break; +#endif + case IPX_FRAME_8022 : frname = "802.2"; break; + case IPX_FRAME_8023 : frname = "802.3"; break; + case IPX_FRAME_SNAP : frname = "SNAP"; break; + case IPX_FRAME_ETHERII : frname = "ETHERNET_II";break; + default : framename[0] = '\0'; + return(-1); + } /* switch */ + strcpy(framename, frname); + return(0); +} + +int init_ipx(uint32 network, uint32 node, int ipx_debug) +{ + int result=-1; + int sock; +#if INTERNAL_RIP_SAP +# ifdef CONFIG_IPX_INTERN + errorp(11, "!! configuration error !!", + "mars_nwe don't run with kernel 'full internal net'.\n" + "Change kernel option CONFIG_IPX_INTERN=NO (nobody needs it)\n" + "or use 'ipxd' and change mars_nwe INTERNAL_RIP_SAP=0."); + exit(1); +# endif +#endif + if ((sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX)) < 0) { + errorp(1, "EMUTLI:init_ipx", NULL); + exit(1); + } else { + ipx_config_data cfgdata; + ioctl(sock, SIOCIPXCFGDATA, &cfgdata); + org_auto_interfaces = + auto_interfaces = cfgdata.ipxcfg_auto_create_interfaces; + set_sock_debug(sock); + result=0; + /* makes new internal net */ + if (network) { + struct sockaddr_ipx ipxs; + memset((char*)&ipxs, 0, sizeof(struct sockaddr_ipx)); + ipxs.sipx_port = htons(SOCK_NCP); + ipxs.sipx_family = AF_IPX; + if (bind(sock, (struct sockaddr*)&ipxs, + sizeof(struct sockaddr_ipx))==-1) { + if (errno == EEXIST || errno == EADDRINUSE) result = -1; + } + if (result) { + errorp(1, "EMUTLI:init_ipx socket 0x451", NULL); + exit(1); + } + del_internal_net(); + add_internal_net(network, node); + have_ipx_started++; + } + close(sock); + } + return(result); +} + +void exit_ipx(int full) +{ + int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX); + if (sock > -1) { + /* Switch DEBUG off */ + set_locipxdebug(0); + set_sock_debug(sock); +#if 1 + if (have_ipx_started && full) org_auto_interfaces = 0; +#endif + if (auto_interfaces != org_auto_interfaces) + ioctl(sock, SIOCAIPXITFCRT, &org_auto_interfaces); + close(sock); + } + if (have_ipx_started && full) del_internal_net(); +} + +int init_dev(char *devname, int frame, uint32 network) +{ + int is_auto = (!network || frame < 0 || devname[0] == '*'); + if (frame > -1 && devname[0] != '*') del_interface(devname, frame); + if (!have_ipx_started) { + if (is_auto) return(-99); + have_ipx_started++; + del_primary_net(); + add_primary_net(devname, frame, network); + } else { + if (!is_auto) + return(add_device_net(devname, frame, network)); + else if (!auto_interfaces) { + int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX); + if (sock < 0) return(-2); + auto_interfaces = 1; + if (ioctl(sock, SIOCAIPXITFCRT, &auto_interfaces) < 0) { + close(sock); + return(-3); + } + close(sock); + } + return(1); + } + return(0); +} + +void exit_dev(char *devname, int frame) +{ + del_interface(devname, frame); +} + +void ipx_route_add(uint32 dest_net, + uint32 route_net, + uint8 *route_node) +{ + struct rtentry rd; + int result; + int sock; + /* Router */ + struct sockaddr_ipx *sr = (struct sockaddr_ipx *)&rd.rt_gateway; + /* Target */ + struct sockaddr_ipx *st = (struct sockaddr_ipx *)&rd.rt_dst; + + rd.rt_flags = RTF_GATEWAY; + + st->sipx_network = htonl(dest_net); + sr->sipx_network = htonl(route_net); + + if (route_node) + memcpy(sr->sipx_node, route_node, IPX_NODE_SIZE); + else + memset(sr->sipx_node, 0, IPX_NODE_SIZE); + + if ( (sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX)) < 0){ + errorp(0, "EMUTLI:ipx_route_add", NULL); + return; + } + sr->sipx_family = st->sipx_family = AF_IPX; + + if ( 0 != (result = x_ioctl(sock, SIOCADDRT, &rd))) { + switch (errno) { + case ENETUNREACH: + errorp(0, "ROUTE ADD", "Router network (%08X) not reachable.\n", + htonl(sr->sipx_network)); + break; + + case EEXIST: + case EADDRINUSE: + break; + + default: + errorp(0, "ROUTE ADD", NULL); + break; + } + } + close(sock); +} + +void ipx_route_del(uint32 net) +{ + struct rtentry rd; + int sock; + /* Router */ + struct sockaddr_ipx *sr = (struct sockaddr_ipx *)&rd.rt_gateway; + /* Target */ + struct sockaddr_ipx *st = (struct sockaddr_ipx *)&rd.rt_dst; + rd.rt_flags = RTF_GATEWAY; + st->sipx_network = htonl(net); + if ( (sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX)) < 0){ + errorp(0, "EMUTLI:ipx_route_del", NULL); + return; + } + sr->sipx_family = st->sipx_family = AF_IPX; + x_ioctl(sock, SIOCDELRT, &rd); + close(sock); +} diff --git a/emutli1.h b/emutli1.h new file mode 100644 index 0000000..ebdae9c --- /dev/null +++ b/emutli1.h @@ -0,0 +1,40 @@ +/* emutli1.h 28-Apr-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. + */ + +#ifndef _EMUTLI1_H_ +#define _EMUTLI1_H_ + +extern void set_locipxdebug(int debug); +extern int get_interface_frame_name(char *name, uint32 net); +extern int get_frame_name(uint8 *framename, int frame); +extern int init_ipx(uint32 network, uint32 node, int ipx_debug); +extern void exit_ipx(int full); +extern int init_dev(char *devname, int frame, uint32 network); +extern void exit_dev(char *devname, int frame); + +#if 0 +extern int get_ipx_addr(ipxAddr_t *addr); +#endif + +extern void ipx_route_add(uint32 dest_net, + uint32 route_net, + uint8 *route_node); + +extern void ipx_route_del(uint32 net); +#endif diff --git a/examples/README.kpatch1.2.13 b/examples/README.kpatch1.2.13 new file mode 100644 index 0000000..ed93fdd --- /dev/null +++ b/examples/README.kpatch1.2.13 @@ -0,0 +1,7 @@ +This is the kernel-ipx patch for the 1.2.13 kernel. +If you have problems with mars_nwe or if you want to +speed up mars_nwe with kernel 1.2.13 you should apply +this patch to kernel 1.2.13 + +Martin + diff --git a/examples/README.kpatch1.3.72 b/examples/README.kpatch1.3.7x similarity index 84% rename from examples/README.kpatch1.3.72 rename to examples/README.kpatch1.3.7x index 9b2a2ac..aa7dbff 100644 --- a/examples/README.kpatch1.3.72 +++ b/examples/README.kpatch1.3.7x @@ -1,4 +1,6 @@ -The kernelpatch kpatch1.3.72 you can use directly for kernels 1.3.72 .. ??? +The kernelpatch kpatch1.3.72 you can use directly for kernels 1.3.72 .. 1.3.77 +The kernelpatch kpatch1.3.78 you can use directly for kernels 1.3.78,79 .. ?? + but it should be easy to apply this patch to all kernels. By older kernels 'sk->protinfo.af_ipx.' must become 'sk->' . After applying this patch please rebuild mars_nwe (make clean) diff --git a/examples/config.h b/examples/config.h index 48977c8..513cb82 100644 --- a/examples/config.h +++ b/examples/config.h @@ -1,8 +1,8 @@ -/* config.h: 14-Mar-96 */ +/* config.h: 03-May-96 */ /* some of this config is needed by make, others by cc */ #define DO_DEBUG 1 /* Compile in debug code */ -#define DO_TESTING 0 +#define DO_TESTING 0 /* only for the next choose */ #if DO_TESTING # define FILENAME_NW_INI "./nw.ini" /* full name of ini (conf) file */ # define PATHNAME_PROGS "." /* path location of progs */ @@ -14,30 +14,44 @@ # define PATHNAME_BINDERY "/etc" /* path location of bindery */ # define FUNC_17_02_IS_DEBUG 0 #endif +#define PATHNAME_PIDFILES "/var/run" /* path location of 'pidfiles' */ + +/* next for utmp/wtmp updates */ +#define FILENAME_UTMP UTMP_FILE +/* can be set NULL if you don't want utmp/wtmp updates */ +#define FILENAME_WTMP WTMP_FILE +/* can be set NULL if you don't want wtmp updates */ #define NETWORK_SERIAL_NMBR 0x44444444L /* Serial Number 4 Byte */ #define NETWORK_APPL_NMBR 0x2222 /* Applikation Number 2 Byte */ -#define MAX_CONNECTIONS 5 /* max. Number of Connections */ +#define MAX_CONNECTIONS 5 /* max. Number of Connections */ /* must be < 256 !!! */ -#define MAX_NW_VOLS 10 /* max. Volumes */ -#define IPX_DATA_GR_546 1 /* allow ipx packets > 546+30 Byte */ -#define WITH_NAME_SPACE_CALLS 0 /* Namespace Calls are only minimal */ +#define IPX_DATA_GR_546 1 /* allow ipx packets > 546+30 Byte */ + +/* <-----------------------------------------------------------> */ +#define MAX_NW_VOLS 10 /* max. Volumes */ +#define MAX_FILE_HANDLES_CONN 80 /* max. open files /connection */ + +/* <--------------- new namespace services call --------------> */ +#define WITH_NAME_SPACE_CALLS 1 /* Namespace Calls are only minimal */ /* supported till now. */ /* to enable testing of them this */ /* entry must be changed to '1' and */ /* entry '6' in ini file must be set */ /* to > '0', too. */ - +#define MAX_DIR_BASE_ENTRIES 50 /* max. cached base entries/connection */ +/* <-----------------------------------------------------------> */ #define MAX_NW_SERVERS 40 /* max. count of servers */ /* <--------------- next is for linux only -------------------> */ #define INTERNAL_RIP_SAP 1 /* use internal/own rip/sap routines */ +/* -------------------- */ #define MAX_NET_DEVICES 5 /* max. Netdevices, frames */ #define MAX_NW_ROUTES 50 /* max. networks (internal + external) */ - -/* this is for very special use of mars_nwe to only act as a router */ -#define FILE_SERVER_INACTIV 0 /* 1 = don't start ncpserv */ +#define MAX_RIP_ENTRIES 50 /* max. rip responses */ +/* -------------------- */ +#define SHADOW_PWD 0 /* change to '1' for shadow passwds */ diff --git a/examples/kpatch1.2.13 b/examples/kpatch1.2.13 new file mode 100644 index 0000000..deb910e --- /dev/null +++ b/examples/kpatch1.2.13 @@ -0,0 +1,122 @@ +Index: include/linux/ipx.h +--- linux.org/include/linux/ipx.h Mon Feb 6 19:25:22 1995 ++++ linux/include/linux/ipx.h Fri Mar 22 00:58:02 1996 +@@ -74,5 +74,6 @@ + #define SIOCAIPXITFCRT (SIOCPROTOPRIVATE) + #define SIOCAIPXPRISLT (SIOCPROTOPRIVATE+1) + #define SIOCIPXCFGDATA (SIOCPROTOPRIVATE+2) ++#define SIOCIPXNCPCONN (SIOCPROTOPRIVATE+3) + #endif + +Index: net/inet/ipx.c +--- linux.org/net/inet/ipx.c Tue Apr 18 21:13:26 1995 ++++ linux/net/inet/ipx.c Fri Mar 22 01:25:25 1996 +@@ -341,6 +341,20 @@ + struct sk_buff *skb1 = NULL, *skb2 = NULL; + int ipx_offset; + ++ if (intrfc == ipx_primary_net ++ && ntohs(ipx->ipx_dest.sock) == 0x451 ++ && *((char*)(ipx+1)) == 0x22 ++ && *((char*)(ipx+1)+1) == 0x22) { ++ int connection = (int) *((char*)(ipx+1)+3); ++ /* 255 connections are enough ;) */ ++ if (connection) { ++ for (sock1=intrfc->if_sklist; ++ (sock1 != NULL) && ++ (sock1->ipx_ncp_conn != connection); ++ sock1=sock1->next);; ++ } ++ } ++ if (sock1 == NULL) + sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock); + + /* +@@ -859,6 +873,7 @@ + ipxif=ipxitf_find_using_phys(dev, ipx_map_frame_type(sipx->sipx_type)); + if(ipxif==NULL) + return -EADDRNOTAVAIL; ++ sipx->sipx_family=AF_IPX; + sipx->sipx_network=ipxif->if_netnum; + memcpy(sipx->sipx_node, ipxif->if_node, sizeof(sipx->sipx_node)); + memcpy_tofs(arg,&ifr,sizeof(ifr)); +@@ -909,7 +924,8 @@ + return -EAGAIN; + rt->ir_next=ipx_routes; + ipx_routes=rt; +- } ++ } else if (intrfc == ipx_internal_net) ++ return(-EEXIST); /* fix for mars_nwe: 11-Jan-96 */ + + rt->ir_net = network; + rt->ir_intrfc = intrfc; +@@ -983,6 +999,7 @@ + int size; + int ipx_offset; + ipx_route *rt = NULL; ++ int snr; + + /* Find the appropriate interface on which to send packet */ + if ((usipx->sipx_network == 0L) && (ipx_primary_net != NULL)) { +@@ -1017,9 +1034,14 @@ + ipx->ipx_tctrl=0; + ipx->ipx_type=usipx->sipx_type; + skb->h.raw = (unsigned char *)ipx; +- ++ if ((snr=ntohs(sk->ipx_port)) == 0x453 || snr == 0x452) { ++ /* RIP/SAP speicial handling for mars_nwe: 11-Jan-96 */ ++ ipx->ipx_source.net = intrfc->if_netnum; ++ memcpy(ipx->ipx_source.node, intrfc->if_node, IPX_NODE_LEN); ++ } else { + ipx->ipx_source.net = sk->ipx_intrfc->if_netnum; + memcpy(ipx->ipx_source.node, sk->ipx_intrfc->if_node, IPX_NODE_LEN); ++ } + ipx->ipx_source.sock = sk->ipx_port; + ipx->ipx_dest.net=usipx->sipx_network; + memcpy(ipx->ipx_dest.node,usipx->sipx_node,IPX_NODE_LEN); +@@ -1335,6 +1357,7 @@ + return err; + put_fs_long(sizeof(int),(unsigned long *)optlen); + err=verify_area(VERIFY_WRITE,optval,sizeof(int)); ++ if (err) return err; + put_fs_long(val,(unsigned long *)optval); + return(0); + } +@@ -1397,6 +1420,8 @@ + sk->debug=0; + sk->ipx_intrfc = NULL; + memset(&sk->ipx_dest_addr,'\0',sizeof(sk->ipx_dest_addr)); ++ sk->ipx_ncp_conn = 0; /* no ncp socket yet */ ++ + sk->ipx_port = 0; + sk->mtu=IPX_MTU; + +@@ -1835,6 +1860,16 @@ + if(err) return err; + return(ipxcfg_get_config_data((void *)arg)); + } ++ case SIOCIPXNCPCONN: ++ { ++ if (!suser()) return(-EPERM); ++ err = verify_area(VERIFY_READ, (void *)arg, ++ sizeof(unsigned short)); ++ if (err) return err; ++ sk->ipx_ncp_conn = get_fs_word(arg); ++ return 0; ++ } ++ + case SIOCGSTAMP: + if (sk) + { +Index: net/inet/sock.h +Prereq: 1.0.4 +--- linux.org/net/inet/sock.h Fri Mar 22 01:11:28 1996 ++++ linux/net/inet/sock.h Fri Mar 22 01:12:26 1996 +@@ -146,6 +146,7 @@ + ipx_interface *ipx_intrfc; + unsigned short ipx_port; + unsigned short ipx_type; ++ unsigned short ipx_ncp_conn; + #endif + #ifdef CONFIG_AX25 + /* Really we want to add a per protocol private area */ diff --git a/examples/kpatch1.3.78 b/examples/kpatch1.3.78 new file mode 100644 index 0000000..34bbb5a --- /dev/null +++ b/examples/kpatch1.3.78 @@ -0,0 +1,74 @@ +diff -rub linux.org/include/linux/ipx.h linux/include/linux/ipx.h +--- linux.org/include/linux/ipx.h Wed Mar 27 18:43:19 1996 ++++ linux/include/linux/ipx.h Thu Mar 28 11:15:31 1996 +@@ -74,5 +74,6 @@ + #define SIOCAIPXITFCRT (SIOCPROTOPRIVATE) + #define SIOCAIPXPRISLT (SIOCPROTOPRIVATE+1) + #define SIOCIPXCFGDATA (SIOCPROTOPRIVATE+2) ++#define SIOCIPXNCPCONN (SIOCPROTOPRIVATE+3) + #endif + +diff -rub linux.org/include/net/sock.h linux/include/net/sock.h +--- linux.org/include/net/sock.h Wed Mar 27 23:05:18 1996 ++++ linux/include/net/sock.h Thu Mar 28 11:15:31 1996 +@@ -112,6 +112,10 @@ + * know the connection this socket belongs to. + */ + struct ncp_server *ncp_server; ++/* ++ * To handle special NCP-Sockets for mars_nwe ++ */ ++ unsigned short ipx_ncp_conn; + + }; + #endif +diff -rub linux.org/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c +--- linux.org/net/ipx/af_ipx.c Wed Mar 27 17:50:39 1996 ++++ linux/net/ipx/af_ipx.c Thu Mar 28 11:15:31 1996 +@@ -448,6 +448,20 @@ + ipx_socket *sock1 = NULL, *sock2 = NULL; + struct sk_buff *skb1 = NULL, *skb2 = NULL; + ++ if (intrfc == ipx_primary_net ++ && ntohs(ipx->ipx_dest.sock) == 0x451 ++ && *((char*)(ipx+1)) == 0x22 ++ && *((char*)(ipx+1)+1) == 0x22) { ++ int connection = (int) *((char*)(ipx+1)+3); ++ /* 255 connections are enough ;) */ ++ if (connection) { ++ for (sock1=intrfc->if_sklist; ++ (sock1 != NULL) && ++ (sock1->protinfo.af_ipx.ipx_ncp_conn != connection); ++ sock1=sock1->next);; ++ } ++ } ++ if (sock1 == NULL) + sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock); + + /* +@@ -1639,6 +1653,7 @@ + sizeof(sk->protinfo.af_ipx.dest_addr)); + sk->protinfo.af_ipx.port = 0; + sk->protinfo.af_ipx.ncp_server = 0; ++ sk->protinfo.af_ipx.ipx_ncp_conn = 0; /* no ncp socket yet */ + sk->mtu=IPX_MTU; + + if(sock!=NULL) +@@ -2142,6 +2157,17 @@ + if(err) return err; + return(ipxcfg_get_config_data((void *)arg)); + } ++ ++ case SIOCIPXNCPCONN: ++ { ++ if (!suser()) return(-EPERM); ++ err = verify_area(VERIFY_READ, (void *)arg, ++ sizeof(unsigned short)); ++ if (err) return err; ++ sk->protinfo.af_ipx.ipx_ncp_conn = get_fs_word(arg); ++ return 0; ++ } ++ + case SIOCGSTAMP: + if (sk) + { diff --git a/examples/mk.li b/examples/mk.li index 4732dc0..88dce0e 100755 --- a/examples/mk.li +++ b/examples/mk.li @@ -1,5 +1,5 @@ #!/bin/sh -# mk.li 10-Feb-96 ### +# mk.li 27-Apr-96 ### # please edit this file ! mk() @@ -11,7 +11,7 @@ mk() if [ ! -d $OBJDIR ] ; then mkdir $OBJDIR; fi cd $OBJDIR; fi - $MAKE -f $V_VPATH/makefile.unx $@ 2>&1 | tee $ERRFILE; + if $MAKE -f $V_VPATH/makefile.unx $@ 2>&1;then true;else kill -HUP $MK_PPID;fi | tee $ERRFILE if [ $V_VPATH = '..' ] ; then cd ..; fi @@ -20,6 +20,9 @@ mk() TOLOWER='tr "[A-Z]" "[a-z]"' UNX=`uname -s | $TOLOWER` +MK_PPID=$$ +export MK_PPID +trap 'echo "Error: Try again :)" && exit 1' 1 case $UNX in linux) diff --git a/examples/nw.ini b/examples/nw.ini index 55eb533..1bfb9bb 100644 --- a/examples/nw.ini +++ b/examples/nw.ini @@ -1,27 +1,42 @@ # (C)opyright 1993, 1996, Martin Stover, Softwareentwicklung, Marburg -# last change: 08-Mar-96 +# last change: 28-Apr-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. volumes depend on your config.h) # Volumename Volumepath Options (k=lowercase,p=pipe,m=removable) 1 SYS /u3/SYS/ # SYS 1 +# SYS, der Name darf auch anders lauten, muss +# eingerichtet sein mit den folgenden Verzeichnissen: +# LOGIN, PUBLIC, SYSTEM, MAIL. +# SYS, may be named diffent but must be setup and must +# contains the following Directories: LOGIN, PUBLIC, SYSTEM, MAIL #################################### # Die folgenden Volumes sind optional. # the following volumes are optional. +#1 HOME ~ k # Users HOME directory +#.............^^^ +# such a 'path' (~) stands for users home dir +# this is an automatic changed volume. #1 SYS1 /u3/SYS1/ # SYS 2 upshift #1 TMP /tmp/ k # TMP downshift #1 CD /cdrom km # CDROM downshift/removable #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 -# eingerichtet sein mit den folgenden Verzeichnissen: -# LOGIN, PUBLIC, SYSTEM, MAIL. -# SYS, may be named diffent but must be setup and must -# contains the following Directories: LOGIN, PUBLIC, SYSTEM, MAIL +# all flags for volumes: +# 'k' all is downshift +# 'm' volume is moveable (cdrom) +# 'o' volume has only one filesystem/device/namespace +# this is for filesystems with high inode > 0xFFFFFFF. +# because for namespace services mars_nwe normally use the +# first 4 bit of 32 bit inode for distinguish +# between several devices/namespaces for one volume. +# 'p' 'PIPE' filesystem. All files are pipe commands. +# see 'doc/PIPE-FS' ###################################### # Eintrag 2 fuer den Servername. # falls nicht gesetzt, wird hostname (in GROSSBUCHSTABEN) verwendet. @@ -31,19 +46,32 @@ ###################################### # next entry for configure mars_nwe to use the internal net # If you have mars_nwe V > 0.96pl5 and a kernel >= 1.3.60 -# or the small ipx-kpatch from the examples dir you can use +# or the small ipx-kpatch from the examples dir you should use # internal net and routing. -# INTERNAL NET [NODE] -#3 0x999999 1 # Node default 1 +# NOTE: the internal NET Number must be UNIQUE +# in your IPX-environment. ! +# INTERNAL NET [NODE] (default 1) +3 0xABCDEF99 1 # Net Number must be unique. ###################################### # 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) +# NOTE for people with other IPX/NCP servers on the net: +# Your network numbers, frames must be the same as at your +# other servers on the same net. +# You also may choose a network number = '0', device = '*' +# and frame = 'auto' for autosetup of devices. +# +# NETWORK NUMBER, DEVICE, Frame-Typ TICKS (default 1) 4 0x10 eth0 802.3 1 +4 0x0 * AUTO 1 # autosetup all devices +# ^^^^...........^^^....^^^^^^^ +# NOTE: autosetup can only be choosen if you have other +# IXP/NCP servers on the same net which are setup correctly. +###### #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) +#4 0x66 tr0 token 1 +# Frames=ethernet_ii, 802.2, 802.3, snap, token, auto, (default 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 @@ -106,9 +134,10 @@ 103 0 # debug NWCONN 104 0 # debug (start) NWCLIENT 105 0 # debug NWBIND +106 1 # debug NWROUTED ############################# -200 1 # 0 = no logfile and dont daemonize nwserv -# # 1 = daemonize nwserv and use logfile +200 1 # 0 = no logfile and dont daemonize nwserv/nwrouted +# # 1 = daemonize nwserv/nwrouted and use logfile 201 /tmp/nw.log # logfilename 202 1 # 1=creat new logfile, 0=append to logfile ############################# @@ -116,11 +145,11 @@ # # after a down command 211 60 # 10 .. 600 (default 60) broadcasts every x seconds ############################# -300 0 # > 0 print routing info to file every x broadcasts. ( normally minutes ) +300 1 # > 0 print routing info to file every x broadcasts. ( normally minutes ) 301 /tmp/nw.routes # filename. -302 1 # creat new filename=1, append to file=0 +302 1 # creat new routing info file=1, append to this file=0 ############################# -310 7 # send wdog's only to device net < x tics. +310 7 # send wdog's only to device net < x ticks. # 0 = allways send wdogs. < 0 = never send wdogs ############################## # station file for special handling of stations. diff --git a/examples/patchme b/examples/patchme index 3dd6677..b43c59d 100755 --- a/examples/patchme +++ b/examples/patchme @@ -1,4 +1,5 @@ #!/bin/sh +### !!!!!!! this is only for kernel 1.3.56 !!!!!!!! ACT_DIR=`pwd` PATCHFILE=kpatch1.3.56 LINUXDIR=/usr/src/linux diff --git a/makefile.unx b/makefile.unx index c82a02a..d3b5eae 100644 --- a/makefile.unx +++ b/makefile.unx @@ -1,5 +1,5 @@ #if 0 -#makefile.unx 15-Mar-96 +#makefile.unx 22-Mar-96 #endif VPATH=$(V_VPATH) @@ -9,7 +9,7 @@ C=.c V_H=0 V_L=97 -P_L=2 +P_L=3 #define D_P_L 1 DISTRIB=mars_nwe @@ -28,6 +28,9 @@ DESTMAKEFILE=Makefile.o all: $(DESTMAKEFILE) $(MAKE) -f $(DESTMAKEFILE) n_$@ +routed: $(DESTMAKEFILE) + $(MAKE) -f $(DESTMAKEFILE) n_$@ + clean: $(DESTMAKEFILE) $(MAKE) -f $(DESTMAKEFILE) n_$@ @@ -63,6 +66,7 @@ PROG3=nwconn PROG4=ncpserv PROG5=nwclient PROG6=nwbind +PROG7=nwrouted #include "config.h" #ifdef FILENAME_NW_INI @@ -83,29 +87,37 @@ M_PATHNAME_PROGS="." #ifdef LINUX EMUTLIOBJ=emutli$(O) +EMUTLIOBJ1=emutli1$(O) # if INTERNAL_RIP_SAP NWROUTE_O=nwroute$(O) # else NWROUTE_O=nwroute1$(O) +NWROUTED=$(PROG7) # endif #else NWROUTE_O=nwroute1$(O) #endif -PROGS=$(PROG1) $(PROG2) $(PROG3) $(PROG4) $(PROG5) $(PROG6) +PROGS=$(PROG1) $(PROG2) $(PROG3) $(PROG4) $(PROG5) $(PROG6) $(NWROUTED) OBJ1= $(EMUTLIOBJ) net1$(O) tools$(O) -OBJ2= $(OBJ1) $(NWROUTE_O) -OBJ3= $(OBJ1) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) +OBJ2= $(OBJ1) $(EMUTLIOBJ1) $(NWROUTE_O) +OBJ3= $(OBJ1) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O) \ +nwqueue$(O) OBJ4= $(OBJ1) OBJ5= $(OBJ1) -OBJ6= $(OBJ1) nwdbm$(O) nwcrypt$(O) +OBJ6= $(OBJ1) nwdbm$(O) nwcrypt$(O) unxlog$(O) +OBJ7= $(OBJ1) $(EMUTLIOBJ1) -OBJS= net1$(O) tools$(O) connect$(O) nwdbm$(O) $(NWROUTE_O) \ - namspace$(O) nwvolume$(O) \ - $(PROG2)$(O) $(PROG3)$(O) $(PROG4)$(O) $(PROG5)$(O) $(PROG6)$(O) +OBJS= $(EMUTLIOBJ) net1$(O) tools$(O) \ + $(EMUTLIOBJ1) $(NWROUTE_O) \ + connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O)\ + nwdbm$(O) nwcrypt$(O) unxlog$(O) \ + $(PROG2)$(O) $(PROG3)$(O) $(PROG4)$(O) $(PROG5)$(O) $(PROG6)$(O) \ + $(PROG7)$(O) -HOBJ3= $(PROG3)$(O) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) +HOBJ3= $(PROG3)$(O) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) \ + unxfile$(O) #if 0 #$(PROG1): $(PROG1)$(O) $(OBJ1) @@ -114,6 +126,7 @@ HOBJ3= $(PROG3)$(O) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) $(PROG2): $(PROG2)$(O) $(OBJ2) $(CC) -o $(VPATH)/$(PROG2) $(PROG2)$(O) $(OBJ2) $(NSLLIB) + #if 0 #$(CC) -o $(VPATH)/$(PROG2) $(PROG2)$(O) $(OBJ2) $(NDBMLIB) $(NSLLIB) #endif @@ -130,6 +143,8 @@ $(PROG5): $(PROG5)$(O) $(OBJ5) $(PROG6): $(PROG6)$(O) $(OBJ6) $(CC) -o $(VPATH)/$(PROG6) $(PROG6)$(O) $(OBJ6) $(NDBMLIB) $(CRYPTLIB) $(NSLLIB) +$(PROG7): $(PROG7)$(O) $(OBJ7) nwserv.c nwroute.c + $(CC) -o $(VPATH)/$(PROG7) $(PROG7)$(O) $(OBJ7) $(NSLLIB) $(HOBJ3): namspace.h connect.h nwvolume.h nwfile.h $(OBJS): net.h config.h @@ -141,6 +156,8 @@ $(C)$(O): n_all: $(PROGS) @echo "don't forget to do a 'make install' as root !" >> $(VPATH)/.mk.notes +n_routed: $(PROG7) + n_install_ini: cd $(VPATH) && $(INSTALL) -m 664 nw.ini $(M_FILENAME_NW_INI) && cd $(OBJDIR) @@ -175,7 +192,7 @@ clean_d: n_clean: rm -f *.o - cd $(VPATH) && (rm -f $(PROGS); cd $(OBJDIR) ) + cd $(VPATH) && (rm -f $(PROGS) $(PROG7); 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 edc843f..fbe1a31 100644 --- a/namspace.c +++ b/namspace.c @@ -1,4 +1,4 @@ -/* namspace.c 07-Feb-96 : NameSpace Services, mars_nwe */ +/* namspace.c 06-May-96 : NameSpace Services, mars_nwe */ /* !!!!!!!!!!!! NOTE !!!!!!!!!! */ /* Its very dirty till now. */ @@ -31,6 +31,7 @@ #include "nwvolume.h" #include "connect.h" #include "nwfile.h" +#include "unxfile.h" #include "namspace.h" #if WITH_NAME_SPACE_CALLS @@ -41,27 +42,27 @@ typedef struct { int volume; /* Volume Number */ int has_wild; /* fn has wildcards */ - struct stat statb; + struct stat statb; /* stat buff */ uint8 *fn; /* points to last entry of path */ - uint8 path[512]; /* path + fn */ + uint8 path[512]; /* path + fn */ } N_NW_PATH; typedef struct { DIR *fdir; /* for dir searches */ uint8 *kpath; /* points one after unixname */ uint8 *unixname; /* is allocates fullname of path */ - /* + 257 Byte for filename. */ + /* + 257 Byte for filename. */ } DIR_SEARCH_STRUCT; typedef struct { - uint32 basehandle; - int namespace; /* namespace of this entry */ - DIR_SEARCH_STRUCT *dir; /* for dir searches */ + uint32 basehandle; + int namespace; /* namespace of this entry */ + int slot; /* act slot in table */ + int locked; /* if locked then do not remove */ + DIR_SEARCH_STRUCT *dir; /* for dir searches */ N_NW_PATH nwpath; } DIR_BASE_ENTRY; -#define MAX_DIR_BASE_ENTRIES 300 - static DIR_BASE_ENTRY *dir_base[MAX_DIR_BASE_ENTRIES]; static int anz_dbe = 0; @@ -74,54 +75,74 @@ static void init_nwpath(N_NW_PATH *nwpath) } static char *xnwpath_2_unix(N_NW_PATH *nwpath, int modus, - int allocate_extra) + int allocate_extra, uint8 *extra_path) /* * returns complete UNIX path * modus & 1 : ignore fn, (only path) * modus & 2 : no '/' at end * - * if allocate_extra > 0, then not the static buffer will be returned - * but a fresh allocated buffer, which must be deallocated later. + * if allocate_extra > 0, then the returned buffer must be + * deallocated later */ { - static char unixname[512]; /* should be big enouugh */ + static char *last_unixname=NULL; + char *unixname; int len; - int volume = nwpath->volume; + int volume = nwpath->volume; + int len_extra = (extra_path) ? strlen(extra_path) : 0; char *p, *pp; - if (volume < 0 || volume >= used_nw_volumes) { - fprintf(stderr, "nwpath_2_unix volume=%d not ok\n", volume); - strcpy(unixname, "Z/Z/Z/Z"); /* */ - len = strlen(unixname); + if (volume < 0 || volume >= used_nw_volumes || !nw_volumes[volume].unixnamlen ) { + char *errorstr="Z/Z/Z"; + errorp(0, "xnwpath_2_unix", "volume=%d not ok", volume); + len = strlen(errorstr); + unixname=xmalloc(len_extra+allocate_extra+len+10); + strcpy(unixname, errorstr); } else { int m = ((modus & 1) && nwpath->fn > nwpath->path) /* last path = fn */ ? nwpath->fn - nwpath->path : strlen((char*)nwpath->path); len = nw_volumes[volume].unixnamlen; - if (m+len >= sizeof(unixname)) { - fprintf(stderr, "nwpath_2_unix buffer to small, needs %d Byte", - m+len+1); - strcpy(unixname, "Z/Z/Z/Z"); /* */ - len = strlen(unixname); - } else { - memcpy(unixname, nw_volumes[volume].unixname, len); /* first UNIXNAME VOLUME */ - p = pp = unixname+len; - memcpy(p, nwpath->path, m); /* path or partiell path */ - len += m; - p += m; - if ((modus & 2) && *(p-1) == '/' ) *(--p) = '\0'; - else *p = '\0'; - if (nw_volumes[volume].options & 1) downstr((uint8*)pp); + unixname=xmalloc(len_extra+allocate_extra+m+len+10); + memcpy(unixname, nw_volumes[volume].unixname, len); + /* first UNIXNAME VOLUME */ + p = pp = unixname+len; + memcpy(p, nwpath->path, m); /* path or partiell path */ + len += m; + p += m; + if ((modus & 2) && *(p-1) == '/' ) { + if (p > unixname+1) { + --p; + --len; + } else { + *p++ = '.'; + ++len; + } + } else if (len_extra) { + if (*(p-1) != '/') { + *p++='/'; + len++; + } + memcpy(p, extra_path, len_extra); + p += len_extra; + len += len_extra; } + *p = '\0'; + if (nw_volumes[volume].options & VOL_OPTION_DOWNSHIFT) + downstr((uint8*)pp); } - if (allocate_extra) { - char *ret=xmalloc(len+allocate_extra+2); - strcpy(ret, unixname); - return(ret); + if (!allocate_extra) { + xfree(last_unixname); + last_unixname=unixname; } return(unixname); } -#define nwpath_2_unix(nwpath, modus) xnwpath_2_unix((nwpath), (modus), 0) +#define nwpath_2_unix(nwpath, modus) \ + xnwpath_2_unix((nwpath), (modus), 0, NULL) +#define nwpath_2_unix1(nwpath, modus, extrabytes) \ + xnwpath_2_unix((nwpath), (modus), (extrabytes), NULL) +#define nwpath_2_unix2(nwpath, modus, extrabytes, extrastr) \ + xnwpath_2_unix((nwpath), (modus), (extrabytes), extrastr) static void free_dbe_dir(DIR_BASE_ENTRY *dbe) { @@ -135,17 +156,19 @@ static void free_dbe_dir(DIR_BASE_ENTRY *dbe) static int allocate_dbe_dir(DIR_BASE_ENTRY *dbe) { - DIR_SEARCH_STRUCT *d; + DIR_SEARCH_STRUCT *d=(DIR_SEARCH_STRUCT*) xcmalloc(sizeof(DIR_SEARCH_STRUCT)); if (dbe->dir) free_dbe_dir(dbe); - dbe->dir = d = (DIR_SEARCH_STRUCT*) xcmalloc(sizeof(DIR_SEARCH_STRUCT)); - d->unixname = (uint8*)xnwpath_2_unix(&(dbe->nwpath), 2, 258); - if (NULL == (d->fdir = opendir(d->unixname))) { + dbe->dir = d; + d->unixname = (uint8*)nwpath_2_unix1(&(dbe->nwpath), 2, 258); + XDPRINTF((4, 0, "UNIXNAME='%s'", d->unixname)); + d->fdir = opendir(d->unixname); + if (NULL == d->fdir) { free_dbe_dir(dbe); return(-0xff); } else { - d->kpath = d->unixname+strlen(d->unixname); - *(d->kpath) = '/'; - *(++d->kpath) = '\0'; + d->kpath = d->unixname+strlen(d->unixname); + *(d->kpath) = '/'; + *(++(d->kpath)) = '\0'; return(0); } } @@ -162,8 +185,12 @@ static int base_open_seek_dir(DIR_BASE_ENTRY *dbe, uint32 offset) { int result = ((dbe->nwpath.statb.st_mode & S_IFMT) != S_IFDIR) ? -0xff : 0; if (!result) { + if (offset == MAX_U32) { + free_dbe_dir(dbe); + offset = 0L; + } if (NULL == dbe->dir) result=allocate_dbe_dir(dbe); - if (result>-1) seekdir(dbe->dir->fdir, offset); + if (result > -1) seekdir(dbe->dir->fdir, offset); } if (result < 0 && NULL != dbe->dir) free_dbe_dir(dbe); XDPRINTF((3, 0, "base_open_seek_dir offset=%d, result=%d", offset, result)); @@ -171,59 +198,91 @@ static int base_open_seek_dir(DIR_BASE_ENTRY *dbe, uint32 offset) } -static int allocate_dbe(int namespace) +static DIR_BASE_ENTRY *allocate_dbe_p(int namespace) /* returns new allocated dir_base_entry */ { int j=-1; + int to_use=-1; DIR_BASE_ENTRY **pdbe=(DIR_BASE_ENTRY**) NULL; - if (namespace) return(-0xff); /* TODO: more namespaces */ - while (++j < anz_dbe && NULL != *(pdbe = &(dir_base[j])) ) ;; + if (namespace) return(NULL); /* TODO: more namespaces */ + while (++j < anz_dbe && NULL != *(pdbe = &(dir_base[j])) ){ + if (to_use < 0 && !(*pdbe)->basehandle && !(*pdbe)->locked) to_use=j; + } if (j == anz_dbe) { if (anz_dbe == MAX_DIR_BASE_ENTRIES) { /* return(-0xff); */ - pdbe = &(dir_base[--j]); + if (to_use > -1) j=to_use; + else while (j--) { + pdbe = &(dir_base[j]); + if (!(*pdbe)->locked) break; /* remove last not locked from list */ + } free_dbe_ptr(*pdbe); } else pdbe = &(dir_base[anz_dbe++]); } *pdbe = (DIR_BASE_ENTRY*)xcmalloc(sizeof(DIR_BASE_ENTRY)); (*pdbe)->namespace = namespace; + (*pdbe)->slot = j; init_nwpath(&((*pdbe)->nwpath)); - return(j); + return(*pdbe); } -static void free_dbe(int dbase) +static int allocate_dbe(int namespace) { - if (dbase > -1 && dbase < anz_dbe) { - free_dbe_ptr(dir_base[dbase]); - dir_base[dbase] = (DIR_BASE_ENTRY*)NULL; - if (dbase+1 == anz_dbe) { + DIR_BASE_ENTRY *dbe=allocate_dbe_p(namespace); + return((NULL != dbe) ? dbe->slot : -1); +} + +static void xx_free_dbe_p(DIR_BASE_ENTRY **dbe) +{ + if (NULL != dbe && NULL != *dbe) { + int slot = (*dbe)->slot; + free_dbe_ptr(*dbe); + dir_base[slot] = *dbe = (DIR_BASE_ENTRY*)NULL; + if (slot+1 == anz_dbe) { while (anz_dbe && ((DIR_BASE_ENTRY*)NULL == dir_base[anz_dbe-1]) ) --anz_dbe; } } } +#define free_dbe_p(dbe) xx_free_dbe_p(&(dbe)) -int touch_handle_entry(int dbase) +#define free_dbe(dbase) \ + xx_free_dbe_p(((dbase) > -1 && (dbase) < anz_dbe) ? &(dir_base[dbase]) : NULL) + +static int touch_handle_entry_p(DIR_BASE_ENTRY *dbe) /* routine touchs this entry and returns the new offset */ { + int dbase = (NULL != dbe) ? dbe->slot : -1; XDPRINTF((4, 0, "touch_handle_entry entry dbase=%d", dbase)); if (dbase > 2) { - DIR_BASE_ENTRY *dbe=dir_base[dbase]; - while (dbase--) dir_base[dbase+1] = dir_base[dbase]; + DIR_BASE_ENTRY **dbp=&(dir_base[dbase]); + while (dbase--) { + *dbp = *(dbp-1); + if (*dbp) (*dbp)->slot = dbase+1; + --dbp; + } dbase=0; dir_base[0] = dbe; + dbe->slot = 0; } XDPRINTF((4, 0, "touch_handle_entry return dbase=%d", dbase)); return(dbase); } +#define touch_handle_entry(dbase) \ + touch_handle_entry_p(((dbase) > -1 && (dbase) < anz_dbe) ? dir_base[dbase] : NULL) + char *debug_nwpath_name(N_NW_PATH *p) -/* for debugging */ +/* only for debugging */ { #if DO_DEBUG - static char nwpathname[512]; + static char *nwpathname=NULL; char volname[300]; - if (nw_get_volume_name(p->volume, volname) < 0) + int len; + if (nw_get_volume_name(p->volume, volname) < 1) sprintf(volname, "<%d=NOT-OK>", (int)p->volume); + len = strlen(volname) + strlen(p->path) + strlen(p->fn) + 30; + xfree(nwpathname); + nwpathname=xmalloc(len); sprintf(nwpathname, "`%s:%s`,fn=`%s`", volname, p->path, p->fn); #else static char nwpathname[2]; @@ -233,6 +292,18 @@ char *debug_nwpath_name(N_NW_PATH *p) return(nwpathname); } +static int get_comp_pathes_size(NW_HPATH *nwp, uint8 *pp_pathes) +{ + int k = -1; + int size = 0; + while (++k < nwp->components) { + int len = (int) *(pp_pathes++); + pp_pathes+= len; + size += len; + size++; + } + return(size); +} static int add_hpath_to_nwpath(N_NW_PATH *nwpath, NW_HPATH *nwp, uint8 *pp_pathes) @@ -243,6 +314,9 @@ static int add_hpath_to_nwpath(N_NW_PATH *nwpath, int result = 0; int k = -1; uint8 *pp = nwpath->path+strlen(nwpath->path); + XDPRINTF((2, 0, "entry add_hpath_to_nwpath: %s", + debug_nwpath_name(nwpath))); + while (!result && ++k < nwp->components) { int len = (int) *(pp_pathes++); uint8 *p = pp_pathes; @@ -287,25 +361,41 @@ static int add_hpath_to_nwpath(N_NW_PATH *nwpath, } /* while */ if (nwpath->volume < 0) result=-0x9c; leave_build_nwpath: - XDPRINTF((2, 0, "add_hpath_to_nwpath: result=0x%x, nwpath=%s", + XDPRINTF((2, 0, "add_hpath_to_nwpath: result=0x%x, %s", result, debug_nwpath_name(nwpath))); return(result); } +static int nwp_stat(N_NW_PATH *nwpath, char *debstr) +{ + uint8 *uname=nwpath_2_unix1(nwpath, 2, 1); + int result=stat(uname, &(nwpath->statb)); + if (nw_debug) { + char xdebstr[2]; + if (!debstr) { + xdebstr[0]='\0'; + debstr = xdebstr; + } + XDPRINTF((4, 0, "nwp_stat:%s:%d,`%s`", + debstr, + result, + debug_nwpath_name(nwpath))); + } + xfree(uname); + return(result); +} + static uint32 build_base_handle(N_NW_PATH *nwpath, int namespace) /* returns basehandle of path, or 0 if not exist !! */ { uint32 basehandle=0L; - if (!stat(nwpath_2_unix(nwpath, 2), &(nwpath->statb))) { + if (!nwp_stat(nwpath, "build_base_handle")) { DEV_NAMESPACE_MAP dnm; dnm.dev = nwpath->statb.st_dev; dnm.namespace = namespace; - basehandle=nw_vol_inode_to_handle(nwpath->volume, + basehandle = nw_vol_inode_to_handle(nwpath->volume, nwpath->statb.st_ino, &dnm); - } else { - XDPRINTF((4,0, "build_base_handle failed:`%s`", - debug_nwpath_name(nwpath))); } return(basehandle); } @@ -322,11 +412,12 @@ static int find_base_entry(int volume, uint32 basehandle) return(-0x9b); } -static int insert_get_base_entry(N_NW_PATH *nwpath, int dbase, +static int insert_get_base_entry(DIR_BASE_ENTRY *dbe, int namespace, int creatmode) { + N_NW_PATH *nwpath = &(dbe->nwpath); uint32 basehandle = build_base_handle(nwpath, namespace); - if (!basehandle && creatmode) { + if (!basehandle && creatmode) { /* now creat the entry (file or dir) */ int result = 0; char *unname = nwpath_2_unix(nwpath, 2); if (creatmode & FILE_ATTR_DIR) { @@ -342,27 +433,30 @@ static int insert_get_base_entry(N_NW_PATH *nwpath, int dbase, if (result) return(result); basehandle = build_base_handle(nwpath, namespace); } + if (basehandle) { - DIR_BASE_ENTRY *dbe=dir_base[dbase]; int k=-1; while (++k < anz_dbe) { DIR_BASE_ENTRY *e=dir_base[k]; if ( (DIR_BASE_ENTRY*)NULL != e - && basehandle == e->basehandle + && basehandle == e->basehandle && nwpath->volume == e->nwpath.volume) { - free_dbe(dbase); - return(touch_handle_entry(k)); + free_dbe_p(e); + dbe->basehandle = basehandle; + return(touch_handle_entry_p(dbe)); } } /* while */ /* now i know that it's a new base entry */ dbe->basehandle = basehandle; - return(touch_handle_entry(dbase)); + return(touch_handle_entry_p(dbe)); } - return(-0x9c); + return(-0xff); /* no files matching */ } -static int build_dos_base(NW_HPATH *nwp, uint8 *pathes, - int dbase, int mode, uint8 *rets) +static int build_dos_base(NW_HPATH *nwp, + uint8 *pathes, + int dbase, + int mode, uint8 *rets) /* routine returns the actual dbe entry offset or */ /* < 0 if error */ /* if mode == 1, then last_path will be ignored and will be put */ @@ -375,8 +469,11 @@ static int build_dos_base(NW_HPATH *nwp, uint8 *pathes, int dir_handle = nwp->base[0]; if (dir_handle > 0 && --dir_handle < (int)used_dirs && dirs[dir_handle].inode) { + int llen = strlen(dirs[dir_handle].path); nwpath->volume = dirs[dir_handle].volume; - strcpy(nwpath->path, dirs[dir_handle].path); + memcpy(nwpath->path, dirs[dir_handle].path, llen+1); + if (llen && *(nwpath->path + llen -1) == '/') + *(nwpath->path+llen-1) = '\0'; result = (nwpath->volume > -1) ? 0 : -0x98; } else result = -0x9b; } else if (nwp->flag == 1) { /* basehandle */ @@ -411,7 +508,7 @@ static int build_dos_base(NW_HPATH *nwp, uint8 *pathes, } } if (pp) nwpath->fn=(uint8*)pp+1; - result = insert_get_base_entry(nwpath, dbase, NAME_DOS, 0); + result = insert_get_base_entry(dbe, NAME_DOS, 0); } } return(result); @@ -419,8 +516,8 @@ static int build_dos_base(NW_HPATH *nwp, uint8 *pathes, int nw_generate_dir_path(int namespace, NW_HPATH *nwp, - uint8 *ns_dir_base, - uint8 *dos_dir_base) + uint8 *ns_dir_base, + uint8 *dos_dir_base) /* returns Volume Number >=0 or errcode < 0 if error */ { @@ -530,8 +627,8 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p) result += (int) *p; } } - XDPRINTF((3, 0, "build_dir_info:path=%s, result=%d, basehandle=0x%x", - debug_nwpath_name(nwpath), result, dbe->basehandle)); + XDPRINTF((3, 0, "build_dir_info:path=%s, result=%d, basehandle=0x%x, mask=0x%lx", + debug_nwpath_name(nwpath), result, dbe->basehandle, infomask)); return(result); } int nw_optain_file_dir_info(int namespace, NW_HPATH *nwp, @@ -547,12 +644,14 @@ int nw_optain_file_dir_info(int namespace, NW_HPATH *nwp, int result = -0xfb; if (dbase > -1) { if ((result = build_dos_base(nwp, nwp->pathes, dbase, 0, NULL)) > -1) { - result = build_dir_info(dir_base[result], infomask, responsedata); + DIR_BASE_ENTRY *dbe=dir_base[result]; + nwp_stat(&(dbe->nwpath), "nw_optain_file_dir_info"); + result = build_dir_info(dbe, infomask, responsedata); } else free_dbe(dbase); } if (result < 0) { - XDPRINTF((3, 0, "nw_optain_file_dir_info NOT OK dbase=%d, result=0x%x", - dbase, result)); + XDPRINTF((3, 0, "nw_optain_file_dir_info NOT OK dbase=%d, result=-0x%x", + dbase, -result)); } return(result); } @@ -561,11 +660,11 @@ static int nw_init_search(int namespace, NW_HPATH *nwp, uint8 *responsedata) { - int dbase = allocate_dbe(namespace); + DIR_BASE_ENTRY *dbe=allocate_dbe_p(namespace); int result = -0xfb; - if (dbase > -1) { - if ((result = build_dos_base(nwp, nwp->pathes, dbase, 0, NULL)) > -1) { - DIR_BASE_ENTRY *dbe=dir_base[result]; + if (NULL != dbe) { + if ((result = build_dos_base(nwp, nwp->pathes, dbe->slot, 0, NULL)) > -1) { + dbe=dir_base[result]; result = base_open_seek_dir(dbe, 0L); if (result > -1) { *responsedata++ = dbe->nwpath.volume; @@ -576,36 +675,33 @@ static int nw_init_search(int namespace, } XDPRINTF((3, 0, "nw_init_search path=%s, result=%d, basehandle=0x%x", debug_nwpath_name(&(dbe->nwpath)), result, dbe->basehandle)); - } else free_dbe(dbase); + } else free_dbe_p(dbe); } if (result < 0) { - XDPRINTF((3, 0, "nw_init_search NOT OK dbase=%d, result=%d", - dbase, result)); + XDPRINTF((3, 0, "nw_init_search NOT OK result=%d", result)); } return(result); } int get_add_new_entry(DIR_BASE_ENTRY *qbe, uint8 *path, int creatmode) { - int dbase = allocate_dbe(qbe->namespace); - if (dbase > -1) { - DIR_BASE_ENTRY *dbe=dir_base[dbase]; + DIR_BASE_ENTRY *dbe=allocate_dbe_p(qbe->namespace); + if (NULL != dbe) { N_NW_PATH *nwpath=&(dbe->nwpath); int result = -0x9c; - nwpath->volume=qbe->nwpath.volume; + nwpath->volume = qbe->nwpath.volume; strcpy(nwpath->path, qbe->nwpath.path); nwpath->fn = nwpath->path+strlen(nwpath->path); if (nwpath->fn > nwpath->path && *(nwpath->fn-1) != '/') { *(nwpath->fn) = '/'; - *(++ nwpath->fn) = '\0'; + *(++nwpath->fn) = '\0'; } strcpy(nwpath->fn, path); - - result = insert_get_base_entry(nwpath, dbase, qbe->namespace, creatmode); - if (result < 0) free_dbe(dbase); + result = insert_get_base_entry(dbe, qbe->namespace, creatmode); + if (result < 0) free_dbe_p(dbe); return(result); } - return(dbase); + return(-1); } int nw_search_file_dir(int namespace, int datastream, @@ -624,6 +720,7 @@ int nw_search_file_dir(int namespace, int datastream, int dest_entry=-1; DIR_SEARCH_STRUCT *ds=dbe->dir; int vol_options = get_volume_options(volume, 0); + dbe->locked++; strmaxcpy(entry, path, min(255, len)); if (vol_options & VOL_OPTION_DOWNSHIFT) downstr(entry); XDPRINTF((5,0,"nw_search_file_dir searchpath=%s", entry)); @@ -639,13 +736,22 @@ int nw_search_file_dir(int namespace, int datastream, strcpy(ds->kpath, name); XDPRINTF((5,0,"nw_search_file_dir Name found=%s unixname=%s", name, ds->unixname)); - if (!stat(ds->unixname, &statb) - && ( !S_ISDIR(statb.st_mode) || - (searchattrib & FILE_ATTR_DIR) ) ) { - strcpy(entry, name); - if (vol_options & 1) upstr(entry); - if ((dest_entry = get_add_new_entry(dbe, entry, 0)) > -1) - break; + if (!stat(ds->unixname, &statb)) { + int flag= (searchattrib & W_SEARCH_ATTR_ALL) == W_SEARCH_ATTR_ALL; + if (!flag) { + if (S_ISDIR(statb.st_mode)) + flag=(searchattrib & FILE_ATTR_DIR); + else + flag = !(searchattrib & FILE_ATTR_DIR); + } + if (flag) { + strcpy(entry, name); + if (vol_options & VOL_OPTION_DOWNSHIFT) upstr(entry); + if ((dest_entry = get_add_new_entry(dbe, entry, 0)) > -1) + break; + } + } else { + XDPRINTF((5,0,"nw_search_file_dir stat error")); } } } /* if */ @@ -653,6 +759,7 @@ int nw_search_file_dir(int namespace, int datastream, *(ds->kpath) = '\0'; if (dest_entry > -1) { DIR_BASE_ENTRY *dest_dbe=dir_base[dest_entry]; + (void) nwp_stat(&(dest_dbe->nwpath), "nw_search_file_dir"); sequence = (uint32) telldir(ds->fdir); *responsedata = (uint8) volume; responsedata++; @@ -666,7 +773,9 @@ int nw_search_file_dir(int namespace, int datastream, build_dir_info(dest_dbe, infomask|INFO_MSK_NAME_SPACE_INFO, responsedata); - } else result=-0xfe; /* no files matching */ + } else + result=-0xff; /* no files matching */ + dbe->locked=0; } /* if result */ } return(result); @@ -714,7 +823,6 @@ static int nw_open_creat_file_or_dir(int namespace, if ((result = file_creat_open(dbe->nwpath.volume, nwpath_2_unix(&dbe->nwpath, 2), &(dbe->nwpath.statb), attrib, access_rights, creatmode)) > -1) { - fhandle = (uint32) result; actionresult |= OPC_ACTION_OPEN; /* FILE OPEN */ if (exist > -1 && (opencreatmode & OPC_MODE_REPLACE)) @@ -745,7 +853,6 @@ static int nw_delete_file_dir(int namespace, int searchattrib, if ((result = build_dos_base(nwp, nwp->pathes, dbase, 0, NULL)) > -1) { DIR_BASE_ENTRY *dbe=dir_base[dbase=result]; uint8 *unname=(uint8*)nwpath_2_unix(&(dbe->nwpath), 2); - if (S_ISDIR(dbe->nwpath.statb.st_mode)) result = rmdir(unname); else result = unlink(unname); if (result < 0) { @@ -762,11 +869,76 @@ static int nw_delete_file_dir(int namespace, int searchattrib, return(result); } -int handle_func_0x57(uint8 *p, uint8 *responsedata) +static int nw_alloc_short_dir_handle(int namespace, int hmode, + NW_HPATH *nwp, int task, int *volume) +{ + DIR_BASE_ENTRY *dbe=allocate_dbe_p(namespace); + int result = -0xfb; + if (NULL != dbe) { + if ((result = build_dos_base(nwp, nwp->pathes, dbe->slot, 0, NULL)) > -1) { + dbe=dir_base[result]; + if (S_ISDIR(dbe->nwpath.statb.st_mode)) { + result=xinsert_new_dir(dbe->nwpath.volume, dbe->nwpath.path, + dbe->nwpath.statb.st_ino, 300, hmode, task); + *volume=dbe->nwpath.volume; + } else result=-0xff; + } else free_dbe_p(dbe); + } + return(result); +} + +static int nw_rename_file_dir(int namespace, + NW_HPATH *nwps, uint8 *pathes_s, + NW_HPATH *nwpd, uint8 *pathes_d, + int searchattrib, + int renameflag) +{ + DIR_BASE_ENTRY *dbe_s = allocate_dbe_p(namespace); + DIR_BASE_ENTRY *dbe_d = (NULL != dbe_s) ? allocate_dbe_p(namespace) : NULL; + int result = -0xfb; + if (dbe_d && + (result = build_dos_base(nwps, pathes_s, dbe_s->slot, 0, NULL)) > -1) { + uint8 last_part[258]; + uint8 *unname_s= + (uint8*)nwpath_2_unix1(&((dbe_s=dir_base[result])->nwpath), + 2, 1); + if ((result = build_dos_base(nwpd, pathes_d, dbe_d->slot, + 1, last_part)) > -1) { + uint8 *unname_d = + (uint8*)nwpath_2_unix2(&((dbe_d=dir_base[result])->nwpath), + 0, 1, last_part); + + if (S_ISDIR(dbe_s->nwpath.statb.st_mode)) + result = unx_mvdir(unname_s, unname_d); + else + result = unx_mvfile(unname_s, unname_d); + + XDPRINTF((5, 0, "Rename:%d '%s' -> '%s'", result, unname_s, unname_d)); + + xfree(unname_d); + switch (result) { + case 0 : break; + + case EEXIST : result = -0x92; break; + + default : result = -0xff; + } + if (!result) { + free_dbe_p(dbe_s); + if ((result=get_add_new_entry(dbe_d, last_part, 0)) > -1) + result = 0; + } + } else free_dbe_p(dbe_d); + xfree(unname_s); + } else free_dbe_p(dbe_s); + return(result); +} + +int handle_func_0x57(uint8 *p, uint8 *responsedata, int task) { int result = -0xfb; /* unknown request */ int ufunc = (int) *p++; /* now p locates at 4 byte boundary */ - int namespace = (int) *p; /* for most calls */ + int namespace = (int) *p; /* for most calls */ XDPRINTF((3, 0, "0x57 call ufunc=0x%x namespace=%d", ufunc, namespace)); switch (ufunc) { case 0x01 : /* open creat file or subdir */ @@ -804,7 +976,7 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata) uint32 basehandle = GET_32(p+9); /* LOW-HI */ uint32 sequence = GET_32(p+13); /* LOW-HI */ int len = *(p+17); - uint8 *path = p+18; + uint8 *path = p+18; result = nw_search_file_dir(namespace, datastream, searchattrib, infomask, volume, basehandle, sequence, @@ -812,6 +984,21 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata) } break; + case 0x04 : /* rename File or Dir */ + { + int renameflag = *(p+1); + int searchattrib = (int) GET_16(p+2); /* LOW-HI */ + NW_HPATH nwps; + NW_HPATH nwpd; + int size; + p+=4; + memcpy(&nwps, p, 7); p+=7; + memcpy(&nwpd, p, 7); p+=7; + size = get_comp_pathes_size(&nwps, p); + result = nw_rename_file_dir(namespace, + &nwps, p, &nwpd, p+size, searchattrib, renameflag); + } + break; case 0x06 : /* Obtain File or Subdir Info */ { @@ -830,6 +1017,7 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata) case 0x07 : /* Modify File or Dir Info */ { + } break; @@ -841,24 +1029,43 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata) } break; - - case 0x09 : /* Set short Dir Handle*/ { + + } break; case 0x0c : /* alloc short dir Handle */ { - + int hmode = (int) GET_16(p+2); /* 0=p, 1=temp, 2=speztemp */ + NW_HPATH *nwp = (NW_HPATH *)(p+4); + struct OUTPUT { + uint8 dir_handle; + uint8 volume; + uint8 reserved[4]; + } *xdata= (struct OUTPUT*)responsedata; + int volume; + result = nw_alloc_short_dir_handle(namespace, hmode, nwp, task, + &volume); + if (result > -1) { + xdata->dir_handle = (uint8) result; + xdata->volume = (uint8) volume; + U32_TO_32(0L, xdata->reserved); + result=sizeof(struct OUTPUT); + } } break; - case 0x15 : /* Get Path String from short dir new */ { - + int dir_handle=(int) *(p+1); + result=nw_get_directory_path(dir_handle, responsedata+1); + if (result > -1) { + *responsedata=(uint8) result; + result+=1; + } } break; diff --git a/namspace.h b/namspace.h index c462b50..f8e0f0c 100644 --- a/namspace.h +++ b/namspace.h @@ -46,11 +46,16 @@ typedef struct { #define INFO_MSK_DIR_ENTRY_INFO 0x00000400 #define INFO_MSK_RIGHTS_INFO 0x00000800 -/* Attributes */ +/* File Attributes */ #define FILE_ATTR_NORMAL 0x00000000 #define FILE_ATTR_DIR 0x00000010 #define FILE_ATTR_SHARE 0x00000080 +/* Search Attributes */ +#define W_SEARCH_ATTR_DIR 0x00008000 +#define W_SEARCH_ATTR_ALL 0x00008006 + + /* OPEN/CREAT Modes */ #define OPC_MODE_OPEN 0x01 #define OPC_MODE_REPLACE 0x02 @@ -62,6 +67,6 @@ typedef struct { #define OPC_ACTION_REPLACE 0x04 -extern int handle_func_0x57(uint8 *p, uint8 *responsedata); +extern int handle_func_0x57(uint8 *p, uint8 *responsedata, int task); #endif diff --git a/ncpserv.c b/ncpserv.c index 399312d..266760d 100644 --- a/ncpserv.c +++ b/ncpserv.c @@ -347,7 +347,7 @@ static int find_get_conn_nr(ipxAddr_t *addr) } } if (connection) { - uint8 buff[sizeof(ipxAddr_t)+sizeof(uint16)]; + uint8 buff[sizeof(ipxAddr_t)+sizeof(uint16)+sizeof(uint32)]; memcpy(buff, addr, sizeof(ipxAddr_t)); #if CALL_NWCONN_OVER_SOCKET /* here i can use the nwconn socket */ @@ -356,6 +356,8 @@ static int find_get_conn_nr(ipxAddr_t *addr) /* and in this mode all must be go over ncpserv */ U16_TO_BE16(SOCK_NCP, buff+sizeof(ipxAddr_t)); #endif + U32_TO_BE32(connections[connection-1].pid, + buff+sizeof(ipxAddr_t)+sizeof(uint16)); nwserv_insert_conn(connection, (char*)buff, sizeof(buff)); } return(connection); @@ -540,11 +542,14 @@ static void handle_ncp_request(void) c->retry = 0; return; } else { /* 0x5555, close connection */ + #if !CALL_NWCONN_OVER_SOCKET if ( (uint8) (c->sequence+1) == (uint8) ncprequest->sequence) #endif { +#if 1 clear_connection(connection); +#endif ncp_response(0x3333, ncprequest->sequence, connection, @@ -566,8 +571,8 @@ static void handle_ncp_request(void) ncp_response(0x3333, ncprequest->sequence, ncprequest->connection, 0, /* task */ - 0xff, /* completition */ - 0xff, /* conn status */ + 0xfe, /* completition */ + 0xf0, /* conn status */ 0); #if !CALL_NWCONN_OVER_SOCKET @@ -621,11 +626,11 @@ static void handle_ncp_request(void) int main(int argc, char *argv[]) { - if (argc != 4) { - fprintf(stderr, "usage ncpserv nwname address nwbindsock\n"); - exit(1); - } init_tools(NCPSERV, 0); + if (argc != 4) { + errorp(1, "Usage:", "ncpserv nwname address nwbindsock"); + return(1); + } get_ini(); strncpy(my_nwname, argv[1], 48); my_nwname[47] = '\0'; @@ -636,7 +641,7 @@ int main(int argc, char *argv[]) #endif if (open_ipx_sockets()) { errorp(1, "open_ipx_sockets", NULL); - exit(1); + return(1); } XDPRINTF((1, 0, "USE_PERMANENT_OUT_SOCKET %s", diff --git a/net.h b/net.h index 90ec931..870116c 100644 --- a/net.h +++ b/net.h @@ -1,4 +1,4 @@ -/* net.h 20-Mar-96 */ +/* net.h 03-May-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * @@ -26,26 +26,33 @@ #ifndef LINUX /* z.B. USL */ -# include "sys/tiuser.h" +# include #endif -#include "sys/fcntl.h" -#include "sys/types.h" -#include "unistd.h" +#include +#include +#include #include #include #include +#include + +#include +extern int errno; #ifndef LINUX -# include "stropts.h" -# include "poll.h" -# include "sys/nwctypes.h" -# include "sys/stream.h" +# include +# include +# include +# include /* # include "common.h" */ /* # include "portable.h" , needed ??? */ -# include "sys/ipx_app.h" +# include + #else +# include # include "emutli.h" /* TLI-EMULATION */ +# include "emutli1.h" /* TLI-EMULATION */ #endif #include @@ -125,13 +132,18 @@ #endif #ifndef MAX_CONNECTIONS -# define MAX_CONNECTIONS 5 /* maximum Number of Connections */ +# define MAX_CONNECTIONS 5 /* maximum Number of connections */ #endif #ifndef MAX_NW_VOLS -# define MAX_NW_VOLS 10 +# define MAX_NW_VOLS 10 /* maximum Number of volumes */ #endif +#ifndef MAX_FILE_HANDLES_CONN +# define MAX_FILE_HANDLES_CONN 80 +#endif + + #ifndef MAX_NET_DEVICES # define MAX_NET_DEVICES 5 #endif @@ -145,6 +157,18 @@ # define PATHNAME_BINDERY "." /* location of bindery files */ #endif +#ifndef PATHNAME_PIDFILES +# define PATHNAME_PIDFILES "/var/run" /* location of pidfiles */ +#endif + +#ifndef FILENAME_UTMP +# define FILENAME_UTMP UTMP_FILE +#endif + +#ifndef FILENAME_WTMP +# define FILENAME_WTMP WTMP_FILE +#endif + #ifndef NETWORK_SERIAL_NMBR # define NETWORK_SERIAL_NMBR 0x44444444L /* Serial Number 4 Byte */ #endif @@ -157,13 +181,26 @@ #endif #ifndef WITH_NAME_SPACE_CALLS -# define WITH_NAME_SPACE_CALLS 0 +# define WITH_NAME_SPACE_CALLS 1 +#endif + +#ifndef MAX_DIR_BASE_ENTRIES +# define MAX_DIR_BASE_ENTRIES 50 #endif #ifndef MAX_NW_ROUTES # define MAX_NW_ROUTES 50 #endif +#ifndef MAX_RIP_ENTRIES +# define MAX_RIP_ENTRIES 50 +#endif + +#if MAX_RIP_ENTRIES < 50 +# undef MAX_RIP_ENTRIES +# define MAX_RIP_ENTRIES 50 +#endif + #ifndef MAX_NW_SERVERS # define MAX_NW_SERVERS MAX_NW_ROUTES #endif @@ -175,26 +212,19 @@ #endif #ifdef LINUX -# ifndef INTERNAL_RIP_SAP +# ifdef IN_NWROUTED +# undef INTERNAL_RIP_SAP # define INTERNAL_RIP_SAP 1 # endif -# if INTERNAL_RIP_SAP -# ifndef FILE_SERVER_INACTIV -# define FILE_SERVER_INACTIV 0 -# endif -# else -# undef FILE_SERVER_INACTIV -# define FILE_SERVER_INACTIV 0 +# ifndef INTERNAL_RIP_SAP +# define INTERNAL_RIP_SAP 1 # endif #else -/* USL has good rip/sap router */ +/* USL has rip/sap router builtin */ # undef INTERNAL_RIP_SAP # define INTERNAL_RIP_SAP 0 -# undef FILE_SERVER_INACTIV -# define FILE_SERVER_INACTIV 0 #endif - #define MAX_SERVER_NAME 48 typedef union { diff --git a/net1.c b/net1.c index ebfa639..e910112 100644 --- a/net1.c +++ b/net1.c @@ -53,6 +53,10 @@ static char str[200]; (int)p->net[0], (int)p->net[1], (int)p->net[2], (int)p->net[3], (int)p->node[0], (int)p->node[1], (int)p->node[2], (int)p->node[3], (int)p->node[4], (int)p->node[5], (int)p->sock[0], (int)p->sock[1]); + } else if (modus== 2) { + sprintf(str,"%02x%02x%02x%02x%02x%02x", + (int)p->node[0], (int)p->node[1], (int)p->node[2], (int)p->node[3], + (int)p->node[4], (int)p->node[5]); } else strcpy(str, "??"); } else strcpy(str, "net=UNKOWN(NULLPOINTER)"); diff --git a/nwbind.c b/nwbind.c index df992f5..c31769c 100644 --- a/nwbind.c +++ b/nwbind.c @@ -1,5 +1,5 @@ /* nwbind.c */ -#define REVISION_DATE "21-Mar-96" +#define REVISION_DATE "05-May-96" /* NCP Bindery SUB-SERVER */ /* authentification and some message handling */ @@ -21,6 +21,7 @@ */ #include "net.h" #include "nwdbm.h" +#include "unxlog.h" /* next should be '1', is for testing only */ #define USE_PERMANENT_OUT_SOCKET 1 @@ -126,9 +127,39 @@ typedef struct { uint8 message[60]; /* saved BCastmessage */ int active; /* 0=closed, 1= active */ int send_to_sock; /* this is the receiving sock */ + int pid_nwconn; /* pid of user process nwconn */ } CONNECTION; static CONNECTION connections[MAX_CONNECTIONS]; +static CONNECTION *act_c=(CONNECTION*)NULL; +static int act_connection; +static int internal_act=0; + +int b_acc(uint32 obj_id, int security, int forwrite) +{ + /* security levels + * 0 = anyone have access. + * 1 = all logged have access + * 2 = object logged have access + * 3 = only supervisor has access + * 4 = only internal access. + */ + if (internal_act || !act_c) return(0); /* allways full access to internal routines */ + if (forwrite) security >>= 4; /* writesecurity */ + security &= 0x4; + if (!security) return(0); /* rights for all */ + else if (security == 1) { + if (act_c->object_id > 0) return(0); /* rights for all logged */ + } else if (security == 2) { + if ( act_c->object_id == obj_id + || act_c->object_id == 1 ) return(0); /* rights for the user */ + } else if (security == 3 && act_c->object_id == 1) return(0); + + XDPRINTF((1, 0, "b_acc no rights for 0x%x to %s property", + act_c->object_id, forwrite ? "read" : "write" )); + + return(forwrite ? -0xf8 : -0xfb); +} static void sent_down_message(void) { @@ -149,12 +180,16 @@ static void open_clear_connection(int conn, int activate, uint8 *addr) CONNECTION *c = &connections[conn]; c->active = activate; c->message[0] = '\0'; - c->object_id = 0; c->t_login = 0; if (activate && addr) { memcpy(&(c->client_adr), addr, sizeof(ipxAddr_t)); c->send_to_sock = GET_BE16(addr+sizeof(ipxAddr_t)); + c->pid_nwconn = GET_BE32(addr+sizeof(ipxAddr_t)+sizeof(uint16)); + } else { + if (c->object_id) + write_utmp(0, conn+1, c->pid_nwconn, &(c->client_adr), NULL); } + c->object_id = 0; } } @@ -172,7 +207,7 @@ static void get_login_time(uint8 login_time[], CONNECTION *cx) login_time[6] = s_tm->tm_wday; } -static void handle_fxx(CONNECTION *c, int gelen, int func) +static void handle_fxx(int gelen, int func) { IPX_DATA ipxoutdata; NCPRESPONSE *ncpresponse = (NCPRESPONSE*)&ipxoutdata; @@ -191,6 +226,7 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) if (nw_debug > 1){ int j = gelen - sizeof(NCPREQUEST); if (nw_debug){ + if (func == 0x19) ufunc=0; XDPRINTF((1, 0, "NCP 0x%x REQUEST:ufunc:0x%x", func, ufunc)); if (j > 0){ uint8 *p=requestdata; @@ -236,8 +272,8 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) break; case 0x01: { /* Get Broadcast Message (old) */ - *responsedata = (uint8) strmaxcpy(responsedata+1, c->message, 58); - c->message[0] = '\0'; + *responsedata = (uint8) strmaxcpy(responsedata+1, act_c->message, 58); + act_c->message[0] = '\0'; data_len = (int)(*responsedata) + 1; } break; @@ -385,17 +421,24 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) XDPRINTF((1, 0, "Supervisor tried unencrypted LOGIN")); } else #endif + + internal_act = 1; result=nw_test_unenpasswd(obj.id, password); + internal_act = 0; } else { XDPRINTF((1, 0, "unencryted logins are not enabled")); result=-0xff; } } if (!result) { - c->object_id = obj.id; /* actuell Object ID */ - c->t_login = akttime; /* u. login Time */ - get_guid((int*) responsedata, (int*)(responsedata+sizeof(int)), obj.id); - data_len = 2 * sizeof(int); + uint8 pw_name[40]; + act_c->object_id = obj.id; /* actuell Object ID */ + act_c->t_login = akttime; /* u. login Time */ + get_guid((int*) responsedata, (int*)(responsedata+sizeof(int)), obj.id, pw_name); + result = get_home_dir(responsedata + 2*sizeof(int)+1, obj.id); + *(responsedata+ 2 * sizeof(int)) = (uint8) result; + data_len = 2 * sizeof(int) + 1 + (int) *(responsedata+2* sizeof(int)); + write_utmp(1, act_connection, act_c->pid_nwconn, &from_addr, pw_name); } else completition = (uint8) -result; } break; @@ -457,8 +500,8 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) } break; case 0x17 : { /* get crypt key */ - int k = sizeof(c->crypt_key); - uint8 *p = c->crypt_key; + int k = sizeof(act_c->crypt_key); + uint8 *p = act_c->crypt_key; uint8 *pp = responsedata; data_len = k; while (k--) *pp++ = *p++ = @@ -475,7 +518,7 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) break; case 0x18 : { /* crypt_keyed LOGIN */ - uint8 *p = rdata+sizeof(c->crypt_key); + uint8 *p = rdata+sizeof(act_c->crypt_key); NETOBJ obj; int result; obj.type = GET_BE16(p); @@ -483,13 +526,21 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) xstrmaxcpy(obj.name, (char*)(p+3), *(p+2)); upstr(obj.name); XDPRINTF((2, 0, "LOGIN CRYPTED PW NAME='%s'",obj.name)); - if (0 == (result = find_obj_id(&obj, 0))) - result=nw_test_passwd(obj.id, c->crypt_key, rdata); + if (0 == (result = find_obj_id(&obj, 0))) { + internal_act = 1; + result=nw_test_passwd(obj.id, act_c->crypt_key, rdata); + internal_act = 0; + } if (result > -1) { - c->object_id = obj.id; /* actuell Object */ - c->t_login = akttime; /* and login time */ - get_guid((int*)responsedata, (int*)(responsedata+sizeof(int)), obj.id); - data_len = 2 * sizeof(int); + uint8 pw_name[40]; + act_c->object_id = obj.id; /* actuell Object */ + act_c->t_login = akttime; /* and login time */ + get_guid((int*)responsedata, (int*)(responsedata+sizeof(int)), obj.id, pw_name); + result = get_home_dir(responsedata + 2*sizeof(int)+1, obj.id); + *(responsedata+ 2 * sizeof(int)) = (uint8) result; + data_len = 2 * sizeof(int) + 1 + (int) *(responsedata+2* sizeof(int)); + write_utmp(1, act_connection, act_c->pid_nwconn, + &from_addr, pw_name); } else { #if 0 /* this is not ok */ @@ -500,6 +551,10 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) #endif completition = (uint8) -result; } + /* completition = 0xde menas login time has expired */ + /* completition = 0xdf means good login, but */ + /* login time has expired */ + /* perhaps I will integrate it later */ } break; @@ -554,7 +609,7 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) case 0x34 : { /* rename OBJECT, only SU */ int result=-0xff; - if (1 == c->object_id) { + if (1 == act_c->object_id) { uint8 *p = rdata; NETOBJ obj; uint8 newname[256]; @@ -642,7 +697,7 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) case 0x38 : { /* change Bindery Objekt Security */ /* only SU ! */ int result= -0xff; - if (1 == c->object_id) { + if (1 == act_c->object_id) { uint8 *p = rdata; NETOBJ obj; obj.type = GET_BE16(p+1); @@ -789,14 +844,17 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) if (0 == (result = find_obj_id(&obj, 0))) { XDPRINTF((6, 0, "CHPW: OLD=`%s`, NEW=`%s`", oldpassword, newpassword)); - if (c->object_id == 1 || + + internal_act = 1; + if (act_c->object_id == 1 || 0 == (result=nw_test_unenpasswd(obj.id, oldpassword))){ - if ( (c->object_id != 1) + if ( (act_c->object_id != 1) || *newpassword || !(password_scheme & PW_SCHEME_LOGIN)) result=nw_set_passwd(obj.id, newpassword, 0); else result = -0xff; } + internal_act = 0; } if (result < 0) completition = (uint8) -result; } else { @@ -880,7 +938,7 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) #endif NETOBJ obj; - obj.id = c->object_id; + obj.id = act_c->object_id; if (0 != obj.id) { int result = nw_get_obj(&obj); if (!result) { @@ -930,14 +988,17 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) break; case 0x4a : { /* keyed verify password */ - uint8 *p = rdata+sizeof(c->crypt_key); + uint8 *p = rdata+sizeof(act_c->crypt_key); NETOBJ obj; int result; obj.type = GET_BE16(p); strmaxcpy((char*)obj.name, (char*)(p+3), *(p+2)); upstr(obj.name); - if (0 == (result = find_obj_id(&obj, 0))) - result=nw_test_passwd(obj.id, c->crypt_key, rdata); + if (0 == (result = find_obj_id(&obj, 0))) { + internal_act = 1; + result=nw_test_passwd(obj.id, act_c->crypt_key, rdata); + internal_act = 0; + } if (result < 0) completition = (uint8) -result; XDPRINTF((2,0, "Keyed Verify PW from OBJECT='%s', result=%d", obj.name, result)); @@ -946,7 +1007,7 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) #ifdef _CHANGE_PASSWD_TESTING_ case 0x4b : { /* keyed change pasword */ - uint8 *p = rdata+sizeof(c->crypt_key); + uint8 *p = rdata+sizeof(act_c->crypt_key); NETOBJ obj; int result; obj.type = GET_BE16(p); @@ -955,11 +1016,17 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) upstr(obj.name); p += (*p+1); /* here is now password-type ?? 0x60,0x66 */ - if (0 == (result = find_obj_id(&obj, 0))) - result=nw_test_passwd(obj.id, c->crypt_key, rdata); + if (0 == (result = find_obj_id(&obj, 0))) { + internal_act = 1; + result=nw_test_passwd(obj.id, act_c->crypt_key, rdata); + internal_act = 0; + } #if 0 - if (result > -1) + if (result > -1) { + internal_act = 1; result=nw_set_enpasswd(obj.id, p+1); + internal_act = 0; + } #endif if (result< 0) completition = (uint8) -result; XDPRINTF((1, 0, "Keyed Change PW from OBJECT='%s', result=0x%x", @@ -1066,11 +1133,12 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) case 0xc8 : { /* CHECK CONSOLE PRIVILEGES */ XDPRINTF((1, 0, "TODO: CHECK CONSOLE PRIV")); /* !!!!!! TODO completition=0xc6 (no rights) */ + if (act_c->object_id != 1) completition=0xc6; /* no rights */ } break; case 0xc9 : { /* GET FILE SERVER DESCRIPTION STRINGs */ char *company = "Mars :-)"; - char *revision = "Version %d.%d"; + char *revision = "Version %d.%d.pl%d"; char *revision_date = REVISION_DATE; char *copyright = "(C)opyright Martin Stover"; int k=strlen(company)+1; @@ -1079,7 +1147,7 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) strcpy(responsedata, company); l = 1 + sprintf(responsedata+k, revision, - _VERS_H_, _VERS_L_ ); + _VERS_H_, _VERS_L_, _VERS_P_ ); #if 0 k+=l; #else @@ -1114,7 +1182,7 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) while (++k < anz_conns) { int conn= (int) *co++; if (conn == ncprequest->connection) { - strmaxcpy(c->message, msg, min(58, msglen)); + strmaxcpy(act_c->message, msg, min(58, msglen)); connect_status = 0x40; /* don't know why */ } else if (conn && --conn < MAX_CONNECTIONS) { CONNECTION *cc= &(connections[conn]); @@ -1125,14 +1193,14 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) } } } else { - strmaxcpy(c->message, msg, min(58, msglen)); + strmaxcpy(act_c->message, msg, min(58, msglen)); connect_status = 0x40; /* don't know why */ } } break; case 0xd3 : { /* down File Server */ - if (c->object_id == 1) { /* only SUPERVISOR */ + if (act_c->object_id == 1) { /* only SUPERVISOR */ /* inform nwserv */ nwserv_down_server(); } else completition = 0xff; @@ -1148,7 +1216,8 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) default : completition = 0xfb; /* not known here */ } /* switch */ } else if (func == 0x19) { /* logout */ - c->object_id = 0; /* not LOGIN */ + write_utmp(0, act_connection, act_c->pid_nwconn, &from_addr, NULL); + act_c->object_id = 0; /* not LOGIN */ } else completition = 0xfb; U16_TO_BE16(0x3333, ncpresponse->type); @@ -1157,10 +1226,10 @@ static void handle_fxx(CONNECTION *c, int gelen, int func) ncpresponse->reserved = 0; ncpresponse->completition = completition; - if (c->message[0]) connect_status |= 0x40; + if (act_c->message[0]) connect_status |= 0x40; ncpresponse->connect_status = connect_status; data_len+=sizeof(NCPRESPONSE); - U16_TO_BE16(c->send_to_sock, my_addr.sock); + U16_TO_BE16(act_c->send_to_sock, my_addr.sock); send_ipx_data(ipx_out_fd, 17, data_len, (char*)ncpresponse, &my_addr, NULL); @@ -1245,10 +1314,10 @@ static void handle_ctrl(void) int size = 0; if (sizeof (int) == xread(&ipxd, &offs, (uint8*)&(size), sizeof(int)) - && size == sizeof(ipxAddr_t) + sizeof(uint16)) { + && size == sizeof(ipxAddr_t) + + sizeof(uint16) + sizeof(uint32) ) { uint8 buf[100]; - if (size == - xread(&ipxd, &offs, buf, size)) + if (size == xread(&ipxd, &offs, buf, size)) open_clear_connection(conn, 1, buf); } } @@ -1323,10 +1392,12 @@ int main(int argc, char *argv[]) sscanf(argv[3], "%x", &sock_nwbind); + internal_act = 1; if (nw_init_dbm(my_nwname, &my_addr) <0) { errorp(1, "nw_init_dbm", NULL); exit(1); } + internal_act = 0; #ifdef LINUX set_emu_tli(); @@ -1354,31 +1425,35 @@ int main(int argc, char *argv[]) set_sig(); while (got_sig != SIGQUIT) { + act_c = (CONNECTION*)NULL; if (t_rcvudata(ncp_fd, &ud, &rcv_flags) > -1){ time(&akttime); XDPRINTF((10, 0, "NWBIND-LOOP from %s", visable_ipx_adr(&from_addr))); if ( ncprequest->type[0] == 0x22 && ncprequest->type[1] == 0x22) { - int conn = ((int)ncprequest->connection) - 1; - if (conn > -1 && conn < MAX_CONNECTIONS) { - CONNECTION *c=&(connections[conn]); - if (c->active && IPXCMPNODE(from_addr.node, my_addr.node) + act_connection = ((int)ncprequest->connection); + if (act_connection > 0 && act_connection <= MAX_CONNECTIONS) { + act_c = &(connections[act_connection-1]); + internal_act = 0; + if (act_c->active && IPXCMPNODE(from_addr.node, my_addr.node) && IPXCMPNET (from_addr.net, my_addr.net)) { - handle_fxx(c, ud.udata.len, (int)ncprequest->function); + handle_fxx(ud.udata.len, (int)ncprequest->function); } else { XDPRINTF((1, 0, "NWBIND-LOOP addr of connection=%d is wrong", - conn+1)); + act_connection)); } } else { XDPRINTF((1, 0, "NWBIND-LOOP connection=%d is wrong", - conn+1)); + act_connection)); } } else if ( ncprequest->type[0] == 0xee && ncprequest->type[1] == 0xee && IPXCMPNODE(from_addr.node, my_addr.node) && IPXCMPNET (from_addr.net, my_addr.net)) { /* comes from nwserv, i hope :) */ + handle_ctrl(); + } else { XDPRINTF((1, 0, "NWBIND-LOOP got wrong type 0x%x func=0x%x", (int) GET_BE16(ncprequest->type), (int) ncprequest->function)); diff --git a/nwconn.c b/nwconn.c index fdf8c74..0244bdf 100644 --- a/nwconn.c +++ b/nwconn.c @@ -1,4 +1,4 @@ -/* nwconn.c 21-Mar-96 */ +/* nwconn.c 04-May-96 */ /* one process / connection */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany @@ -23,6 +23,7 @@ #include "nwvolume.h" #include "nwfile.h" #include "connect.h" +#include "nwqueue.h" #include "namspace.h" @@ -100,6 +101,7 @@ static void pr_debug_request() switch (ncprequest->function) { case 0x16 : case 0x17 : ufunc = (int) *(requestdata+2); break; + case 0x57 : ufunc = (int) *(requestdata); break; default : break; } /* switch */ XDPRINTF((0, 0, "NCP REQUEST: func=0x%02x, ufunc=0x%02x, seq:%03d, task:%02d", @@ -175,9 +177,12 @@ static int handle_ncp_serv(void) if ((result = nw_get_volume_name(volume, xdata->name))>-1){ struct fs_usage fsp; if (!nw_get_fs_usage(xdata->name, &fsp)) { - U16_TO_BE16(1000, xdata->sec_per_block); /* hard coded */ - U16_TO_BE16(fsp.fsu_blocks/1000, xdata->total_blocks); - U16_TO_BE16(fsp.fsu_bavail/1000, xdata->avail_blocks); + int sector_scale=1; + while (fsp.fsu_blocks/sector_scale > 0xffff) + sector_scale*=2; + U16_TO_BE16(sector_scale, xdata->sec_per_block); + U16_TO_BE16(fsp.fsu_blocks/sector_scale, xdata->total_blocks); + U16_TO_BE16(fsp.fsu_bavail/sector_scale, xdata->avail_blocks); U16_TO_BE16(fsp.fsu_files, xdata->total_dirs); U16_TO_BE16(fsp.fsu_ffree, xdata->avail_dirs); if ( get_volume_options(volume, 1) & VOL_OPTION_REMOUNT) { @@ -360,6 +365,17 @@ static int handle_ncp_serv(void) } *input = (struct INPUT *) (ncprequest); /* TODO !!!!!!!!!!!!!!!!!!!! */ do_druck++; + } else if (*p == 0xf){ /* rename dir */ + /******** Rename DIR *********************/ + int dir_handle = (int) *(p+1); + int oldpathlen = (int) *(p+2); + uint8 *oldpath = p+3; + int newpathlen = (int) *(oldpath + oldpathlen); + uint8 *newpath = oldpath + oldpathlen + 1; + int code = mv_dir(dir_handle, + oldpath, oldpathlen, + newpath, newpathlen); + if (code) completition = (uint8) -code; } else if (*p == 0x12 /* Allocate Permanent Dir Handle */ /******** Allocate Permanent DIR Handle **/ @@ -408,9 +424,12 @@ static int handle_ncp_serv(void) if (result > -1) { struct fs_usage fsp; if (!nw_get_fs_usage(xdata->name, &fsp)) { - U16_TO_BE16(1000, xdata->sectors); - U16_TO_BE16(fsp.fsu_blocks/1000, xdata->total_blocks); - U16_TO_BE16(fsp.fsu_bavail/1000, xdata->avail_blocks); + int sector_scale=1; + while (fsp.fsu_blocks/sector_scale > 0xffff) + sector_scale*=2; + U16_TO_BE16(sector_scale, xdata->sectors); + U16_TO_BE16(fsp.fsu_blocks/sector_scale, xdata->total_blocks); + U16_TO_BE16(fsp.fsu_bavail/sector_scale, xdata->avail_blocks); U16_TO_BE16(fsp.fsu_files, xdata->total_dirs); U16_TO_BE16(fsp.fsu_ffree, xdata->avail_dirs); if (get_volume_options(volume, 1) & VOL_OPTION_REMOUNT) { @@ -672,8 +691,8 @@ static int handle_ncp_serv(void) break; #endif - case 0x14: - case 0x18: + case 0x14: /* Login Objekt, unencrypted passwords */ + case 0x18: /* crypt_keyed LOGIN */ return(-2); /* nwbind must do prehandling */ @@ -781,6 +800,7 @@ static int handle_ncp_serv(void) case 0x19 : /* logout, some of this call is handled in ncpserv. */ nw_free_handles(0); set_default_guid(); + nw_setup_home_vol(-1, NULL); return(-1); /* nwbind must do rest */ break; @@ -944,6 +964,36 @@ static int handle_ncp_serv(void) } break; + case 0x41 : { /* open file for reading */ + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 dirhandle; /* Dirhandle */ + uint8 attrib; /* z.B. 0x6 od. 0x4e */ + /* O_RDWR|TRUNC 0x6, O_RDONLY 0x6 */ + uint8 len; /* namelaenge */ + uint8 data[2]; /* Name */ + } *input = (struct INPUT *)ncprequest; + struct OUTPUT { + uint8 ext_fhandle[2]; /* all zero */ + uint8 fhandle[4]; /* Dateihandle */ + uint8 reserve2[2]; /* z.B 0x0 0x0 */ + NW_FILE_INFO fileinfo; + } *xdata= (struct OUTPUT*)responsedata; + int fhandle=nw_creat_open_file((int)input->dirhandle, + input->data, input->len, + &(xdata->fileinfo), + (int)input->attrib, + 0x1, 0); + + if (fhandle > -1){ + U32_TO_BE32(fhandle, xdata->fhandle); + U16_TO_BE16(0, xdata->ext_fhandle); + U16_TO_BE16(0, xdata->reserve2); + data_len = sizeof(struct OUTPUT); + } else completition = (uint8) (-fhandle); + } + break; + case 0x42 : /* close file */ { struct INPUT { @@ -1086,12 +1136,12 @@ static int handle_ncp_serv(void) uint8 filler; uint8 ext_fhandle[2]; /* all zero */ uint8 fhandle[4]; /* filehandle */ - uint8 offset[4]; /* alles 0 */ - uint8 max_size[2]; /* zu lesende Bytes */ + uint8 offset[4]; + uint8 max_size[2]; /* byte to readd */ } *input = (struct INPUT *)ncprequest; struct OUTPUT { - uint8 size[2]; /* Lese Bytes */ - uint8 data[1072]; /* max data */ + uint8 size[2]; /* read byzes */ + uint8 data[1072]; /* max data */ } *xdata=(struct OUTPUT*)responsedata; int fhandle = GET_BE32(input->fhandle); int max_size = GET_BE16(input->max_size); @@ -1231,7 +1281,7 @@ static int handle_ncp_serv(void) #if WITH_NAME_SPACE_CALLS case 0x57 : /* some new namespace calls */ { - int result = handle_func_0x57(requestdata, responsedata); + int result = handle_func_0x57(requestdata, responsedata, ncprequest->task); if (result > -1) data_len = result; else completition=(uint8)-result; } @@ -1310,9 +1360,12 @@ static void handle_after_bind() uint8 ufunc = *(requestdata+2); uint8 *rdata = requestdata+3; switch (ufunc) { - case 0x14: - case 0x18: { /* ncpserv have change the structure */ + case 0x14: /* Login Objekt, unencrypted passwords */ + case 0x18: { /* crypt_keyed LOGIN */ + int fnlen = (int) *(bindresponse + 2 * sizeof(int)); + /* ncpserv have changed the structure */ set_guid(*((int*)bindresponse), *((int*)(bindresponse+sizeof(int)))); + nw_setup_home_vol(fnlen, bindresponse + 2 * sizeof(int) +1); } break; diff --git a/nwdbm.c b/nwdbm.c index 39ec1aa..1c2bc8e 100644 --- a/nwdbm.c +++ b/nwdbm.c @@ -1,4 +1,4 @@ -/* nwdbm.c 20-Mar-96 data base for mars_nwe */ +/* nwdbm.c 30-Apr-96 data base for mars_nwe */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -26,9 +26,12 @@ #include "nwcrypt.h" #ifdef LINUX # include -# define SHADOW_PWD 0 +# ifndef SHADOW_PWD +# define SHADOW_PWD 0 +# endif #else # include +# undef SHADOW_PWD # define SHADOW_PWD 1 #endif @@ -372,14 +375,16 @@ static int loc_change_prop_security(NETPROP *p, uint32 obj_id) if (data.dptr != NULL && name_match(prop->name, p->name) ) { uint8 security = p->security; XDPRINTF((2,0, "found PROP %s, id=0x%x", prop->name, (int) prop->id)); - result = 0; - memcpy(p, prop, sizeof(NETPROP)); - p->security = security; - data.dptr = (char*)p; - data.dsize = sizeof(NETPROP); - key.dptr = (char *)p; - key.dsize = NETPROP_KEY_SIZE; - if (store(key, data)) result=-0xff; + result = b_acc(obj_id, prop->security, 1); + if (!result) { + memcpy(p, prop, sizeof(NETPROP)); + p->security = security; + data.dptr = (char*)p; + data.dsize = sizeof(NETPROP); + key.dptr = (char *)p; + key.dsize = NETPROP_KEY_SIZE; + if (store(key, data)) result=-0xff; + } break; } } @@ -526,17 +531,19 @@ L1: return(result); } -int ins_prop_val(uint32 obj_id, uint8 prop_id, int segment, +static int ins_prop_val(uint32 obj_id, NETPROP *prop, int segment, uint8 *property_value, int erase_segments) { - int result = -0xec; /* no such Segment */ + int result = b_acc(obj_id, prop->security, 1); + if (result) return(result); if (!dbminit(FNVAL)){ NETVAL val; int flag = 1; key.dsize = NETVAL_KEY_SIZE; key.dptr = (char*)&val; val.obj_id = obj_id; - val.prop_id = (uint8)prop_id; + val.prop_id = (uint8)prop->id; + result = -0xec; /* no such Segment */ if (segment > 1) { val.segment = segment-1; data = fetch(key); @@ -722,7 +729,7 @@ int nw_write_prop_value(int object_type, if ((result = find_obj_id(&obj, 0)) == 0){ if ((result=find_first_prop_id(&prop, obj.id))==0){ - result=ins_prop_val(obj.id, prop.id, segment_nr, + result=ins_prop_val(obj.id, &prop, segment_nr, property_value, erase_segments); } @@ -745,10 +752,9 @@ int nw_change_prop_security(int object_type, XDPRINTF((2,0, "nw_change_prop_security obj=%s,0x%x, prop=%s", obj.name, object_type, prop.name)); obj.type = (uint16) object_type; - if ((result = find_obj_id(&obj, 0)) == 0){ - result=loc_change_prop_security(&prop, obj.id); - } - return(result); + if ((result = find_obj_id(&obj, 0)) == 0) + return(loc_change_prop_security(&prop, obj.id)); + return(-0xff); } int nw_scan_property(NETPROP *prop, @@ -960,16 +966,18 @@ uint32 nw_new_obj_prop(uint32 wanted_id, uint8 locvalue[128]; memset(locvalue, 0, sizeof(locvalue)); memcpy(locvalue, value, min(sizeof(locvalue), valuesize)); - ins_prop_val(obj.id, prop.id, 1, locvalue, 0xff); + ins_prop_val(obj.id, &prop, 1, locvalue, 0xff); } } return(obj.id); } typedef struct { - int pw_uid; - int pw_gid; - char pw_passwd[80]; + int pw_uid; + int pw_gid; + char pw_passwd[80]; + uint8 pw_dir[257]; + uint8 pw_name[20]; } MYPASSWD; static MYPASSWD *nw_getpwnam(uint32 obj_id) @@ -979,10 +987,13 @@ static MYPASSWD *nw_getpwnam(uint32 obj_id) if (nw_get_prop_val_str(obj_id, "UNIX_USER", buff) > 0){ struct passwd *pw = getpwnam(buff); if (NULL != pw) { - memcpy(&pwstat, pw, sizeof(struct passwd)); + if (obj_id != 1 && pw->pw_uid == 1) + return(NULL); /* only supervisor -> root */ pwstat.pw_uid = pw->pw_uid; pwstat.pw_gid = pw->pw_gid; xstrcpy(pwstat.pw_passwd, pw->pw_passwd); + xstrcpy(pwstat.pw_name, pw->pw_name); + xstrcpy(pwstat.pw_dir, pw->pw_dir); #if SHADOW_PWD if (pwstat.pw_passwd[0] == 'x' && pwstat.pw_passwd[1]=='\0') { struct spwd *spw=getspnam(buff); @@ -998,21 +1009,42 @@ static MYPASSWD *nw_getpwnam(uint32 obj_id) return(NULL); } -int get_guid(int *gid, int *uid, uint32 obj_id) +int get_guid(int *gid, int *uid, uint32 obj_id, uint8 *name) /* searched for gid und uid of actual obj */ { MYPASSWD *pw = nw_getpwnam(obj_id); if (NULL != pw) { *gid = pw->pw_gid; *uid = pw->pw_uid; + if (name) strmaxcpy(name, pw->pw_name, 20); return(0); } else { *gid = -1; *uid = -1; + if (name) strcpy(name, "UNKNOWN"); return(-0xff); } } +int get_home_dir(uint8 *homedir, uint32 obj_id) +/* searches for UNIX homedir of actual obj */ +{ + MYPASSWD *pw = nw_getpwnam(obj_id); + if (NULL != pw) { + int len=strlen(pw->pw_dir); + if (!len) { + *homedir++ = '/'; + *homedir = '\0'; + len =1; + } else + strmaxcpy(homedir, pw->pw_dir, min(255, len)); + return(len); + } else { + *homedir='\0'; + return(0); + } +} + static int crypt_pw_ok(uint8 *password, char *passwd) /* returns 0 if not ok */ { @@ -1221,7 +1253,7 @@ static void add_user(uint32 u_id, uint32 g_id, add_user_to_group(u_id, g_id); if (unname && *unname) nw_new_obj_prop(u_id, NULL, 0 , 0 , 0 , - "UNIX_USER", P_FL_ITEM, 0x33, + "UNIX_USER", P_FL_ITEM, 0x33, (char*)unname, strlen(unname)); if (password && *password) { @@ -1237,7 +1269,7 @@ static void add_group(char *name, char *unname, char *password) (void) nw_new_obj(&g_id, name, 0x2 , 0x0, 0x31); if (unname && *unname) nw_new_obj_prop(g_id, NULL, 0 , 0 , 0 , - "UNIX_GROUP", P_FL_ITEM, 0x33, + "UNIX_GROUP", P_FL_ITEM, 0x33, (char*)unname, strlen(unname)); } @@ -1453,7 +1485,7 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) int gid; int uid; sprintf(sx, "%lx", objs[ocount]); - if (!get_guid(&gid, &uid, objs[ocount])) + if (!get_guid(&gid, &uid, objs[ocount], NULL)) test_add_dir(unixname, ppp, 1, downshift, 0770, gid, uid, sx); else { NETOBJ obj; diff --git a/nwdbm.h b/nwdbm.h index 8dcb8f1..fbcabb5 100644 --- a/nwdbm.h +++ b/nwdbm.h @@ -1,4 +1,4 @@ -/* nwdbm.h 22-Feb-96 */ +/* nwdbm.h 30-Apr-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -68,6 +68,8 @@ extern int password_scheme; #define PW_SCHEME_GET_KEY_FAIL 4 #define PW_SCHEME_ALLOW_EMPTY_PW 8 +/* next routine is in nwbind.c !!!! */ +extern int b_acc(uint32 obj_id, int security, int forwrite); extern void sync_dbm(void); @@ -93,12 +95,6 @@ extern int prop_find_member(uint32 obj_id, int prop_id, uint32 member_id); extern int prop_add_member(uint32 obj_id, int prop_id, uint32 member_id); extern int prop_delete_member(uint32 obj_id, int prop_id, uint32 member_id); - - -extern int ins_prop_val(uint32 obj_id, uint8 prop_id, int segment, - uint8 *property_value, int erase_segments); - - extern int nw_get_prop_val_by_obj_id(uint32 obj_id, int segment_nr, uint8 *prop_name, int prop_namlen, @@ -179,7 +175,8 @@ extern uint32 nw_new_obj_prop(uint32 wanted_id, char *propname, int propflags, int propsecurity, char *value, int valuesize); -extern int get_guid(int *gid, int *uid, uint32 obj_id); +extern int get_guid(int *gid, int *uid, uint32 obj_id, uint8 *name); +extern int get_home_dir(uint8 *homedir, uint32 obj_id); extern int nw_test_passwd(uint32 obj_id, uint8 *vgl_key, uint8 *akt_key); extern int nw_test_unenpasswd(uint32 obj_id, uint8 *password); diff --git a/nwfile.c b/nwfile.c index ffdbc4a..ad77443 100644 --- a/nwfile.c +++ b/nwfile.c @@ -1,4 +1,4 @@ -/* nwfile.c 23-Jan-96 */ +/* nwfile.c 01-May-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -27,12 +27,9 @@ #include "nwfile.h" #include "connect.h" - -#define MAX_FILEHANDLES 80 -static FILE_HANDLE file_handles[MAX_FILEHANDLES]; +static FILE_HANDLE file_handles[MAX_FILE_HANDLES_CONN]; static int anz_fhandles=0; - static int new_file_handle(uint8 *unixname) { int rethandle = -1; @@ -45,7 +42,7 @@ static int new_file_handle(uint8 *unixname) } else fh=NULL; } if (fh == NULL) { - if (anz_fhandles < MAX_FILEHANDLES) { + if (anz_fhandles < MAX_FILE_HANDLES_CONN) { fh=&(file_handles[anz_fhandles]); rethandle = ++anz_fhandles; } else return(0); /* no free handle anymore */ @@ -69,7 +66,7 @@ static int free_file_handle(int fhandle) FILE_HANDLE *fh=&(file_handles[fhandle-1]); if (fh->fd > -1) { if (fh->flags & 2) { - if (fh->f) pclose(fh->f); + if (fh->f) ext_pclose(fh->f); fh->f = NULL; } else close(fh->fd); if (fh->tmodi > 0L && !(fh->flags & 2)) { @@ -107,7 +104,8 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, /* * creatmode: 0 = open | 1 = creat | 2 = creatnew & 4 == save handle * attrib ?? - * access: 0x1=read, 0x2=write + * access: 0x1=readonly, 0x2=writeonly, 0x4=deny read, 0x5=deny write + * */ { int fhandle=new_file_handle(unixname); @@ -115,19 +113,20 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, FILE_HANDLE *fh=&(file_handles[fhandle-1]); int completition = -0xff; /* no File Found */ if (get_volume_options(volume, 1) & VOL_OPTION_IS_PIPE) { - /* this is a PIPE Dir */ + /* this is a PIPE Volume */ int statr = stat(fh->fname, stbuff); if (!statr && (stbuff->st_mode & S_IFMT) != S_IFDIR) { + int dowrite= (access & 2) || creatmode ; char pipecommand[300]; - char *pipeopen = (creatmode || (access & 2)) ? "w" : "r"; - char *topipe = "READ"; - if (creatmode) topipe = "CREAT"; - else if (access & 2) topipe = "WRITE"; + char *topipe = "READ"; + if (creatmode) topipe = "CREAT"; + else if (dowrite) topipe = "WRITE"; sprintf(pipecommand, "%s %s", fh->fname, topipe); - fh->f = popen(pipecommand, pipeopen); - fh->fd = (fh->f) ? fileno(fh->f) : -1; + fh->f = ext_popen(pipecommand, geteuid(), getegid()); + fh->fd = (fh->f) ? fileno(fh->f->fildes[1]) : -1; if (fh->fd > -1) { fh->flags |= 2; + if (!dowrite) stbuff->st_size = 0x7fffffff; if (creatmode & 4) fh->flags |= 4; return(fhandle); } @@ -158,7 +157,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, } } else { int statr = stat(fh->fname, stbuff); - int acm = (access & 2) ? (int) O_RDWR /*|O_CREAT*/ : (int)O_RDONLY; + int acm = (access & 2) ? (int) O_RDWR : (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->fname:%s: fhandle=%d",attrib,access, fh->fname, fhandle)); @@ -203,8 +202,8 @@ int nw_close_datei(int fhandle, int reset_reuse) int result2; if (fh->flags & 2) { if (fh->f) { - result=pclose(fh->f); - if (result) result = -1; + result=ext_pclose(fh->f); + if (result > 0) result = 0; } fh->f = NULL; } else result=close(fh->fd); @@ -241,12 +240,23 @@ int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset) if (fhandle > 0 && (--fhandle < anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fd > -1) { - if (fh->offd != (long)offset) - fh->offd=lseek(fh->fd, offset, SEEK_SET); - if (fh->offd > -1L) { - size = read(fh->fd, data, size); - fh->offd+=(long)size; - } else size = -1; + if (fh->flags & 2) { /* PIPE */ + size = fread(data, 1, size, fh->f->fildes[1]); + } else { + if (fh->offd != (long)offset) { + fh->offd=lseek(fh->fd, offset, SEEK_SET); + if (fh->offd < 0) { + XDPRINTF((5,0,"read-file failed in lseek")); + } + } + if (fh->offd > -1L) { + if ((size = read(fh->fd, data, size)) > -1) + fh->offd+=(long)size; + else { + XDPRINTF((5,0,"read-file failed in read")); + } + } else size = -1; + } return(size); } } @@ -258,12 +268,16 @@ int nw_seek_datei(int fhandle, int modus) if (fhandle > 0 && (--fhandle < anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fd > -1) { - int size=-0xfb; - if (!modus) { - if ( (size=fh->offd=lseek(fh->fd, 0L, SEEK_END)) < 0L) - size = -1; + if (fh->flags & 2) { /* PIPE */ + return(0x7fffffff); + } else { + int size=-0xfb; + if (!modus) { + if ( (size=fh->offd=lseek(fh->fd, 0L, SEEK_END)) < 0L) + size = -1; + } + return(size); } - return(size); } } return(-0x88); /* wrong filehandle */ @@ -275,27 +289,35 @@ int nw_write_datei(int fhandle, uint8 *data, int size, uint32 offset) if (fhandle > 0 && (--fhandle < anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fd > -1) { - if (fh->offd != (long)offset) - fh->offd = lseek(fh->fd, offset, SEEK_SET); - if (size) { - if (fh->offd > -1L) { - size = write(fh->fd, data, size); - fh->offd+=(long)size; - } else size = -1; - return(size); - } else { /* strip FILE */ - /* TODO: for LINUX */ - struct flock flockd; - int result= /* -1 */ 0; - flockd.l_type = 0; - flockd.l_whence = SEEK_SET; - flockd.l_start = offset; - flockd.l_len = 0; -#if HAVE_TLI - result = fcntl(fh->fd, F_FREESP, &flockd); - XDPRINTF((5,0,"File %s is stripped, result=%d", fh->fname, result)); + if (fh->flags & 2) { /* PIPE */ + if (size) + return(fwrite(data, 1, size, fh->f->fildes[0])); + return(0); + } else { + if (fh->offd != (long)offset) + fh->offd = lseek(fh->fd, offset, SEEK_SET); + if (size) { + if (fh->offd > -1L) { + size = write(fh->fd, data, size); + fh->offd+=(long)size; + } 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 - return(result); + XDPRINTF((5,0,"File %s is truncated, result=%d", fh->fname, result)); + fh->offd = -1L; + return(result); + } } } } @@ -321,7 +343,7 @@ int nw_server_copy(int qfhandle, uint32 qoffset, int xsize = read(fhq->fd, buff, min(size, (uint32)sizeof(buff))); if (xsize > 0){ if ((wsize =write(fhz->fd, buff, xsize)) != xsize) { - retsize = -0x1; /* out of Disk SPace */ + retsize = -0x1; /* out of Disk Space */ break; } else { size -= (uint32)xsize; @@ -352,6 +374,7 @@ int nw_lock_datei(int fhandle, int offset, int size, int do_lock) if (fh->fd > -1) { struct flock flockd; int result; + if (fh->flags & 2) return(0); flockd.l_type = (do_lock) ? F_WRLCK : F_UNLCK; flockd.l_whence = SEEK_SET; flockd.l_start = offset; diff --git a/nwfile.h b/nwfile.h index 139d623..846a59a 100644 --- a/nwfile.h +++ b/nwfile.h @@ -1,12 +1,13 @@ /* nwfile.h 23-Jan-96 */ #ifndef _NWFILE_H_ #define _NWFILE_H_ +#include "nwqueue.h" typedef struct { int fd; /* filehandle from system open/creat */ long offd; /* aktuell file offset */ time_t tmodi; /* modification TIME */ - FILE *f; /* for PIPE */ + FILE_PIPE *f; /* for PIPE */ int flags; /* 2 = PIPE */ /* 4 = don't reuse after close */ char fname[256]; /* UNIX filename */ diff --git a/nwqueue.c b/nwqueue.c new file mode 100644 index 0000000..ced863b --- /dev/null +++ b/nwqueue.c @@ -0,0 +1,408 @@ +/* nwconn.c 04-May-96 */ +/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "net.h" +#include +#include "connect.h" +#include "nwfile.h" +#include "nwqueue.h" + +static char **build_argv(char *buf, int bufsize, char *command) +/* routine returns **argv for use with execv routines */ +/* buf will contain the path component */ +{ + int len = strlen(command); + int offset = ((len+4) / 4) * 4; /* aligned offset for **argv */ + int components = (bufsize - offset) / 4; + if (components > 1) { /* minimal argv[0] + NULL */ + char **argv = (char **)(buf+offset); + char **pp = argv; + char *p = buf; + char c; + int i=0; + --components; + memcpy(buf, command, len); + memset(buf+len, 0, bufsize - len); + *pp = p; + while ((0 != (c = *p++)) && i < components) { + if (c == 32 || c == '\t') { + *(p-1) = '\0'; + if (*p != 32 && *p != '\t') { + *(++pp)=p; + i++; + } + } else if (!i && c == '/') { /* here i must get argv[0] */ + *pp=p; + } + } + XDPRINTF((5, 0, "build_argv, path='%s'", buf)); + pp=argv; + while (*pp) { + XDPRINTF((5, 0, "build_argv, argv='%s'", *pp)); + pp++; + } + return(argv); + } + return(NULL); +} + + +static void close_piped(int piped[3][2]) +{ + int j=3; + while (j--) { + int k=2; + while (k--) { + if (piped[j][k] > -1){ + close(piped[j][k]); + piped[j][k] = -1; + } + } + } +} + +static void err_close_pipe(FILE_PIPE *fp, int lpid, int j, int piped[3][2]) +{ + while (j--) if (fp->fildes[j]) fclose(fp->fildes[j]); + close_piped(piped); + kill(lpid, SIGTERM); + kill(lpid, SIGQUIT); + waitpid(lpid, NULL, 0); + kill(lpid, SIGKILL); +} + +static int x_popen(char *command, int uid, int gid, FILE_PIPE *fp) +{ + int piped[3][2]; + int lpid=-1; + int j=3; + char buf[300]; + char **argv=build_argv(buf, sizeof(buf), command); + if (argv == NULL) return(-1); + while (j--){ + int k=2; + while(k--) piped[j][k] = -1; + } + if (! (pipe(&piped[0][0]) > -1 && pipe(&piped[1][0]) > -1 + && pipe(&piped[2][0]) > -1 && (lpid=fork()) > -1)) { + close_piped(piped); + return(-1); + } + if (lpid == 0) { /* Child */ + signal(SIGTERM, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGINT, SIG_DFL); + signal(SIGPIPE, SIG_DFL); + signal(SIGHUP, SIG_DFL); + j=3; + while(j--) close(j); + j=3; + while(j--) { + int x = (j) ? 0 : 1; + int x_ = (j) ? 1 : 0; + close(piped[j][x] ); + dup2( piped[j][x_], j); + close(piped[j][x_] ); + } + if (uid > -1 || gid > -1) { + seteuid(0); + if (gid > -1) setgid(gid); + if (uid > -1) setuid(uid); + if (gid > -1) setegid(gid); + if (uid > -1) seteuid(uid); + } + execvp(buf, argv); + exit(1); /* Never reached I hope */ + } + j=-1; + while (++j < 3) { + int x = (j) ? 0 : 1; + int x_ = (j) ? 1 : 0; + close(piped[j][x_]); + piped [j][x_] = -1; + fp->fildes [j] = fdopen(piped[j][x], ( (j) ? "r" : "w") ); + if (NULL == fp->fildes[j]){ + err_close_pipe(fp, lpid, j+1, piped); + return(-1); + } + } + return(lpid); +} + +int ext_pclose(FILE_PIPE *fp) +{ + int status=-1; + void (*intsave) (int) = signal(SIGINT, SIG_IGN); + void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN); + void (*hupsave) (int) = signal(SIGHUP, SIG_IGN); + int j = 3; + while (j--) if (fp->fildes[j]) fclose(fp->fildes[j]); + /* kill(fp->command_pid, SIGTERM); */ + waitpid(fp->command_pid, &status, 0); + kill(fp->command_pid, SIGKILL); + signal(SIGINT, intsave); + signal(SIGQUIT, quitsave); + signal(SIGHUP, hupsave); + xfree(fp); + return(status); +} + +FILE_PIPE *ext_popen(char *command, int uid, int gid) +{ + FILE_PIPE *fp=(FILE_PIPE*) xcmalloc(sizeof(FILE_PIPE)); + void (*intsave) (int) = signal(SIGINT, SIG_IGN); + void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN); + void (*hupsave) (int) = signal(SIGHUP, SIG_IGN); + if ((fp->command_pid = x_popen(command, uid, gid, fp)) < 0) { + xfree(fp); + fp=NULL; + XDPRINTF((1, 0, "ext_popen failed:command='%s'", command)); + } + signal(SIGINT, intsave); + signal(SIGQUIT, quitsave); + signal(SIGHUP, hupsave); + return(fp); +} + +/* minimal queue handling to enable simple printing */ + +#define MAX_JOBS 5 /* max. open queue jobs for one connection */ +static int anz_jobs=0; + +typedef struct { + uint32 fhandle; + int old_job; /* is old structure */ + union { + QUEUE_JOB n; + QUEUE_JOB_OLD o; + } q; +} INT_QUEUE_JOB; + +INT_QUEUE_JOB *queue_jobs[MAX_JOBS]; + +static INT_QUEUE_JOB *give_new_queue_job(int old_job) +{ + int k=-1; + while (++k < anz_jobs) { + INT_QUEUE_JOB *p=queue_jobs[k]; + if (!p->fhandle) { /* free slot */ + memset(p, 0, sizeof(INT_QUEUE_JOB)); + p->old_job = old_job; + if (old_job) + p->q.o.job_id[0] = k+1; + else + p->q.n.job_id[0] = k+1; + return(p); + } + } + if (anz_jobs < MAX_JOBS) { + INT_QUEUE_JOB **pp=&(queue_jobs[anz_jobs++]); + *pp = (INT_QUEUE_JOB *) xmalloc(sizeof(INT_QUEUE_JOB)); + memset(*pp, 0, sizeof(INT_QUEUE_JOB)); + (*pp)->old_job = old_job; + if (old_job) + (*pp)->q.o.job_id[0] = anz_jobs; + else + (*pp)->q.n.job_id[0] = anz_jobs; + return(*pp); + } + return(NULL); +} + +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, 1); + if (q_id == anz_jobs) { + xfree(*pp); + --anz_jobs; + } else (*pp)->fhandle=0L; + } +} + +static void set_entry_time(uint8 *entry_time) +{ + struct tm *s_tm; + time_t timer; + time(&timer); + s_tm = localtime(&timer); + entry_time[0] = (uint8) s_tm->tm_year; + entry_time[1] = (uint8) s_tm->tm_mon+1; + entry_time[2] = (uint8) s_tm->tm_mday; + entry_time[3] = (uint8) s_tm->tm_hour; + entry_time[4] = (uint8) s_tm->tm_min; + entry_time[5] = (uint8) s_tm->tm_sec; +} + +static int create_queue_file(uint8 *job_file_name, + uint32 q_id, + int jo_id, + int connection, + uint8 *dirname, + int dir_nam_len, + uint8 *job_bez) + +{ + int result; + NW_FILE_INFO fnfo; + *job_file_name + = sprintf((char*)job_file_name+1, "%07lX%d.%03d", q_id, jo_id, connection); + + result=nw_alloc_dir_handle(0, dirname, dir_nam_len, 99, 2, 1); + if (result > -1) + result = nw_creat_open_file(result, job_file_name+1, + (int) *job_file_name, + &fnfo, 0x6, 0x6, 1 | 4); + + XDPRINTF((5,0,"creat queue file bez=`%s` handle=%d", + job_bez, result)); + return(result); +} + + +int nw_creat_queue(int connection, uint8 *queue_id, uint8 *queue_job, + uint8 *dirname, int dir_nam_len, int old_call) +{ + INT_QUEUE_JOB *jo = give_new_queue_job(old_call); + uint32 q_id = GET_BE32(queue_id); + int result = -0xff; + XDPRINTF((5,0,"NW_CREAT_Q:dlen=%d, dirname=%s", dir_nam_len, dirname)); + + if (NULL != jo) { + int jo_id = 0; + if (jo->old_job) { + jo_id = (int) jo->q.o.job_id[0]; + memcpy(&(jo->q.o), queue_job, sizeof(QUEUE_JOB_OLD)); + jo->q.o.job_id[0] = (uint8) jo_id; + jo->q.o.client_connection = (uint8)connection; + jo->q.o.client_task = (uint8)0xfe; /* ?? */ + U32_TO_BE32(1, jo->q.o.client_id); /* SU */ + set_entry_time(jo->q.o.job_entry_time); + jo->q.o.job_typ[0] = 0x0; /* 0xd0;*/ + jo->q.o.job_typ[1] = 0x0; + jo->q.o.job_position = 0x1; + jo->q.o.job_control_flags |= 0x20; + + result = create_queue_file(jo->q.o.job_file_name, + q_id, jo_id, connection, + dirname, dir_nam_len, + jo->q.o.job_bez); + + if (result > -1) { + jo->fhandle = (uint32) result; + U16_TO_BE16(0, jo->q.o.job_file_handle); + U32_TO_BE32(jo->fhandle, jo->q.o.job_file_handle+2); + result = 0; + } + jo->q.o.server_station = 0; + jo->q.o.server_task = 0; + U32_TO_BE32(0, jo->q.o.server_id); + if (!result) memcpy(queue_job, &(jo->q.o), sizeof(QUEUE_JOB_OLD)); + } else { + jo_id = (int) jo->q.n.job_id[0]; + memcpy(&(jo->q.n), queue_job, sizeof(QUEUE_JOB)); + jo->q.n.job_id[0] = (uint8) jo_id; + + U16_TO_BE16(0xffff, jo->q.n.record_in_use); + U32_TO_BE32(0x0, jo->q.n.record_previous); + U32_TO_BE32(0x0, jo->q.n.record_next); + memset(jo->q.n.client_connection, 0, 4); + jo->q.n.client_connection[0] = (uint8)connection; + memset(jo->q.n.client_task, 0, 4); + jo->q.n.client_task[0] = (uint8)0xfe; /* ?? */ + U32_TO_BE32(1, jo->q.n.client_id); /* SU */ + set_entry_time(jo->q.n.job_entry_time); + + jo->q.n.job_typ[0] = 0x0; /* 0xd0;*/ + jo->q.n.job_typ[1] = 0x0; + jo->q.n.job_position[0] = 0x1; + jo->q.n.job_position[1] = 0x0; + jo->q.n.job_control_flags[0] |= 0x20; + jo->q.n.job_control_flags[1] = 0x0; + + result = create_queue_file(jo->q.n.job_file_name, + q_id, jo_id, connection, + dirname, dir_nam_len, + jo->q.n.job_bez); + + if (result > -1) { + jo->fhandle = (uint32) result; + U32_TO_BE32(jo->fhandle, jo->q.n.job_file_handle); + result = 0; + } + U32_TO_BE32(0, jo->q.n.server_station); + U32_TO_BE32(0, jo->q.n.server_task); + U32_TO_BE32(0, jo->q.n.server_id); + if (!result) memcpy(queue_job, &(jo->q.n), sizeof(QUEUE_JOB)); + } + if (result) free_queue_job(jo_id); + } + return(result); +} + +int nw_close_file_queue(uint8 *queue_id, + uint8 *job_id, + uint8 *prc, int prc_len) +{ + int result = -0xff; + int jo_id = (int) *job_id; /* ever only the first byte */ + XDPRINTF((5,0,"nw_close_file_queue JOB=%d", jo_id)); + if (jo_id > 0 && jo_id <= anz_jobs){ + INT_QUEUE_JOB *jo=queue_jobs[jo_id-1]; + int fhandle = (int)jo->fhandle; + char unixname[300]; + strmaxcpy((uint8*)unixname, (uint8*)file_get_unix_name(fhandle), sizeof(unixname)-1); + XDPRINTF((5,0,"nw_close_file_queue fhandle=%d", fhandle)); + if (*unixname) { + char printcommand[256]; + FILE *f=NULL; + strmaxcpy((uint8*)printcommand, prc, prc_len); + nw_close_datei(fhandle, 1); + jo->fhandle = 0L; + if (NULL != (f = fopen(unixname, "r"))) { + int is_ok = 0; + FILE_PIPE *fp = ext_popen(printcommand, geteuid(), getegid()); + if (fp) { + char buff[1024]; + int k; + is_ok++; + while ((k = fread(buff, 1, sizeof(buff), f)) > 0) { + if (1 != fwrite(buff, k, 1, fp->fildes[0])) { + XDPRINTF((1,0,"Cannot write to pipe `%s`", printcommand)); + is_ok=0; + } + } + if (ext_pclose(fp)) { + XDPRINTF((1,0,"Error by closing print pipe")); + } + } else + XDPRINTF((1,0,"Cannot open pipe `%s`", printcommand)); + fclose(f); + if (is_ok) { + unlink(unixname); + result=0; + } + } else XDPRINTF((1,0,"Cannot open queue-file `%s`", unixname)); + } else + XDPRINTF((2,0,"fhandle=%d NOT OK !", fhandle)); + free_queue_job(jo_id); + } + return(result); +} diff --git a/nwqueue.h b/nwqueue.h new file mode 100644 index 0000000..eee5267 --- /dev/null +++ b/nwqueue.h @@ -0,0 +1,92 @@ +/* nwqueue.h 04-May-96 */ +#ifndef _NWQUEUE_H_ +#define _NWQUEUE_H_ + +/* enhanced pipe handling */ +typedef struct { + FILE *fildes[3]; /* filedescriptor to 0,1,2 of new process */ + int command_pid; /* pid of piped command */ +} FILE_PIPE; + +extern int ext_pclose(FILE_PIPE *fp); +extern FILE_PIPE *ext_popen(char *command, int uid, int gid); + +/* queues */ +typedef struct { + uint8 record_in_use[2]; + uint8 record_previous[4]; + uint8 record_next[4]; + uint8 client_connection[4]; + uint8 client_task[4]; + 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_id[4]; /* ?? alles 0 HI-LOW */ + uint8 job_typ[2]; /* z.B. Printform HI-LOW */ + uint8 job_position[2]; /* ?? alles 0 low-high ? */ + uint8 job_control_flags[2]; /* z.B 0x10, 0x00 */ + /* 0x80 operator hold flag */ + /* 0x40 user hold flag */ + /* 0x20 entry open flag */ + /* 0x10 service restart flag */ + /* 0x08 autostart flag */ + + uint8 job_file_name[14]; /* len + DOS filename */ + uint8 job_file_handle[4]; + uint8 server_station[4]; + uint8 server_task[4]; + uint8 server_id[4]; + uint8 job_bez[50]; /* "LPT1 Catch" */ + uint8 client_area[152]; +} QUEUE_JOB; + +typedef struct { + uint8 client_connection; + uint8 client_task; + 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_id[2]; /* ?? alles 0 HI-LOW */ + uint8 job_typ[2]; /* z.B. Printform HI-LOW */ + uint8 job_position; /* zero */ + uint8 job_control_flags; /* z.B 0x10 */ + /* 0x80 operator hold flag */ + /* 0x40 user hold flag */ + /* 0x20 entry open flag */ + /* 0x10 service restart flag */ + /* 0x08 autostart flag */ + + uint8 job_file_name[14]; /* len + DOS filename */ + uint8 job_file_handle[6]; + uint8 server_station; + uint8 server_task; + uint8 server_id[4]; + uint8 job_bez[50]; /* "LPT1 Catch" */ + uint8 client_area[152]; +} QUEUE_JOB_OLD; /* before 3.11 */ + +typedef struct { + uint8 version; /* normal 0x0 */ + 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 bannner_header_file_name[14]; /* all zero */ + uint8 file_path_name[80]; /* all zero */ +} QUEUE_PRINT_AREA; + +extern int nw_creat_queue(int connection, uint8 *queue_id, uint8 *queue_job, + uint8 *dirname, int dir_nam_len, int old_call); + +extern int nw_close_file_queue(uint8 *queue_id, + uint8 *job_id, + uint8 *prc, int prc_len); +#endif diff --git a/nwroute.c b/nwroute.c index d869070..2215044 100644 --- a/nwroute.c +++ b/nwroute.c @@ -1,4 +1,4 @@ -/* nwroute.c 09-Mar-96 */ +/* nwroute.c 24-Apr-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -19,13 +19,12 @@ #include "net.h" #include "nwserv.h" - typedef struct { - uint32 net; /* destnet */ - uint16 hops; /* hops to net */ + uint32 net; /* destnet */ + uint16 hops; /* hops to net over rnet */ uint16 ticks; /* ticks to net, ether 1/hop, isdn 7/hop */ - uint32 rnet; /* net of forw. router */ - uint8 rnode[IPX_NODE_SIZE]; /* node of forw. router */ + uint32 rnet; /* net of forw. router */ + uint8 rnode[IPX_NODE_SIZE]; /* node of forw. router */ } NW_ROUTES; static int anz_routes=0; @@ -50,9 +49,11 @@ static void insert_delete_net(uint32 destnet, uint16 ticks, int do_delete) /* delete == 1 */ { - int k=-1; - int freeslot=-1; - NW_ROUTES *nr=NULL; + int k = -1; + int freeslot = -1; + NW_ROUTES *nr = NULL; + NW_NET_DEVICE *nd_dev = NULL; + int ndticks = 99; XDPRINTF((3,0,"%s net:0x%X, over 0x%X, 0x%02x:%02x:%02x:%02x:%02x:%02x", (do_delete) ? "DEL" : "INS", destnet, rnet, @@ -63,20 +64,26 @@ static void insert_delete_net(uint32 destnet, while (++k < anz_net_devices) { NW_NET_DEVICE *nd=net_devices[k]; - if (nd->net == destnet && (do_delete || (nd->ticks <= ticks))) return; + if (nd->is_up) { + if (nd->net == destnet) { + if (!do_delete) return; /* don't route device */ + nd_dev = nd; + } + if (nd->net == rnet) ndticks=nd->ticks; + } } + if (!do_delete && nd_dev && nd_dev->ticks <= ndticks) return; k=-1; while (++k < anz_routes && nw_routes[k]->net != destnet) { - XDPRINTF((3,0, "NET 0x%x is routed", nw_routes[k]->net)); - if (freeslot < 0 && !nw_routes[k]->net) freeslot=k; + if (freeslot < 0 && !nw_routes[k]->net) freeslot=k; } if (k == anz_routes) { /* no route slot found */ if (do_delete) return; /* nothing to delete */ if (freeslot < 0) { if (anz_routes == MAX_NW_ROUTES) { - XDPRINTF((1, 0, "too many routes=%d, increase MAX_NW_ROUTES in config.h", anz_routes)); + XDPRINTF((1, 0, "too many routes > %d, increase MAX_NW_ROUTES in config.h", anz_routes)); return; } nw_routes[k] = (NW_ROUTES*)xmalloc(sizeof(NW_ROUTES)); @@ -94,6 +101,12 @@ static void insert_delete_net(uint32 destnet, XDPRINTF((2,0,"ROUTE DEL NET=0x%x over Router NET 0x%x", nr->net, rnet)); ipx_route_del(nr->net); + if (nd_dev != NULL) { /* this is net to our device */ + /* I must delete and setup new, because there is */ + /* no direct way to delete this route from interface :( */ + exit_dev(nd_dev->devname, nd_dev->frame); + init_dev(nd_dev->devname, nd_dev->frame, nd_dev->net); + } nr->net = 0L; } else { XDPRINTF((3,0,"ROUTE NOT deleted NET=0x%x, RNET=0x%x", @@ -101,9 +114,10 @@ static void insert_delete_net(uint32 destnet, } return; } else nr=nw_routes[k]; + + ticks+=ndticks; if (ticks <= nr->ticks) { - if (ticks > nr->ticks) return; - if (ticks == nr->ticks && hops > nr->hops) return; + if (ticks == nr->ticks && hops >= nr->hops) return; nr->hops = hops; nr->ticks = ticks; nr->rnet = rnet; @@ -122,12 +136,11 @@ NW_NET_DEVICE *find_netdevice(uint32 network) { uint32 net=network; int l=2; - XDPRINTF((3, 0, "find_netdevice of network=%lX", net)); while (l--) { int k=-1; while (++k < anz_net_devices) { NW_NET_DEVICE *nd=net_devices[k]; - if (nd->net == net) { + if (nd->is_up && nd->net == net) { XDPRINTF((3, 0, "found netdevive %s, frame=%d, ticks=%d", nd->devname, nd->frame, nd->ticks)); return(nd); @@ -142,6 +155,17 @@ NW_NET_DEVICE *find_netdevice(uint32 network) return(NULL); } +static NW_NET_DEVICE *find_device_by_net(uint32 net) +/* return the device of this net I hope */ +{ + int k=-1; + while (++k < anz_net_devices) { + NW_NET_DEVICE *nd=net_devices[k]; + if (nd->is_up && nd->net == net) return(nd); + } + return(NULL); +} + void insert_delete_server(uint8 *name, /* Server Name */ int styp, /* Server Typ */ ipxAddr_t *addr, /* Server Addr */ @@ -178,7 +202,7 @@ void insert_delete_server(uint8 *name, /* Server Name */ if (freeslot < 0) { if (anz_servers == MAX_NW_SERVERS) { - XDPRINTF((1, 0, "too many servers=%d, increase MAX_NW_SERVERS in config.h", anz_servers)); + XDPRINTF((1, 0, "too many servers > %d, increase MAX_NW_SERVERS in config.h", anz_servers)); return; } nw_servers[k] = (NW_SERVERS*)xcmalloc(sizeof(NW_SERVERS)); @@ -191,7 +215,7 @@ void insert_delete_server(uint8 *name, /* Server Name */ } else if (do_delete) { nr=nw_servers[k]; -#if !FILE_SERVER_INACTIV +#if !IN_NWROUTED if (!IPXCMPNODE(nr->addr.node, my_server_adr.node) || !IPXCMPNET (nr->addr.net, my_server_adr.net) ) #endif @@ -203,11 +227,12 @@ void insert_delete_server(uint8 *name, /* Server Name */ } return; } else nr=nw_servers[k]; + /* here now i perhaps must change the entry */ if (nr->hops > 16 || memcmp(&(nr->addr), addr, sizeof(ipxAddr_t))) { ins_del_bind_net_addr(nr->name, nr->typ, addr); memcpy(&(nr->addr), addr, sizeof(ipxAddr_t)); -#if !FILE_SERVER_INACTIV +#if !IN_NWROUTED if (IPXCMPNODE(from_addr->node, my_server_adr.node) && IPXCMPNET (from_addr->net, my_server_adr.net) && GET_BE16(from_addr->sock) == SOCK_SAP) { @@ -216,76 +241,84 @@ void insert_delete_server(uint8 *name, /* Server Name */ #endif } if (hops <= nr->hops && 0 != (net = GET_BE32(from_addr->net)) ) { + if (nr->net && nr->net != net && nr->hops >= hops) { + NW_NET_DEVICE *nrd=find_device_by_net(nr->net); + NW_NET_DEVICE *nnd=find_device_by_net(net); + if (nrd && nnd && nrd->ticks < nnd->ticks) return; + } nr->net = net; nr->hops = hops; } } -static uint32 rnet=0L; +static uint32 rnet=0L; /* Router NET */ +static int rmode; /* 0=normal, 1=shutdown response */ + /* 10=request */ + static int rentries=0; -static int rmode; /* 0=normal, 1=shutdown, 10=request */ -static uint8 rip_buff[402]; /* operation + max. 50 RIPS */ +static uint8 rip_buff[2 + MAX_RIP_ENTRIES * 8]; + /* operation + max. 50 RIPS */ static void init_rip_buff(uint32 net, int mode) { - rnet=net; - rentries=0; - rmode=mode; + rnet = net; + rentries = 0; + rmode = mode; U16_TO_BE16((mode > 9) ? 1 : 2, rip_buff); /* rip request or response */ } static void ins_rip_buff(uint32 net, uint16 hops, uint16 ticks) { - if ( net && rentries < 50 && - (net != rnet || (!rentries && net == internal_net))) { - uint8 *p=rip_buff+2+(rentries*8); - U32_TO_BE32(net, p); - U16_TO_BE16(hops, p+4); - U16_TO_BE16(ticks, p+6); - rentries++; + if (!net) return; + if (net != rnet || (!rentries && net == internal_net)) { + if (rentries < MAX_RIP_ENTRIES) { + uint8 *p=rip_buff+2+(rentries*8); + U32_TO_BE32(net, p); + U16_TO_BE16(hops, p+4); + U16_TO_BE16(ticks, p+6); + rentries++; + } else { + XDPRINTF((1, 0, "too many rips > %d, increase MAX_RIP_ENTRIES in config.h", MAX_RIP_ENTRIES)); + } } } -static void build_rip_buff(uint32 destnet, int to_internal_net) -/* to_internal_net = request from dosemu etc. */ +static void build_rip_buff(uint32 destnet) { int is_wild = (destnet==MAX_U32); int is_response = (rmode < 10); int k; - if (!destnet) return; if (is_wild) rentries=0; - if (is_response) { if (is_wild || internal_net == destnet) { ins_rip_buff(internal_net, (rmode==1) ? 16 : 1, (rnet==internal_net) ? 1 : 2); } + k=-1; while (++k < anz_net_devices) { NW_NET_DEVICE *nd=net_devices[k]; - if (is_wild || nd->net == destnet) + if (nd->is_up && (is_wild || nd->net == destnet)) ins_rip_buff(nd->net, (rmode==1) ? 16 : 1, nd->ticks+1); } } + k=-1; while (++k < anz_routes) { NW_ROUTES *nr=nw_routes[k]; -#if 0 - if ( (is_wild || nr->net == destnet) && - (rmode==1 || nr->hops < 2 || to_internal_net) ) -#else - if (is_wild || (nr->net == destnet)) -#endif - ins_rip_buff(nr->net, (rmode==1) ? 16 : nr->hops, nr->ticks); + if (nr->rnet != rnet && (is_wild || (nr->net == destnet)) ) + ins_rip_buff(nr->net, (rmode==1) ? 16 : nr->hops+1, nr->ticks+1); } } static void send_rip_buff(ipxAddr_t *from_addr) { - if (rentries > 0) { - int datasize=(rentries*8)+2; + while (rentries > 0) { + int entries = min(rentries, 50); + int datasize = (entries*8)+2; ipxAddr_t to_addr; + rentries -= entries; if (from_addr) memcpy(&to_addr, from_addr, sizeof(ipxAddr_t)); else { memset(&to_addr, 0, sizeof(ipxAddr_t)); @@ -298,9 +331,9 @@ static void send_rip_buff(ipxAddr_t *from_addr) uint8 *p = rip_buff; int operation = GET_BE16(p); XDPRINTF((2,0, "Send Rip %s entries=%d", - (operation==1) ? "Request" : "Response", rentries)); + (operation==1) ? "Request" : "Response", entries)); p+=2; - while (rentries--) { + while (entries--) { #if 0 uint32 net = GET_BE32(p); #endif @@ -311,26 +344,28 @@ static void send_rip_buff(ipxAddr_t *from_addr) p+=8; } } - send_ipx_data(sockfd[RIP_SLOT], 1, datasize, (char *)rip_buff, &to_addr, "SEND RIP"); - rentries=0; - } + + if (rentries > 0) + memcpy(rip_buff+2, rip_buff+2+50*8, min(50, rentries)*8); + } /* while */ + rentries=0; } static void send_rip_broadcast(int mode) /* mode=0, standard broadcast */ /* mode=1, first trie */ -/* mode=2, shutdown */ +/* mode=2, shutdown */ { int k=-1; while (++k < anz_net_devices) { NW_NET_DEVICE *nd=net_devices[k]; - if (nd->ticks < 7) { /* isdn devices should not get RIP broadcasts everytime */ + if (nd->is_up && nd->ticks < 7) { /* isdn devices should not get RIP broadcasts everytime */ init_rip_buff(nd->net, (mode == 2) ? 1 : 0); - build_rip_buff(MAX_U32, 0); + build_rip_buff(MAX_U32); send_rip_buff(NULL); } } @@ -341,7 +376,7 @@ void rip_for_net(uint32 net) int k=-1; while (++k < anz_net_devices) { NW_NET_DEVICE *nd=net_devices[k]; - if (nd->ticks < 7) { /* isdn devices should not get RIP broadcasts everytime */ + if (nd->is_up && nd->ticks < 7) { /* isdn devices should not get RIP broadcasts everytime */ init_rip_buff(nd->net, 10); ins_rip_buff(net, MAX_U16, MAX_U16); send_rip_buff(NULL); @@ -350,8 +385,11 @@ void rip_for_net(uint32 net) } void handle_rip(int fd, int ipx_pack_typ, - int data_len, IPX_DATA *ipxdata, - ipxAddr_t *from_addr) + int data_len, IPX_DATA *ipxdata, + ipxAddr_t *from_addr) + +/* All received rip packeta reach this function */ +/* It can be a RIP Request or a RIP Respons */ { int operation = GET_BE16(ipxdata->rip.operation); int entries = (data_len-2) / 8; @@ -379,9 +417,9 @@ void handle_rip(int fd, int ipx_pack_typ, if (is_response) { insert_delete_net(net, GET_BE32(from_addr->net), - from_addr->node, hops+1, ticks+1, (hops > 15) ? 1 : 0); + from_addr->node, hops, ticks, (hops > 15) ? 1 : 0); } else { /* rip request */ - build_rip_buff(net, GET_BE32(from_addr->net)==internal_net); + build_rip_buff(net); if (net == MAX_U32) break; } p+=8; @@ -420,28 +458,29 @@ void send_server_response(int respond_typ, NW_SERVERS *nw=nw_servers[entry]; strcpy((char*)ipx_data.sip.server_name, nw->name); memcpy(&ipx_data.sip.server_adr, &nw->addr, sizeof(ipxAddr_t)); - XDPRINTF((4, 0, "NEAREST SERVER=%s, typ=0x%x, tics=%d, hops=%d", + hops++; + XDPRINTF((4, 0, "NEAREST SERVER=%s, typ=0x%x, ticks=%d, hops=%d", nw->name, styp, tics, hops)); U16_TO_BE16(respond_typ, ipx_data.sip.response_type); U16_TO_BE16(styp, ipx_data.sip.server_type); U16_TO_BE16(hops, ipx_data.sip.intermediate_networks); send_ipx_data(sockfd[SAP_SLOT], 4, /* this is the official packet typ for SAP's */ - sizeof(ipx_data.sip), - (char *)&(ipx_data.sip), - to_addr, "Nearest Server Response"); + sizeof(ipx_data.sip), + (char *)&(ipx_data.sip), + to_addr, "Nearest Server Response"); } } static void send_sap_broadcast(int mode) /* mode=0, standard broadcast */ /* mode=1, first trie */ -/* mode=2, shutdown */ +/* mode=2, shutdown */ { int k=-1; while (++k < anz_net_devices) { NW_NET_DEVICE *nd=net_devices[k]; - if (nd->ticks < 7 || mode) { + if (nd->is_up && (nd->ticks < 7 || mode)) { /* isdn devices should not get SAP broadcasts everytime */ IPX_DATA ipx_data; ipxAddr_t wild; @@ -454,7 +493,7 @@ static void send_sap_broadcast(int mode) NW_SERVERS *nw=nw_servers[j]; if ( !nw->typ /* server has no typ */ || ( nw->net == nd->net && nw->hops) /* server has same net but */ - /* hops */ + /* hops */ || ( mode == 2 && nw->hops) ) { /* no SAP to this NET */ XDPRINTF((3, 0, "No SAP mode=%d, to net=0x%lx for server '%s'", mode, nd->net, nw->name)); @@ -475,9 +514,9 @@ static void send_sap_broadcast(int mode) } send_ipx_data(sockfd[SAP_SLOT], 4, /* this is the official packet typ for SAP's */ - sizeof(ipx_data.sip), - (char *)&(ipx_data.sip), - &wild, "SIP Broadcast"); + sizeof(ipx_data.sip), + (char *)&(ipx_data.sip), + &wild, "SIP Broadcast"); } } } @@ -498,10 +537,55 @@ static FILE *open_route_info_fn(void) return(f); } +void print_routing_info(void) +{ + FILE *f= open_route_info_fn(); + if (f) { + int k=-1; + fprintf(f, "<--------- Devices ---------------->\n"); + fprintf(f, "%-15s %-15s %5s Network Status\n", "DevName", "Frame", "Ticks"); + while (++k < anz_net_devices) { + uint8 frname[30]; + NW_NET_DEVICE *nd=net_devices[k]; + (void) get_frame_name(frname, nd->frame); + fprintf(f, "%-15s %-15s %5d %08lX %s\n", + nd->devname, frname, nd->ticks, nd->net, + (!nd->is_up) ? "DOWN" + : ( (nd->is_up==1) ? "UP" + : "ADDED") ); + } + fprintf(f, "<--------- Routing Table ---------->\n"); + fprintf(f, "%8s Hops Ticks %9s Router Node\n", "Network", "RouterNet"); + k=-1; + while (++k < anz_routes) { + NW_ROUTES *nr = nw_routes[k]; + if (nr->net) { + fprintf(f, "%08lX %4d %5d %08lX %02x:%02x:%02x:%02x:%02x:%02x\n", + nr->net, nr->hops, nr->ticks, nr->rnet, + (int)nr->rnode[0], (int)nr->rnode[1], (int)nr->rnode[2], + (int)nr->rnode[3], (int)nr->rnode[4], (int)nr->rnode[5]); + } + } + k=-1; + fprintf(f, "<--------- Server Table ---------->\n"); + fprintf(f, "%-20s %4s %9s Hops Server-Address\n","Name", "Typ", "RouterNet"); + while (++k < anz_servers) { + NW_SERVERS *ns = nw_servers[k]; + if (ns->typ) { + char sname[50]; + strmaxcpy(sname, ns->name, 20); + fprintf(f, "%-20s %4d %08lX %4d %s\n", sname, ns->typ, + ns->net, ns->hops, xvisable_ipx_adr(&(ns->addr), 1)); + } + } /* while */ + fclose(f); + } +} + void send_sap_rip_broadcast(int mode) /* mode=0, standard broadcast */ /* mode=1, first trie */ -/* mode=2, shutdown */ +/* mode=2, shutdown */ { static int flipflop=1; if (mode) { @@ -516,36 +600,7 @@ static int flipflop=1; flipflop=1; } } - if (!mode && flipflop) { /* jedes 2. mal */ - FILE *f= open_route_info_fn(); - if (f) { - int k=-1; - fprintf(f, "<--------- Routing Table ---------->\n"); - fprintf(f, "%8s Hops Tics %9s Router Node\n", "Network", "RouterNet"); - while (++k < anz_routes) { - NW_ROUTES *nr = nw_routes[k]; - if (nr->net) { - fprintf(f, "%08lX %4d %4d %08lX %02x:%02x:%02x:%02x:%02x:%02x\n", - nr->net, nr->hops, nr->ticks, nr->rnet, - (int)nr->rnode[0], (int)nr->rnode[1], (int)nr->rnode[2], - (int)nr->rnode[3], (int)nr->rnode[4], (int)nr->rnode[5]); - } - } - k=-1; - fprintf(f, "<--------- Server Table ---------->\n"); - fprintf(f, "%-20s %4s %9s Hops Server-Address\n","Name", "Typ", "RouterNet"); - while (++k < anz_servers) { - NW_SERVERS *ns = nw_servers[k]; - if (ns->typ) { - char sname[50]; - strmaxcpy(sname, ns->name, 20); - fprintf(f, "%-20s %4d %08lX %4d %s\n", sname, ns->typ, - ns->net, ns->hops, xvisable_ipx_adr(&(ns->addr), 1)); - } - } /* while */ - fclose(f); - } - } + if (flipflop) print_routing_info(); /* every second time */ } static void query_sap_on_net(uint32 net) @@ -568,14 +623,15 @@ void get_servers(void) int k=-1; while (++k < anz_net_devices) { NW_NET_DEVICE *nd=net_devices[k]; - if (nd->ticks < 7) query_sap_on_net(nd->net); /* only fast routes */ + if (nd->is_up && nd->ticks < 7) + query_sap_on_net(nd->net); /* only fast routes */ } if (!anz_net_devices) query_sap_on_net(internal_net); } int dont_send_wdog(ipxAddr_t *addr) -/* returns != 0 if tics are to high for wdogs */ +/* returns != 0 if ticks are to high for wdogs */ { NW_NET_DEVICE *nd; if (!wdogs_till_tics) return(0); /* ever send wdogs */ @@ -585,3 +641,92 @@ int dont_send_wdog(ipxAddr_t *addr) return(0); } +/* ---------------------------------------------------- */ +int test_ins_device_net(uint32 rnet) +{ + int rnetframe; + uint8 rnetdevname[100]; + int k = -1; + int foundfree=-1; /* first matching/free entry */ + NW_NET_DEVICE *nd; + if (!rnet || rnet == internal_net) return(0); + while (++k < anz_net_devices) { + nd=net_devices[k]; + if (!nd->is_up) { + if (nd->net == rnet) { + foundfree = k; + break; + } else if (foundfree < 0 && !nd->net) + foundfree = k; + } else if (nd->net == rnet) return(0); + } + if ((rnetframe=get_interface_frame_name(rnetdevname, rnet)) < 0) + return(0); + + if (foundfree > -1 && (net_devices[foundfree])->net != rnet) { + int devfound = -1; + int framefound = -1; + k = foundfree - 1; + foundfree = -1; + while (++k < anz_net_devices) { + nd = net_devices[k]; + if (!nd->is_up && !nd->net) { + int dfound = !strcmp(nd->devname, rnetdevname); + int ffound = nd->frame == rnetframe; + if (dfound && ffound) { + devfound = k; + framefound = k; + break; + } else { + if (dfound) { + if (devfound < 0 && nd->frame < 0) + devfound =k; + } else if (ffound) { + if (framefound < 0 && nd->devname[0] == '*') + framefound=k; + } else if (nd->frame < 0 && nd->devname[0] == '*') { + if (foundfree < 0) + foundfree = k; + } + } + } + } + if (devfound > -1) foundfree = devfound; + else if (framefound > -1) foundfree = framefound; + } + + if ( foundfree < 0 ) { + if (anz_net_devices < MAX_NET_DEVICES) { + NW_NET_DEVICE **pnd=&(net_devices[anz_net_devices++]); + nd=*pnd= (NW_NET_DEVICE*)xmalloc(sizeof(NW_NET_DEVICE)); + memset(nd, 0, sizeof(NW_NET_DEVICE)); + nd->ticks = 1; + } else { + XDPRINTF((1, 0, "too many devices > %d, increase MAX_NET_DEVICES in config.h", anz_net_devices)); + return(0); + } + } else { + nd = net_devices[foundfree]; + } + nd->net = rnet; + nd->frame = rnetframe; + new_str(nd->devname, rnetdevname); + nd->is_up = 2; + /* now perhaps i must delete an existing route over */ + /* another device */ + + k = -1; + while (++k < anz_routes) { + NW_ROUTES *nr = nw_routes[k]; + if (nr->net == rnet) { + ipx_route_del(nr->net); + nr->net = 0L; + /* I must delete and setup new, because there is */ + /* no direct way to delete this route from interface :( */ + exit_dev(nd->devname, nd->frame); + init_dev(nd->devname, nd->frame, nd->net); + break; + } + } + return(1); +} diff --git a/nwroute1.c b/nwroute1.c index 4482a37..25bf791 100644 --- a/nwroute1.c +++ b/nwroute1.c @@ -125,6 +125,11 @@ void get_servers(void) #endif } +void print_routing_info(void) +{ +;; /* DUMMY */ +} + void send_sap_rip_broadcast(int mode) /* mode=0, standard broadcast */ /* mode=1, first trie */ diff --git a/nwrouted.c b/nwrouted.c new file mode 100644 index 0000000..6dcb935 --- /dev/null +++ b/nwrouted.c @@ -0,0 +1,4 @@ +/* nwrouted.c */ +#define IN_NWROUTED 1 +#include "nwroute.c" +#include "nwserv.c" diff --git a/nwserv.c b/nwserv.c index 8c9c359..03d589a 100644 --- a/nwserv.c +++ b/nwserv.c @@ -1,4 +1,6 @@ -/* nwserv.c 20-Mar-96 */ +/* nwserv.c 03-May-96 */ +/* MAIN Prog for NWSERV + NWROUTED */ + /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -20,6 +22,9 @@ #include "nwserv.h" uint32 internal_net = 0x0L; /* NETWORKNUMMER INTERN (SERVER) */ +int no_internal = 0; /* no use of internal net */ +int auto_creat_interfaces=0; + ipxAddr_t my_server_adr; /* Address of this server */ char my_nwname[50]; /* Name of this server */ int print_route_tac = 0; /* every x broadcasts print it */ @@ -57,7 +62,7 @@ uint16 ipx_sock_nummern[]={ SOCK_AUTO /* WDOG */ }; #define NEEDED_SOCKETS (sizeof(ipx_sock_nummern) / sizeof(uint16)) -#if FILE_SERVER_INACTIV +#if IN_NWROUTED # define NEEDED_POLLS (NEEDED_SOCKETS+1) #else # define NEEDED_POLLS (NEEDED_SOCKETS+2) @@ -91,6 +96,14 @@ static int save_ipx_routes = 0; static uint8 *station_fn=NULL; static int nearest_request_flag=0; +#if IN_NWROUTED +static char *prog_name_typ="ROUTER"; +#define IN_PROG NWROUTED +#else +static char *prog_name_typ="SERVER"; +#define IN_PROG NWSERV +#endif + static void add_wdata(IPX_DATA *d, char *data, int size) { memcpy(d->owndata.d.data+d->owndata.d.size, data, size); @@ -149,7 +162,7 @@ static void write_to_sons(int what, int connection, write_wdata(&ipxd, what, sock); } -#if !FILE_SERVER_INACTIV +#if !IN_NWROUTED # define write_to_ncpserv(what, connection, data, data_size) \ write_to_sons((what), (connection), (data), (data_size), SOCK_NCP) #else @@ -215,7 +228,7 @@ static int open_ipx_socket(uint16 sock_nr, int nr, int open_mode) static int start_ncpserv(char *nwname, ipxAddr_t *addr) { -#if !FILE_SERVER_INACTIV +#if !IN_NWROUTED int fds_in[2]; int pid; if (pipe(fds_in) < 0) return(-1); @@ -255,7 +268,7 @@ static int start_ncpserv(char *nwname, ipxAddr_t *addr) static int start_nwbind(char *nwname, ipxAddr_t *addr) { -#if !FILE_SERVER_INACTIV +#if !IN_NWROUTED int fds_in[2]; int pid; struct t_bind bind; @@ -322,7 +335,7 @@ static int start_nwbind(char *nwname, ipxAddr_t *addr) return(0); /* OK */ } - +#if !IN_NWROUTED static int start_nwclient(void) { switch (fork()){ @@ -342,6 +355,7 @@ static int start_nwclient(void) } return(0); /* OK */ } +#endif /* =========================== WDOG =============================== */ #ifndef _WDOG_TESTING_ @@ -481,6 +495,7 @@ void get_server_data(char *name, ipxAddr_t *adr, ipxAddr_t *from_addr) { +#if !IN_NWROUTED if (!nw386_found && strcmp(name, my_nwname)) { memcpy(&nw386_adr, adr, sizeof(ipxAddr_t)); nw386_found++; @@ -489,6 +504,7 @@ void get_server_data(char *name, client_mode = 0; /* only start once */ } } +#endif XDPRINTF((2,0,"NW386 %s found at:%s", name, visable_ipx_adr(adr))); } @@ -588,7 +604,8 @@ static void handle_sap(int fd, uint8 *name = p+2; ipxAddr_t *ad = (ipxAddr_t*) (p+50); int hops = GET_BE16(p+ sizeof(SAPS) -2); - if (hops < 16) U16_TO_BE16(hops+1, p+ sizeof(SAPS) -2); + /* if (hops < 16) U16_TO_BE16(hops+1, p+ sizeof(SAPS) -2); */ + /* if (hops < 16) hops++; */ XDPRINTF((2,0, "TYP=%2d,hops=%2d, Addr=%s, Name=%s", type, hops, visable_ipx_adr(ad), name)); @@ -752,6 +769,8 @@ static void handle_event(int fd, uint16 socknr, int slot) /* it also can be Packets from DOSEMU OR ncpfs on this machine */ XDPRINTF((2,0,"Packet from OWN maschine:sock=0x%x", source_sock)); } + if (auto_creat_interfaces && test_ins_device_net(GET_BE32(source_adr.net))) + broadmillisecs = 3000; /* now faster rip/sap to new devices */ #endif switch (slot) { @@ -844,11 +863,19 @@ static void get_ini(int full) if (sscanf(inhalt, "%ld%c", &nd->net, &dummy) != 1) sscanf(inhalt, "%lx", &nd->net); + + if (nd->net == internal_net) { + errorp(11, "Get_ini", "device net 0x%lx = internal net", nd->net); + exit(1); + } + if (anz > 1) new_str(nd->devname, inhalt2); if (anz > 2) { upstr(inhalt3); + if (!strcmp(inhalt3, "AUTO")) + nd->frame=-1; if (!strcmp(inhalt3, "802.3")) nd->frame=IPX_FRAME_8023; else if (!strcmp(inhalt3, "802.2")) @@ -857,6 +884,10 @@ static void get_ini(int full) nd->frame=IPX_FRAME_SNAP; else if (!strcmp(inhalt3, "ETHERNET_II")) nd->frame=IPX_FRAME_ETHERII; +# ifdef IPX_FRAME_TR_8022 + else if (!strcmp(inhalt3, "TOKEN")) + nd->frame=IPX_FRAME_TR_8022; +# endif } if (anz > 3) nd->ticks = atoi(inhalt4); } @@ -866,11 +897,13 @@ static void get_ini(int full) case 5 : save_ipx_routes=atoi(inhalt); break; #endif + +#if !IN_NWROUTED case 104 : /* nwclient */ if (client_mode && atoi(inhalt)) client_mode++; break; - +#endif case 210 : server_goes_down_secs=atoi(inhalt); if (server_goes_down_secs < 1 || server_goes_down_secs > 600) @@ -919,29 +952,47 @@ static void get_ini(int full) if (full) { #ifdef LINUX # if INTERNAL_RIP_SAP + no_internal = !internal_net; + if (no_internal && anz_net_devices > 1) { + errorp(11, "Get_ini", "No internal net, but more than 1 Device specified"); + exit(1); + } init_ipx(internal_net, node, ipxdebug); + for (k=0; k < anz_net_devices; k++){ NW_NET_DEVICE *nd=net_devices[k]; - char *frname=NULL; - switch (nd->frame) { - case IPX_FRAME_8022 : frname = "802.2"; break; - case IPX_FRAME_8023 : frname = "802.3"; break; - case IPX_FRAME_SNAP : frname = "SNAP"; break; - case IPX_FRAME_ETHERII : frname = "ETHERNET_II";break; - default : break; - } /* switch */ - XDPRINTF((1, 0, "DEVICE=%s, FRAME=%s, NETWORK=0x%lx", - nd->devname, frname, nd->net)); - init_dev(nd->devname, nd->frame, nd->net); + int result; + uint8 frname[30]; + char *sp = "DEVICE=%s, FRAME=%s, NETWORK=0x%lx"; + (void) get_frame_name(frname, nd->frame); + XDPRINTF((1, 0, sp, nd->devname, frname, nd->net)); + if ((result= init_dev(nd->devname, nd->frame, nd->net)) < 0) { + if (result == -99) { + errorp(11, "init_dev", "AUTO device is only in combination with internal net allowed"); + exit(1); + } else + errorp(1, "init_dev", sp, nd->devname, frname, nd->net); + } else if (!result) + nd->is_up = 1; + else auto_creat_interfaces=1; } # endif #endif - if (!get_ipx_addr(&my_server_adr)) { internal_net = GET_BE32(my_server_adr.net); } else exit(1); - XDPRINTF((1, 0, "Servername='%s', INTERNAL NET=0x%lx, NODE=0x%02x:%02x:%02x:%02x:%02x:%02x", - my_nwname, internal_net, + +#if LINUX && INTERNAL_RIP_SAP + if (no_internal) { + errorp(10, "WARNING:No use of internal net", NULL); + } else if (!anz_net_devices) { + errorp(10, "WARNING:No external devices specified", NULL); + } + print_routing_info(); +#endif + + XDPRINTF((1, 0, "%s name='%s', INTERNAL NET=0x%lx, NODE=0x%02x:%02x:%02x:%02x:%02x:%02x", + prog_name_typ, my_nwname, internal_net, (int)my_server_adr.node[0], (int)my_server_adr.node[1], (int)my_server_adr.node[2], @@ -982,9 +1033,9 @@ static void close_all(void) close(fd_nwbind_in); fd_nwbind_in = -1; } - kill(pid_nwbind, SIGQUIT); /* terminate ncpserv */ + kill(pid_nwbind, SIGQUIT); /* terminate nwbind */ waitpid(pid_nwbind, &status, 0); - kill(pid_nwbind, SIGKILL); /* kill ncpserv */ + kill(pid_nwbind, SIGKILL); /* kill nwbind */ } #ifdef LINUX @@ -992,9 +1043,11 @@ static void close_all(void) if (!save_ipx_routes) { for (j=0; jis_up) { + XDPRINTF((1, 0, "Close Device=%s, frame=%d", nd->devname, nd->frame)); - exit_dev(nd->devname, nd->frame); + exit_dev(nd->devname, nd->frame); + } } } exit_ipx(!save_ipx_routes); @@ -1011,8 +1064,8 @@ static void down_server(void) signal(SIGPIPE, SIG_IGN); fprintf(stderr, "\007"); fprintf(stderr, "\n*********************************************\n"); - fprintf(stderr, "\nWARNING: NWE-SERVER shuts down in %3d sec !!!\n", - server_goes_down_secs); + fprintf(stderr, "\nWARNING: NWE-%s shuts down in %3d sec !!!\n", + prog_name_typ, server_goes_down_secs); fprintf(stderr, "\n*********************************************\n"); sleep(1); fprintf(stderr, "\007\n"); @@ -1033,7 +1086,7 @@ static void sig_quit(int rsig) static void handle_hup_reqest(void) { - get_ini_debug(NWSERV); + get_ini_debug(IN_PROG); XDPRINTF((2,0, "Got HUP, reading ini.")); get_ini(0); write_to_ncpserv(0xeeee, 0, NULL, 0); /* inform ncpserv */ @@ -1060,14 +1113,25 @@ static int server_is_down=0; int main(int argc, char **argv) { - int j = -1; + int j = 0; + int init_mode=0; tzset(); - if (argc > 1) client_mode=1; + while (++j < argc) { + char *a=argv[j]; + if (*a == '-') { + while (*(++a)) { + switch (*a) { + case 'h' : init_mode = 1; break; + case 'k' : init_mode = 2; break; + default : break; + } + } + } else if (*a == 'y') client_mode=1; /* in client mode the testprog 'nwclient' will be startet. */ - - init_tools(NWSERV, 0); + } + init_tools(IN_PROG, init_mode); get_ini(1); - + j=-1; while (++j < NEEDED_POLLS) { polls[j].events = POLLIN|POLLPRI; polls[j].revents = 0; @@ -1092,10 +1156,13 @@ int main(int argc, char **argv) /* now do polling */ time_t broadtime; time(&broadtime); + set_sigs(); + creat_pidfile(); + polls[NEEDED_SOCKETS].fd = fd_nwbind_in; -#if !FILE_SERVER_INACTIV +#if !IN_NWROUTED { ipxAddr_t server_adr_sap; polls[NEEDED_SOCKETS+1].fd = fd_ncpserv_in; @@ -1106,6 +1173,7 @@ int main(int argc, char **argv) &my_server_adr, &server_adr_sap, 0, 0, 0); } #endif + while (!server_is_down) { int anz_poll = poll(polls, NEEDED_POLLS, broadmillisecs); int call_wdog=0; @@ -1144,7 +1212,7 @@ int main(int argc, char **argv) (char*)&conn, sizeof(int)) && sizeof(int) == read(p->fd, (char*)&size, sizeof(int)) - && sizeof(ipxAddr_t) + sizeof(uint16) + && sizeof(ipxAddr_t) + sizeof(uint16) + sizeof(uint32) == read(p->fd, (char*)buf, size)) { insert_wdog_conn(conn, (ipxAddr_t*)buf); @@ -1228,7 +1296,8 @@ int main(int argc, char **argv) send_down_broadcast(); } close_all(); - fprintf(stderr, "\nNWE-SERVER is down now !!\n"); + fprintf(stderr, "\nNWE-%s is down now !!\n", prog_name_typ); + exit_tools(); return(0); } diff --git a/nwserv.h b/nwserv.h index 4fbb324..c2b8793 100644 --- a/nwserv.h +++ b/nwserv.h @@ -1,4 +1,4 @@ -/* nwserv.h 30-Jan-96 */ +/* nwserv.h 26-Apr-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -15,20 +15,24 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - +#ifndef _M_NWSERV_H_ +#define _M_NWSERV_H_ extern uint32 internal_net; /* NETWORKNUMMER INTERN (SERVER) */ -extern ipxAddr_t my_server_adr; /* Address of this server */ -extern char my_nwname[50]; /* Name of this server */ +extern int no_internal; /* no use of internal net */ +extern int auto_creat_interfaces; +extern ipxAddr_t my_server_adr; /* Address of this server */ +extern char my_nwname[50]; /* Name of this server */ extern int print_route_tac; /* every x broadcasts print it */ -extern int print_route_mode; /* append */ -extern char *pr_route_info_fn; /* filename */ +extern int print_route_mode; /* append */ +extern char *pr_route_info_fn; /* filename */ extern int wdogs_till_tics; typedef struct { - char *devname; /* "eth0" or "isdnX" */ - int frame; /* frametyp */ + char *devname; /* "eth0" or "isdnX" or ?? */ + int frame; /* frametyp */ int ticks; /* ether:ticks=1, isdn:ticks=7 */ - uint32 net; /* NETWORK NUMBER */ + uint32 net; /* NETWORK NUMBER */ + int is_up; /* Is this device up ? */ } NW_NET_DEVICE; /* <========== DEVICES ==========> */ @@ -55,13 +59,14 @@ extern void ins_del_bind_net_addr(uint8 *name, int styp, ipxAddr_t *adr); extern void send_server_response(int respond_typ, int styp, ipxAddr_t *to_addr); +extern void print_routing_info(void); extern void send_sap_rip_broadcast(int mode); extern void rip_for_net(uint32 net); extern void get_servers(void); extern void handle_rip(int fd, int ipx_pack_typ, - int data_len, IPX_DATA *ipxdata, - ipxAddr_t *from_addr); + int data_len, IPX_DATA *ipxdata, + ipxAddr_t *from_addr); extern void insert_delete_server(uint8 *name, @@ -73,4 +78,5 @@ extern void insert_delete_server(uint8 *name, int flags); extern int dont_send_wdog(ipxAddr_t *addr); - +extern int test_ins_device_net(uint32 rnet); +#endif diff --git a/nwvolume.c b/nwvolume.c index 0190109..434f6dc 100644 --- a/nwvolume.c +++ b/nwvolume.c @@ -1,5 +1,5 @@ -/* nwvolume.c 20-Mar-96 */ -/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany +/* nwvolume.c 22-Apr-96 */ +/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -62,44 +62,79 @@ void nw_init_volumes(FILE *f) 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((char*)unixname); - if (unixname[len-1] != '/') { + NW_VOL *vol=&(nw_volumes[used_nw_volumes]); + vol->options = 0; + new_str(vol->sysname, sysname); + if (1 == (len = strlen((char*)unixname)) && unixname[0] == '~') { + vol->options |= VOL_OPTION_IS_HOME; + unixname[0] = '\0'; + len = 0; + } else 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); + vol->unixnamlen = len; + new_str(vol->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 'k' : vol->options + |= VOL_OPTION_DOWNSHIFT; + break; - case 'p' : nw_volumes[used_nw_volumes].options - |= VOL_OPTION_IS_PIPE; break; + case 'm' : vol->options + |= VOL_OPTION_REMOUNT; + break; - case 'm' : nw_volumes[used_nw_volumes].options - |= VOL_OPTION_REMOUNT; break; + case 'o' : vol->options + |= VOL_OPTION_ONE_DEV; + break; + + case 'p' : vol->options + |= VOL_OPTION_IS_PIPE; + break; default : break; } } } used_nw_volumes++; + if (vol->options & VOL_OPTION_ONE_DEV) { + vol->max_maps_count = 1; + vol->high_inode = 0xffffffff; + } else { + vol->max_maps_count = MAX_DEV_NAMESPACE_MAPS; + vol->high_inode = 0xfffffff; + } + } } } /* while */ } +void nw_setup_home_vol(int len, uint8 *fn) +{ + int k=used_nw_volumes; + uint8 unixname[258]; + unixname[0] = '\0'; + if (len > 0) { + strmaxcpy(unixname, fn, len); + if (unixname[len-1] != '/') { + unixname[len++] = '/'; + unixname[len] = '\0'; + } + } + while (k--) { + if (nw_volumes[k].options & VOL_OPTION_IS_HOME) { + nw_volumes[k].unixnamlen = len; + new_str(nw_volumes[k].unixname, unixname); + } + } +} -static int look_name_space_map(int volume, DEV_NAMESPACE_MAP *dnm, +static int look_name_space_map(NW_VOL *v, 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) { @@ -107,31 +142,35 @@ static int look_name_space_map(int volume, DEV_NAMESPACE_MAP *dnm, if (mp->dev == dnm->dev && mp->namespace == dnm->namespace) return(k); } - if (do_insert && v->maps_count < MAX_DEV_NAMESPACE_MAPS) { + if (do_insert && v->maps_count < v->max_maps_count) { /* 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); + return(-1); } 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); + if (volume > -1 && volume < used_nw_volumes) { + NW_VOL *v= &(nw_volumes[volume]); + if (inode > 0 && inode <= v->high_inode) { + int result = look_name_space_map(v, dnm, 1); + if (result > -1) { + uint32 handle = (v->options & VOL_OPTION_ONE_DEV) + ? (uint32)inode + : (((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)); + XDPRINTF((1,0, "Cannot map inode=%d, dev=%d, namespace=%d to vol=%d handle", + inode, dnm->dev, dnm->namespace, volume)); return(0L); } @@ -141,16 +180,17 @@ ino_t nw_vol_handle_to_inode(int volume, uint32 handle, { if (handle > 0 && volume > -1 && volume < used_nw_volumes) { NW_VOL *v= &(nw_volumes[volume]); - int entry = (int) ((handle >> 28) & 0xFF); + int entry = (v->options & VOL_OPTION_ONE_DEV) + ? 0 + : (int) ((handle >> 28) & 0xF); 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), + XDPRINTF((3, 0, "vol=%d, handle=0x%x to ino=%d, dev=%d, namespace=%d", + volume, handle, (int)(handle & v->high_inode), v->dev_namespace_maps[entry]->dev, v->dev_namespace_maps[entry]->namespace)); - return((ino_t) (handle & 0xFFFFFF)); + return((ino_t) (handle & v->high_inode)); } } XDPRINTF((1, 0, "Can't vol=%d, handle=0x%x to inode", volume, handle)); diff --git a/nwvolume.h b/nwvolume.h index 7661ad9..0745082 100644 --- a/nwvolume.h +++ b/nwvolume.h @@ -1,4 +1,4 @@ -/* nwvolume.h 07-Feb-96 */ +/* nwvolume.h 29-Mar-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,7 @@ #ifndef _NWVOLUME_H_ #define _NWVOLUME_H_ -#define MAX_DEV_NAMESPACE_MAPS 256 +#define MAX_DEV_NAMESPACE_MAPS 16 typedef struct { int dev; @@ -32,17 +32,21 @@ typedef struct { */ typedef struct { - uint8 *sysname; /* VOL_NAME */ - uint8 *unixname; /* UNIX-DIR */ - int unixnamlen; /* len of unixname */ + uint8 *sysname; /* VOL_NAME */ + uint8 *unixname; /* UNIX-DIR */ + 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_* all is lowercase */ + int max_maps_count; /* may be less than MAX_DEV_NAMESPACE_MAPS */ + int maps_count; /* count of dev_namespace_maps */ + uint32 high_inode; /* hight inode to can handle correct */ + int options; /* *_1_* all is lowercase */ } NW_VOL; -#define VOL_OPTION_DOWNSHIFT 1 -#define VOL_OPTION_IS_PIPE 2 /* Volume has only pipes */ -#define VOL_OPTION_REMOUNT 4 /* Volume can be remounted (cdroms) */ +#define VOL_OPTION_DOWNSHIFT 0x01 /* All downshift */ +#define VOL_OPTION_IS_PIPE 0x02 /* Volume contains pipes */ +#define VOL_OPTION_REMOUNT 0x04 /* Volume can be remounted (cdroms) */ +#define VOL_OPTION_IS_HOME 0x08 /* Volume is USERS HOME */ +#define VOL_OPTION_ONE_DEV 0x10 /* Volume has only one filesys */ /* stolen from GNU-fileutils */ /* Space usage statistics for a filesystem. Blocks are 512-byte. */ @@ -58,6 +62,7 @@ extern NW_VOL nw_volumes[MAX_NW_VOLS]; extern int used_nw_volumes; extern void nw_init_volumes(FILE *f); +extern void nw_setup_home_vol(int len, uint8 *fn); extern int nw_get_volume_number(uint8 *volname, int namelen); extern int nw_get_volume_name(int volnr, uint8 *volname); extern int nw_get_fs_usage(uint8 *volname, struct fs_usage *fsu); diff --git a/tools.c b/tools.c index 9504a9f..c65f49c 100644 --- a/tools.c +++ b/tools.c @@ -1,4 +1,4 @@ -/* tools.c 20-Mar-96 */ +/* tools.c 06-May-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -20,9 +20,8 @@ #include #ifndef LINUX -#include -extern int _sys_nerr; -extern char _sys_errlist[]; +extern int _sys_nerr; +extern char *_sys_errlist[]; #endif @@ -33,13 +32,14 @@ static int in_module=0; /* in which process i am ? */ static int connection=0; /* which connection (nwconn) */ static int my_pid = -1; static void (*sigsegv_func)(int isig); -static char *modnames[] = -{ "???????", - "NWSERV ", +static char *modnames[] = +{ "?", + "NWSERV", "NCPSERV", - "NWCONN ", - "NWCLIEN", - "NWBIND " }; + "NWCONN", + "NWCLIENT", + "NWBIND", + "NWROUTED" }; static char *get_modstr(void) { @@ -93,7 +93,7 @@ void dprintf(char *p, ...) { va_list ap; if (nw_debug){ - fprintf(logfile, "%s:", get_modstr()); + fprintf(logfile, "%-8s:", get_modstr()); va_start(ap, p); vfprintf(logfile, p, ap); va_end(ap); @@ -107,7 +107,7 @@ void xdprintf(int dlevel, int mode, char *p, ...) { va_list ap; if (nw_debug >= dlevel) { - if (!(mode & 1)) fprintf(logfile, "%s %d:", get_modstr(), connection); + if (!(mode & 1)) fprintf(logfile, "%-8s %d:", get_modstr(), connection); if (p) { va_start(ap, p); vfprintf(logfile, p, ap); @@ -123,12 +123,20 @@ void errorp(int mode, char *what, char *p, ...) va_list ap; int errnum = errno; FILE *lologfile = logfile; + char errbuf[200]; + char *errstr = errbuf; + if (mode > 9) { + errnum = -1; + mode -= 10; + } + if (errnum >= 0 && errnum < _sys_nerr) errstr = _sys_errlist[errnum]; + else if (errnum > -1) + sprintf(errbuf, "errno=%d", errnum); + else + errbuf[0] = '\0'; while (1) { - if (mode==1) fprintf(lologfile, "\n!! %s %d:PANIC !!\n", get_modstr(), connection); - if (errnum >= 0 && errnum < _sys_nerr) - fprintf(lologfile, "%s %d:%s:%s\n", get_modstr(), connection, what, _sys_errlist[errnum]); - else - fprintf(lologfile, "%s %d:%s:errno=%d\n", get_modstr(), connection, what, errnum); + if (mode==1) fprintf(lologfile, "\n!! %-8s %d:PANIC !!\n", get_modstr(), connection); + fprintf(lologfile, "%-8s %d:%s:%s\n", get_modstr(), connection, what, errstr); if (p) { va_start(ap, p); vfprintf(lologfile, p, ap); @@ -193,9 +201,24 @@ int get_ini_entry(FILE *f, int entry, uint8 *str, int strsize) return(0); } -char *get_exec_path(char *buff, char *progname) +char *get_div_pathes(char *buff, char *name, int what, char *p, ... ) { - sprintf(buff, "%s/%s", PATHNAME_PROGS, progname); + char *wpath; + int len; + switch (what) { + case 0 : wpath = PATHNAME_PROGS; break; + case 1 : wpath = PATHNAME_BINDERY; break; + case 2 : wpath = PATHNAME_PIDFILES; break; + default : buff[0]='\0'; + return(buff); + } + len=sprintf(buff, (name && *name) ? "%s/%s" : "%s/", wpath, name); + if (NULL != p) { + va_list ap; + va_start(ap, p); + vsprintf(buff+len, p, ap); + va_end(ap); + } return(buff); } @@ -214,6 +237,8 @@ void get_ini_debug(int module) * 2 = ncpserv * 3 = nwconn * 4 = nwclient + * 5 = nwbind + * 6 = nwrouted */ { int debug = get_ini_int(100+module); @@ -226,42 +251,96 @@ static void sig_segv(int isig) XDPRINTF((0, 0, s, my_pid)); fprintf(stderr, "\n"); fprintf(stderr, s, my_pid); -#if 1 +#if 0 (*sigsegv_func)(isig); #endif } -void init_tools(int module, int conn) +static int fn_exist(char *fn) { - uint8 buff[300]; - char logfilename[300]; + struct stat stb; + return((stat(fn, &stb) == -1) ? 0 : stb.st_mode); +} + +static char *get_pidfilefn(char *buf) +{ + char lbuf[100]; + strcpy(lbuf, get_modstr()); + return(get_div_pathes(buf, downstr((uint8*)lbuf), 2, ".pid")); +} + +void creat_pidfile(void) +{ + char buf[300]; + char *pidfn=get_pidfilefn(buf); + FILE *f=fopen(pidfn, "w"); + if (f != NULL) { + fprintf(f, "%d\n", getpid()); + fclose(f); + } else { + XDPRINTF((1, 0, "Cannot creat pidfile=%s", pidfn)); + } +} + +void init_tools(int module, int options) +{ + uint8 buf[300]; + char logfilename[300]; FILE *f=open_nw_ini(); - int withlog=0; - int dodaemon=0; - int new_log=0; + int withlog=0; + int dodaemon=0; + int new_log=0; in_module = module; - connection = conn; + connection = (NWCONN == module) ? options : 0; + if (NWSERV == module || NWROUTED == module) { + char *pidfn=get_pidfilefn(buf); + if (fn_exist(pidfn)) { + int sig; + FILE *pf; + if (options == 1) { /* kill -HUP prog */ + sig = SIGHUP; + } else if (options == 2) { /* kill prog */ + sig = SIGTERM; + } else { + errorp(11, "INIT", "Program allways running or pidfn=%s exists" , + pidfn); + exit(1); + } + if ( NULL != (pf=fopen(pidfn, "r"))) { + int kill_pid=0; + if (1 == fscanf(pf, "%d", &kill_pid) && kill_pid > 1) + kill(kill_pid, sig); + fclose(pf); + exit(0); + } + exit(1); + } else if (options == 1 || options == 2) { + errorp(11, "INIT", "Program not running or pidfn=%s not exists" , + pidfn); + exit(1); + } + } if (f) { int what; - while (0 != (what=get_ini_entry(f, 0, buff, sizeof(buff)))) { /* daemonize */ - if (200 == what) dodaemon = atoi((char*)buff); + while (0 != (what=get_ini_entry(f, 0, buf, sizeof(buf)))) { /* daemonize */ + if (200 == what) dodaemon = atoi((char*)buf); else if (201 == what) { - strmaxcpy((uint8*)logfilename, (uint8*)buff, sizeof(logfilename)-1); + strmaxcpy((uint8*)logfilename, (uint8*)buf, sizeof(logfilename)-1); withlog++; } else if (202 == what) { - new_log = atoi((char*)buff); - } else if (100+module == what) nw_debug=atoi((char*)buff); + new_log = atoi((char*)buf); + } else if (100+module == what) nw_debug=atoi((char*)buf); } fclose(f); } if (dodaemon) { if (!withlog) strcpy(logfilename, "./nw.log"); - if (NWSERV == module) { /* now make daemon */ + if (NWSERV == module || NWROUTED == module) { /* now make daemon */ int fd=fork(); if (fd) exit((fd > 0) ? 0 : 1); } if (NULL == (logfile = fopen(logfilename, - (new_log && NWSERV == module) ? "w" : "a"))) { + (new_log && (NWSERV == module || NWROUTED == module)) ? "w" : "a"))) { char sxx[100]; sprintf(sxx, "\n\nOpen logfile `%s`", logfilename); perror(sxx); @@ -269,19 +348,25 @@ void init_tools(int module, int conn) fprintf(stderr, "\n!! ABORTED !!\n"); exit(1); } - if (NWSERV == module) setsid(); + if (NWSERV == module || NWROUTED == module) setsid(); } - if (NWSERV == module || NCPSERV == module || NWBIND == module || - nw_debug > 1) { + if ( NWCONN != module || nw_debug > 1 ) { XDPRINTF((1, 0, "Starting Version: %d.%02dpl%d", _VERS_H_, _VERS_L_, _VERS_P_ )); } - sigsegv_func = signal(SIGSEGV, sig_segv); +#if 1 + if (nw_debug < 8) + sigsegv_func = signal(SIGSEGV, sig_segv); +#endif my_pid = getpid(); } -void exit_tools(int what) +void exit_tools(void) { + if (in_module == NWSERV || in_module == NWROUTED) { + char buf[300]; + unlink(get_pidfilefn(buf)); + } if (logfile != stdout) { if (logfile != NULL) fclose(logfile); logfile=stdout; @@ -312,17 +397,19 @@ uint8 up_char(uint8 ch) return(ch); } -uint8 *upstr(uint8 *s) +uint8 *upstr(uint8 *ss) { + uint8 *s=ss; if (!s) return((uint8*)NULL); for (;*s;s++) *s=up_char(*s); - return(s); + return(ss); } -uint8 *downstr(uint8 *s) +uint8 *downstr(uint8 *ss) { + uint8 *s=ss; if (!s) return((uint8*)NULL); for (;*s;s++) *s=down_char(*s); - return(s); + return(ss); } diff --git a/tools.h b/tools.h index 1066780..bb88d01 100644 --- a/tools.h +++ b/tools.h @@ -1,4 +1,4 @@ -/* tools.h : 20-Mar-96 */ +/* tools.h : 01-May-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * @@ -25,6 +25,7 @@ #define NWCONN 3 #define NWCLIENT 4 #define NWBIND 5 +#define NWROUTED 6 extern FILE *logfile; extern void x_x_xfree(char **p); @@ -44,15 +45,19 @@ extern void xdprintf(int dlevel, int mode, char *p, ...); extern void errorp(int mode, char *what, char *p, ...); extern FILE *open_nw_ini(void); extern int get_ini_entry(FILE *f, int entry, uint8 *str, int strsize); -extern char *get_exec_path(char *buff, char *progname); +extern char *get_div_pathes(char *buff, char *name, int what, char *p, ... ); +#define get_exec_path(bu, progn) get_div_pathes((bu), (progn), 0, NULL) + extern int get_ini_int(int what); extern void get_ini_debug(int what); -extern void init_tools(int module, int conn); +extern void creat_pidfile(void); +extern void init_tools(int module, int options); +extern void exit_tools(void); extern uint8 down_char(uint8 ch); extern uint8 up_char(uint8 ch); -extern uint8 *downstr(uint8 *s); -extern uint8 *upstr(uint8 *s); +extern uint8 *downstr(uint8 *ss); +extern uint8 *upstr(uint8 *ss); extern int nw_debug; diff --git a/unxfile.c b/unxfile.c new file mode 100644 index 0000000..dde917d --- /dev/null +++ b/unxfile.c @@ -0,0 +1,54 @@ +/* unxfile.c: 29-Apr-96*/ + +/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "net.h" +#include "unxfile.h" + +#if 1 +int unx_mvdir(uint8 *oldname, uint8 *newname) +{ + struct stat statb; + if (!stat(newname, &statb)) return(EEXIST); + if (stat(oldname, &statb)) return(-1); + else if (!S_ISDIR(statb.st_mode)) return(-1); + return( (rename(oldname, newname) < 0) ? errno : 0); +} + +int unx_mvfile(uint8 *oldname, uint8 *newname) +{ + struct stat statb; + if (!stat(newname, &statb)) return(EEXIST); + if (stat(oldname, &statb)) return(-1); + else if (S_ISDIR(statb.st_mode)) return(-1); + return( (rename(oldname, newname) < 0) ? errno : 0); +} + +#else +int unx_mvdir(uint8 *oldname, uint8 *newname) +{ + uint8 command[500]; + struct stat statb; + if (!stat(newname, &statb)) return(EEXIST); + if (stat(oldname, &statb)) return(-1); + else if (!S_ISDIR(statb.st_mode)) return(-1); + sprintf(command, "mv %s %s 2>&1 >/dev/null" , oldname, newname); + return(system(command)); +} +#endif + diff --git a/unxfile.h b/unxfile.h new file mode 100644 index 0000000..40a81aa --- /dev/null +++ b/unxfile.h @@ -0,0 +1,22 @@ +/* unxfile.h: 29-Apr-96*/ + +/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +extern int unx_mvdir(uint8 *oldname, uint8 *newname); +extern int unx_mvfile(uint8 *oldname, uint8 *newname); + diff --git a/unxlog.c b/unxlog.c new file mode 100644 index 0000000..941e45a --- /dev/null +++ b/unxlog.c @@ -0,0 +1,77 @@ +/* unxlog.c : 30-Apr-96 */ +/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include "net.h" +#include "unxlog.h" + +void write_utmp(int dologin, int connection, int pid, + ipxAddr_t *from_addr, uint8 *username) +{ + struct utmp loc_ut; + struct utmp *ut; + int fd; + char buff[200]; + int found = 0; + char *fn_utmp=FILENAME_UTMP; + char *fn_wtmp=FILENAME_WTMP; + if (NULL == fn_utmp) return; + + utmpname(fn_utmp); + setutent(); + sprintf(buff, "NCP%03d", connection); + while (NULL != (ut = getutent())) { + if (pid == ut->ut_pid || + !strncmp(buff, ut->ut_line, sizeof(ut->ut_line))) { + found++; + break; + } + } + + if (!found) { + if (!dologin) { + endutent(); + return; + } else { + ut=&loc_ut; + memset(ut, 0, sizeof(struct utmp)); + } + } + ut->ut_type = dologin ? USER_PROCESS : DEAD_PROCESS; + + if (dologin) { + strncpy(ut->ut_line, buff, sizeof(ut->ut_line)); + ut->ut_pid = pid; + sprintf(buff, "%d", connection); + strncpy(ut->ut_id, buff, sizeof(ut->ut_id)); + if (username) strncpy((char*)ut->ut_user, (char*)username, sizeof(ut->ut_user)); +#ifdef LINUX + ut->ut_addr = (long) GET_BE32(from_addr->net); + strncpy(ut->ut_host, xvisable_ipx_adr(from_addr, 2), sizeof(ut->ut_host)); +#endif + } else { + memset(ut->ut_user, 0, sizeof(ut->ut_user)); + ut->ut_pid = 0; + } + (void)time(&(ut->ut_time)); + pututline(ut); + endutent(); + if (NULL == fn_wtmp) return; + if ((fd = open(fn_wtmp, O_APPEND|O_WRONLY)) > -1) { + write(fd, (char *)ut, sizeof(struct utmp)); + close(fd); + } +} diff --git a/unxlog.h b/unxlog.h new file mode 100644 index 0000000..20f49b8 --- /dev/null +++ b/unxlog.h @@ -0,0 +1,5 @@ +/* unxlog.h */ +extern void write_utmp(int dologin, int connection, int pid, + ipxAddr_t *from_addr, uint8 *username); + +