mars_nwe-0.97.pl03
This commit is contained in:
parent
55682d7171
commit
da30e32a01
5
Makefile
5
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 $@
|
||||
|
||||
|
4
README
4
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".
|
||||
|
||||
|
||||
|
||||
|
||||
|
329
connect.c
329
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 <dirent.h>
|
||||
#include <utime.h>
|
||||
|
||||
#include <sys/errno.h>
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
94
connect.h
94
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; /* f<>r 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, /* zus„tzlicher Pfad */
|
||||
int len); /* L„nge 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, /* zus„tzl. 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);
|
||||
|
23
doc/CHANGES
23
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.
|
||||
|
||||
|
14
doc/FAQS
Normal file
14
doc/FAQS
Normal file
@ -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.
|
||||
|
34
doc/FRAGEN
Normal file
34
doc/FRAGEN
Normal file
@ -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.
|
||||
|
||||
|
||||
|
100
doc/FRAGEN.erik
Normal file
100
doc/FRAGEN.erik
Normal file
@ -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...
|
||||
|
||||
|
||||
|
||||
|
19
doc/INSTALL
19
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.
|
||||
|
@ -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.
|
||||
|
17
doc/NEWS
17
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'
|
||||
|
70
doc/PIPE-FS
Normal file
70
doc/PIPE-FS
Normal file
@ -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)
|
||||
|
69
doc/PIPE-FS.ger
Normal file
69
doc/PIPE-FS.ger
Normal file
@ -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
|
||||
|
@ -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
|
||||
|
271
emutli.c
271
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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@ -42,32 +35,27 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
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);
|
||||
|
36
emutli.h
36
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
|
||||
|
391
emutli1.c
Normal file
391
emutli1.c
Normal file
@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/sockios.h>
|
||||
#include "net.h"
|
||||
#include <linux/if.h>
|
||||
#include <linux/route.h>
|
||||
#include <linux/in.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
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);
|
||||
}
|
40
emutli1.h
Normal file
40
emutli1.h
Normal file
@ -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
|
7
examples/README.kpatch1.2.13
Normal file
7
examples/README.kpatch1.2.13
Normal file
@ -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
|
||||
|
@ -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)
|
@ -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 */
|
||||
|
||||
|
||||
|
122
examples/kpatch1.2.13
Normal file
122
examples/kpatch1.2.13
Normal file
@ -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 */
|
74
examples/kpatch1.3.78
Normal file
74
examples/kpatch1.3.78
Normal file
@ -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)
|
||||
{
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
39
makefile.unx
39
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))
|
||||
|
447
namspace.c
447
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;
|
||||
|
||||
|
@ -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
|
||||
|
21
ncpserv.c
21
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",
|
||||
|
80
net.h
80
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 <sys/tiuser.h>
|
||||
#endif
|
||||
|
||||
#include "sys/fcntl.h"
|
||||
#include "sys/types.h"
|
||||
#include "unistd.h"
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <utmp.h>
|
||||
|
||||
#include <sys/errno.h>
|
||||
extern int errno;
|
||||
|
||||
#ifndef LINUX
|
||||
# include "stropts.h"
|
||||
# include "poll.h"
|
||||
# include "sys/nwctypes.h"
|
||||
# include "sys/stream.h"
|
||||
# include <stropts.h>
|
||||
# include <poll.h>
|
||||
# include <sys/nwctypes.h>
|
||||
# include <sys/stream.h>
|
||||
/* # include "common.h" */
|
||||
/* # include "portable.h" , needed ??? */
|
||||
# include "sys/ipx_app.h"
|
||||
# include <sys/ipx_app.h>
|
||||
|
||||
#else
|
||||
# include <sys/ioctl.h>
|
||||
# include "emutli.h" /* TLI-EMULATION */
|
||||
# include "emutli1.h" /* TLI-EMULATION */
|
||||
#endif
|
||||
|
||||
#include <pwd.h>
|
||||
@ -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 {
|
||||
|
4
net1.c
4
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)");
|
||||
|
171
nwbind.c
171
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));
|
||||
|
85
nwconn.c
85
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;
|
||||
|
||||
|
86
nwdbm.c
86
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 <ndbm.h>
|
||||
# define SHADOW_PWD 0
|
||||
# ifndef SHADOW_PWD
|
||||
# define SHADOW_PWD 0
|
||||
# endif
|
||||
#else
|
||||
# include </usr/ucbinclude/ndbm.h>
|
||||
# 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;
|
||||
|
13
nwdbm.h
13
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);
|
||||
|
123
nwfile.c
123
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;
|
||||
|
3
nwfile.h
3
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 */
|
||||
|
408
nwqueue.c
Normal file
408
nwqueue.c
Normal file
@ -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 <dirent.h>
|
||||
#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);
|
||||
}
|
92
nwqueue.h
Normal file
92
nwqueue.h
Normal file
@ -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
|
351
nwroute.c
351
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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
4
nwrouted.c
Normal file
4
nwrouted.c
Normal file
@ -0,0 +1,4 @@
|
||||
/* nwrouted.c */
|
||||
#define IN_NWROUTED 1
|
||||
#include "nwroute.c"
|
||||
#include "nwserv.c"
|
143
nwserv.c
143
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; j<anz_net_devices;j++) {
|
||||
NW_NET_DEVICE *nd=net_devices[j];
|
||||
XDPRINTF((1, 0, "Close Device=%s, frame=%d",
|
||||
if (nd->is_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);
|
||||
}
|
||||
|
||||
|
30
nwserv.h
30
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
|
||||
|
110
nwvolume.c
110
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));
|
||||
|
25
nwvolume.h
25
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);
|
||||
|
173
tools.c
173
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 <stdarg.h>
|
||||
|
||||
#ifndef LINUX
|
||||
#include <errno.h>
|
||||
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);
|
||||
}
|
||||
|
||||
|
15
tools.h
15
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;
|
||||
|
54
unxfile.c
Normal file
54
unxfile.c
Normal file
@ -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
|
||||
|
22
unxfile.h
Normal file
22
unxfile.h
Normal file
@ -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);
|
||||
|
77
unxlog.c
Normal file
77
unxlog.c
Normal file
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user