1371 lines
58 KiB
C
1371 lines
58 KiB
C
/* nwconn.c 20-Nov-95 */
|
||
/* one process / connection */
|
||
|
||
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
|
||
*
|
||
* This program is free software; you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation; either version 2 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* This program is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with this program; if not, write to the Free Software
|
||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||
*/
|
||
|
||
#include "net.h"
|
||
static int default_uid=-1;
|
||
static int default_gid=-1;
|
||
|
||
static int ipxdebug=0;
|
||
|
||
static int father_pid = -1;
|
||
static ipxAddr_t from_addr;
|
||
static ipxAddr_t my_addr;
|
||
static struct t_unitdata ud;
|
||
static int ipx_fd = -1;
|
||
static uint8 ipx_pack_typ = PACKT_CORE;
|
||
static int last_sequence = -9999;
|
||
|
||
static IPX_DATA ipxdata;
|
||
static NCPRESPONSE *ncpresponse=(NCPRESPONSE*)&ipxdata;
|
||
static uint8 *responsedata=((uint8*)&ipxdata)+sizeof(NCPRESPONSE);
|
||
|
||
static int requestlen;
|
||
static uint8 readbuff[IPX_MAX_DATA+500];
|
||
|
||
static NCPREQUEST *ncprequest = (NCPREQUEST*)readbuff;
|
||
static uint8 *requestdata = readbuff + sizeof(NCPREQUEST);
|
||
static int ncp_type;
|
||
|
||
static int open_ipx_socket()
|
||
{
|
||
struct t_bind bind;
|
||
ipx_fd=t_open("/dev/ipx", O_RDWR, NULL);
|
||
if (ipx_fd < 0) {
|
||
t_error("t_open !Ok");
|
||
return(-1);
|
||
}
|
||
U16_TO_BE16(0, my_addr.sock); /* actual write socket */
|
||
bind.addr.len = sizeof(ipxAddr_t);
|
||
bind.addr.maxlen = sizeof(ipxAddr_t);
|
||
bind.addr.buf = (char*)&my_addr;
|
||
bind.qlen = 0; /* allways */
|
||
if (t_bind(ipx_fd, &bind, &bind) < 0){
|
||
t_error("t_bind !OK");
|
||
close(ipx_fd);
|
||
return(-1);
|
||
}
|
||
DPRINTF(("NWCONN OpenSocket: %s\n",
|
||
visable_ipx_adr((ipxAddr_t *) bind.addr.buf)));
|
||
return(0);
|
||
}
|
||
|
||
static void set_default_guid(void)
|
||
{
|
||
setgid(default_gid);
|
||
setuid(default_uid);
|
||
}
|
||
|
||
static int ncp_response(int sequence,
|
||
int completition, int data_len)
|
||
|
||
{
|
||
ncpresponse->sequence = (uint8) sequence;
|
||
ncpresponse->completition = (uint8) completition;
|
||
last_sequence = sequence;
|
||
DPRINTF(("NWCONN NCP_RESP seq:%d, conn:%d, compl=0x%x TO %s\n",
|
||
(int)ncpresponse->sequence, (int) ncpresponse->connection, (int)completition,
|
||
visable_ipx_adr((ipxAddr_t *) ud.addr.buf)));
|
||
|
||
ud.udata.len = ud.udata.maxlen = sizeof(NCPRESPONSE) + data_len;
|
||
if (t_sndudata(ipx_fd, &ud) < 0){
|
||
t_error("t_sndudata in NWCONN !OK");
|
||
return(-1);
|
||
}
|
||
return(0);
|
||
}
|
||
|
||
|
||
static int test_handle = -1;
|
||
static void handle_ncp_serv()
|
||
{
|
||
int data_len = 0;
|
||
int sequence = (int)ncprequest->sequence;
|
||
int task = (int)ncprequest->task;
|
||
int reserved = (int)ncprequest->reserved;
|
||
int function = (int)ncprequest->function;
|
||
int completition = 0; /* first set */
|
||
int org_nw_debug = nw_debug;
|
||
int do_druck = 0;
|
||
|
||
if (last_sequence == sequence && ncp_type != 0x1111){ /* send the same again */
|
||
if (t_sndudata(ipx_fd, &ud) < 0){
|
||
t_error("t_sndudata !OK");
|
||
}
|
||
DPRINTF(("Sequence %d is written twice\n", sequence));
|
||
return;
|
||
}
|
||
|
||
if (!nw_debug && (
|
||
/*
|
||
function == 0x43 ||
|
||
function == 0x4c ||
|
||
function == 0x4d ||
|
||
function == 0x4a ||
|
||
*/
|
||
function == 0x11
|
||
) ) nw_debug=1;
|
||
|
||
|
||
if (nw_debug){
|
||
int j = requestlen;
|
||
if (nw_debug == 1
|
||
&& (function==0x48 || function == 0x49)) /* read or write */
|
||
nw_debug=0;
|
||
if (nw_debug == 2
|
||
&& (function==0x48)) /* read */
|
||
nw_debug=0;
|
||
|
||
if (nw_debug){
|
||
do_druck=2;
|
||
DPRINTF(("NCP REQUEST:type:0x%x, seq:%d, task:%d, reserved:0x%x, func:0x%x\n",
|
||
ncp_type, sequence, task, reserved, function));
|
||
if (j > 0){
|
||
uint8 *p=requestdata;
|
||
DPRINTF(("len %d, DATA:", j));
|
||
while (j--) {
|
||
int c = *p++;
|
||
if (c > 32 && c < 127) DPRINTF((",\'%c\'", (char) c));
|
||
else DPRINTF((",0x%x", c));
|
||
}
|
||
DPRINTF(("\n"));
|
||
}
|
||
}
|
||
}
|
||
|
||
if (ncp_type == 0x2222) {
|
||
switch (function) {
|
||
case 0x12 : { /* Get Volume Info with Number */
|
||
int volume = (int)*requestdata;
|
||
struct XDATA {
|
||
uint8 sec_per_block[2];
|
||
uint8 total_blocks[2];
|
||
uint8 avail_blocks[2];
|
||
uint8 total_dirs[2];
|
||
uint8 avail_dirs[2];
|
||
uint8 name[16];
|
||
uint8 removable[2];
|
||
} *xdata = (struct XDATA*) responsedata;
|
||
int result;
|
||
memset(xdata, 0, sizeof(struct XDATA));
|
||
if ((result = nw_get_volume_name(volume, xdata->name))>-1){
|
||
struct fs_usage fsp;
|
||
if (!nw_get_fs_usage(xdata->name, &fsp)) {
|
||
U16_TO_BE16(38, xdata->sec_per_block); /* hard coded */
|
||
U16_TO_BE16(fsp.fsu_blocks, xdata->total_blocks);
|
||
U16_TO_BE16(fsp.fsu_bavail, xdata->avail_blocks);
|
||
U16_TO_BE16(fsp.fsu_files, xdata->total_dirs);
|
||
U16_TO_BE16(fsp.fsu_ffree, xdata->avail_dirs);
|
||
U16_TO_BE16(0, xdata->removable);
|
||
}
|
||
data_len = sizeof(struct XDATA);
|
||
} else completition = (uint8) -result;
|
||
} break;
|
||
|
||
case 0x14 : { /* GET DATE und TIME */
|
||
struct SERVER_DATE {
|
||
uint8 year;
|
||
uint8 mon;
|
||
uint8 day;
|
||
uint8 std;
|
||
uint8 min;
|
||
uint8 sec;
|
||
uint8 day_of_week;
|
||
} *mydate = (struct SERVER_DATE*) responsedata;
|
||
struct tm *s_tm;
|
||
time_t timer;
|
||
time(&timer);
|
||
s_tm = localtime(&timer);
|
||
mydate->year = (uint8) s_tm->tm_year;
|
||
mydate->mon = (uint8) s_tm->tm_mon+1;
|
||
mydate->day = (uint8) s_tm->tm_mday;
|
||
|
||
mydate->std = (uint8) s_tm->tm_hour;
|
||
mydate->min = (uint8) s_tm->tm_min;
|
||
mydate->sec = (uint8) s_tm->tm_sec;
|
||
mydate->day_of_week = (uint8) s_tm->tm_wday; /* Wochentag */
|
||
data_len = sizeof(struct SERVER_DATE);
|
||
}
|
||
break;
|
||
|
||
|
||
case 0x16 : {
|
||
uint8 len = *(requestdata+1);
|
||
uint8 *p = requestdata +2;
|
||
if (0 == *p){
|
||
/****** * SetDirektoryHandle *************/
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 filler; /* 0x0 */
|
||
uint8 datalen;
|
||
uint8 type; /* 0x0 */
|
||
uint8 target_dir_handle; /* Verzeichnis Handle zu <20>ndern */
|
||
uint8 source_dir_handle; /* Verzeichnis Handle */
|
||
uint8 pathlen;
|
||
uint8 path[2];
|
||
} *input = (struct INPUT *) (ncprequest);
|
||
completition =
|
||
(uint8)-nw_set_dir_handle((int)input->target_dir_handle,
|
||
(int)input->source_dir_handle,
|
||
input->path,
|
||
(int)input->pathlen, task);
|
||
|
||
} else if (1 == *p){ /* liefert Verzeichnis Namen */
|
||
/* Dir_handles */
|
||
/******** GetDirektoryPATH ***************/
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 filler; /* 0x0 */
|
||
uint8 datalen; /* 0x2 */
|
||
uint8 type; /* 0x1 */
|
||
uint8 dir_handle; /* Verzeichnis Handle */
|
||
} *input = (struct INPUT *) (ncprequest);
|
||
struct XDATA {
|
||
uint8 len;
|
||
uint8 name[256];
|
||
} *xdata = (struct XDATA*) responsedata;
|
||
int result = nw_get_directory_path((int)input->dir_handle, xdata->name);
|
||
if (result > -1){
|
||
xdata->len = (uint8) result;
|
||
data_len = result + 1;
|
||
xdata->name[result] = '\0';
|
||
DPRINTF(("GetDirektoryPATH=%s\n", xdata->name));
|
||
} else completition = (uint8)-result;
|
||
} else if (2 == *p){ /* Scan Direktory Information */
|
||
/******** Scan Dir Info ****************/
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 filler; /* 0x0 */
|
||
uint8 datalen; /* */
|
||
uint8 type; /* 0x2 */
|
||
uint8 dir_handle; /* Verzeichnis Handle */
|
||
uint8 sub_dir_nmbr[2]; /* HI LOW */
|
||
uint8 len; /* kann auch 0 sein */
|
||
uint8 path[2];
|
||
} *input = (struct INPUT *) (ncprequest);
|
||
struct XDATA {
|
||
uint8 sub_dir_name[16];
|
||
uint8 create_date_time[4];
|
||
uint8 owner_id[4]; /* HI LOW */
|
||
uint8 max_right_mask;
|
||
uint8 reserved; /* Reserved by Novell */
|
||
uint8 sub_dir_nmbr[2]; /* HI LOW */
|
||
} *xdata = (struct XDATA*) responsedata;
|
||
int result;
|
||
memcpy(xdata->sub_dir_nmbr, input->sub_dir_nmbr, 2);
|
||
result = nw_scan_dir_info((int)input->dir_handle,
|
||
input->path, (int)input->len,
|
||
xdata->sub_dir_nmbr, xdata->sub_dir_name,
|
||
xdata->create_date_time, xdata->owner_id);
|
||
if (result > -1){
|
||
xdata->max_right_mask = (uint8)result;
|
||
data_len = sizeof(struct XDATA);
|
||
DPRINTF(("Scan Dir Info max_right_mask=%d\n", (int)result));
|
||
} else completition = (uint8)-result;
|
||
} else if (*p == 0x3){ /* Get Direktory Rights */
|
||
/******** Get Eff Dir Rights ****************/
|
||
struct XDATA {
|
||
uint8 eff_right_mask; /* Effektive Right to Dir, old! */
|
||
} *xdata = (struct XDATA*) responsedata;
|
||
int result = nw_get_eff_dir_rights((int)*(p+1), p+3, (int)*(p+2));
|
||
if (result > -1) {
|
||
xdata->eff_right_mask = (uint8) result;
|
||
data_len = 1;
|
||
DPRINTF(("Get eff Dir Rights=%d\n", (int)result));
|
||
} else completition = (uint8) -result;
|
||
} else if (*p == 0x4){ /* Modify Max Right MAsk */
|
||
/******** MODIFY MAX RIGHT MASK ****************/
|
||
/* NO REPLY !! */
|
||
completition = 0xfb; /* TODO */
|
||
} else if (*p == 0x5){ /* Get Volume Number 0 .. 31 */
|
||
/******** GetVolume Number ***************/
|
||
/* p+1 = namelen */
|
||
/* p+2 = data z.b 'SYS' */
|
||
struct XDATA {
|
||
uint8 volume; /* Nummer */
|
||
} *xdata = (struct XDATA*) responsedata;
|
||
int result = nw_get_volume_number(p+2, (int)*(p+1));
|
||
if (result > -1) {
|
||
xdata->volume = (uint8) result;
|
||
data_len = 1;
|
||
} else completition = (uint8) -result;
|
||
} else if (*p == 0x6){ /* Get Volume Name von 0 .. 31 */
|
||
/******** Get Volume Name ***************/
|
||
struct XDATA {
|
||
uint8 namelen;
|
||
uint8 name[16];
|
||
} *xdata = (struct XDATA*) responsedata;
|
||
int result = nw_get_volume_name((int)*(p+1), xdata->name);
|
||
if (result > -1) {
|
||
xdata->namelen = (uint8) result;
|
||
data_len = sizeof(struct XDATA);
|
||
} else completition = (uint8) -result;
|
||
} else if (*p == 0xa){ /* legt Verzeichnis an */
|
||
/******** Create Dir *********************/
|
||
int dir_handle = (int) *(p+1);
|
||
int rightmask = (int) *(p+2);
|
||
int pathlen = (int) *(p+3);
|
||
uint8 *path = p+4;
|
||
int code = nw_mk_rd_dir(dir_handle, path, pathlen, 1);
|
||
if (code) completition = (uint8) -code;
|
||
} else if (*p == 0xb){ /* l<>scht Verzeichnis */
|
||
/******** Delete DIR *********************/
|
||
int dir_handle = (int) *(p+1);
|
||
int reserved = (int) *(p+2); /* Res. by NOVELL */
|
||
int pathlen = (int) *(p+3);
|
||
uint8 *path = p+4;
|
||
int code = nw_mk_rd_dir(dir_handle, path, pathlen, 0);
|
||
if (code) completition = (uint8) -code;
|
||
} else if (*p == 0xd){ /* Add Trustees to DIR */
|
||
/******** GetDirektoryPATH ***************/
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 filler; /* 0x0 */
|
||
uint8 datalen;
|
||
uint8 type;
|
||
uint8 dir_handle; /* Verzeichnis Handle */
|
||
uint8 trustee_id[4]; /* Trustee Object ID */
|
||
uint8 trustee_right_mask;
|
||
uint8 pathlen;
|
||
uint8 path;
|
||
} *input = (struct INPUT *) (ncprequest);
|
||
/* TODO !!!!!!!!!!!!!!!!!!!! */
|
||
do_druck++;
|
||
} else if (*p == 0x12 /* Allocate Permanent Dir Handle */
|
||
|
||
/******** Allocate Permanent DIR Handle **/
|
||
|| *p == 0x13 /* Allocate Temp Dir Handle */
|
||
/******** Allocate Temp DIR Handle **/
|
||
|| *p == 0x16) { /* Allocate spez Temp Dir Handle */
|
||
/******** Allocate spez temp DIR Handle **/
|
||
struct XDATA {
|
||
uint8 dirhandle; /* new Dir Handle */
|
||
uint8 right_mask; /* 0xff effektive Right MAsk ? */
|
||
} *xdata = (struct XDATA*) responsedata;
|
||
int dirhandle = nw_alloc_dir_handle(
|
||
(int) *(p+1),
|
||
p+4,
|
||
(int)*(p+3),
|
||
(int)*(p+2),
|
||
(*p==0x12) ? 0
|
||
: ((*p==0x13) ? 1 : 2), task);
|
||
if (dirhandle > -1){
|
||
xdata->dirhandle = (uint8) dirhandle;
|
||
xdata->right_mask = 0xff;
|
||
data_len = sizeof(struct XDATA);
|
||
} else completition = (uint8) -dirhandle;
|
||
|
||
} else if (*p == 0x14){ /* deallocate Dir Handle */
|
||
/******** Free DIR Handle ****************/
|
||
int err_code = nw_free_dir_handle((int)*(p+1));
|
||
if (err_code) completition = (uint8) -err_code;
|
||
} else if (*p == 0x15){ /* liefert Volume Information */
|
||
/******** Get Volume Info with Handle ****/
|
||
struct XDATA {
|
||
uint8 reserve1;
|
||
uint8 len;
|
||
uint8 total_blocks[2];
|
||
uint8 avail_blocks[2];
|
||
uint8 total_dirs[2]; /* anz dirs */
|
||
uint8 avail_dirs[2]; /* free dirs */
|
||
uint8 name[16]; /* SYS Name */
|
||
uint8 removable[2];
|
||
} *xdata = (struct XDATA*)responsedata;
|
||
int result = nw_get_vol_number((int)*(p+1));
|
||
memset(xdata, 0, sizeof(struct XDATA));
|
||
if (result > -1) {
|
||
result = nw_get_volume_name(result, xdata->name);
|
||
if (result > -1) {
|
||
struct fs_usage fsp;
|
||
if (!nw_get_fs_usage(xdata->name, &fsp)) {
|
||
xdata->len = 8; /* blocks entries */
|
||
U16_TO_BE16(fsp.fsu_blocks, xdata->total_blocks);
|
||
U16_TO_BE16(fsp.fsu_bavail, xdata->avail_blocks);
|
||
U16_TO_BE16(fsp.fsu_files, xdata->total_dirs);
|
||
U16_TO_BE16(fsp.fsu_ffree, xdata->avail_dirs);
|
||
U16_TO_BE16(0, xdata->removable);
|
||
}
|
||
data_len = sizeof(struct XDATA);
|
||
DPRINTF(("GIVE VOLUME INFO von :%s:\n", xdata->name));
|
||
result = 0;
|
||
}
|
||
}
|
||
completition = (uint8)-result;
|
||
} else if (*p == 0x19){ /* Set Directory Information */
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 filler; /* 0x0 */
|
||
uint8 datalen;
|
||
uint8 sub_func;
|
||
uint8 dir_handle; /* Verzeichnis Handle */
|
||
uint8 trustee_id[4]; /* Trustee Object ID */
|
||
uint8 trustee_right_mask;
|
||
uint8 pathlen;
|
||
uint8 path;
|
||
} *input = (struct INPUT *) (ncprequest);
|
||
/* No REPLY */
|
||
completition = 0xfb; /* !!!!! TODO !!!! */
|
||
} else if (*p == 0x1a){ /* Get Pathname of A Volume Dir Pair */
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 filler; /* 0x0 */
|
||
uint8 datalen;
|
||
uint8 sub_func;
|
||
uint8 volume;
|
||
uint8 dir_entry[2];
|
||
} *input = (struct INPUT *) (ncprequest);
|
||
struct XDATA {
|
||
uint8 pathlen;
|
||
uint8 pathname;
|
||
} *xdata = (struct XDATA*)responsedata;
|
||
completition = 0xfb; /* !!!!! Machen !!!! */
|
||
} else if (*p == 0x1e){ /* liefert Trustees ?? */
|
||
/* des Dir_handles + PATH */
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 filler; /* 0x0 */
|
||
uint8 datalen; /* 0x2 */
|
||
uint8 type; /* 0x1e */
|
||
uint8 dir_handle; /* Verzeichnis Handle */
|
||
uint8 attrib; /* Attrib ?? 0x6 */
|
||
uint8 reserve1[4]; /* alles 0xff */
|
||
uint8 len;
|
||
uint8 data[2];
|
||
} *input = (struct INPUT *) (ncprequest);
|
||
NW_FILE_INFO f;
|
||
struct XDATA {
|
||
uint8 unknown[15];
|
||
uint8 namlen;
|
||
uint8 name[14];
|
||
} *xdata = (struct XDATA*)responsedata;
|
||
int len=input->len;
|
||
int searchsequence = nw_search( (uint8*)
|
||
&(f),
|
||
(int)input->dir_handle,
|
||
MAX_U16,
|
||
(int) input->attrib,
|
||
input->data, len);
|
||
if (searchsequence > -1){
|
||
memset(xdata, 0, 132);
|
||
xdata->namlen = min(14, strlen(f.name));
|
||
memcpy(xdata->name, f.name, xdata->namlen);
|
||
} else completition = (uint8) - searchsequence;
|
||
} else if (*p == 0x20){ /* testet ??*/
|
||
struct XDATA {
|
||
uint8 res1; /* 0x0 */
|
||
} *xdata = (struct XDATA*) responsedata;
|
||
xdata->res1 = 0x0;
|
||
data_len = 1;
|
||
} else if (*p == 0x21) {
|
||
/* change Vol restrictions for Obj */
|
||
uint8 volnr = *(p+1);
|
||
uint32 id = GET_BE32(p+2);
|
||
uint32 blocks = GET_BE32(p+6);
|
||
DPRINTF(("Change vol restriction vol=%d, id=0x%lx, Blocks=0x%lx",
|
||
(int)volnr, id, blocks));
|
||
} else if (*p == 0x22) {
|
||
/* remove Vol restrictions for Obj */
|
||
uint8 volnr = *(p+1);
|
||
uint32 id = GET_BE32(p+2);
|
||
DPRINTF(("Renmove vol restriction vol=%d, id=0x%lx",
|
||
(int)volnr, id));
|
||
|
||
} else if (*p == 0x25){ /* setting FILE INFO ??*/
|
||
/* TODO !!!!!!!!!!!!!!!!!!!! */
|
||
do_druck++;
|
||
} else if (*p == 0x27){ /* Add Trustees to DIR ?? */
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 filler; /* 0x0 */
|
||
uint8 datalen; /* 0x2 */
|
||
uint8 type; /* 0x27 */
|
||
uint8 dir_handle; /* Verzeichnis Handle */
|
||
uint8 trustee_id[4]; /* Trustee Object ID */
|
||
uint8 trustee_right_mask;
|
||
uint8 weis_nicht; /* ??? z.B. 0x0 */
|
||
uint8 pathlen;
|
||
uint8 path;
|
||
} *input = (struct INPUT *) (ncprequest);
|
||
/* TODO !!!!!!!!!!!!!!!!!!!! */
|
||
do_druck++;
|
||
} else if (*p == 0x29){
|
||
/* read volume restrictions for an object */
|
||
uint8 volnr = *(p+1);
|
||
uint32 id = GET_BE32(p+2);
|
||
struct XDATA {
|
||
uint8 weisnicht[8]; /* ?????? */
|
||
} *xdata = (struct XDATA*) responsedata;
|
||
DPRINTF(("Get vol restriction vol=%d, id=0x%lx",
|
||
(int)volnr, id));
|
||
memset(xdata, 0, sizeof(struct XDATA));
|
||
data_len=sizeof(struct XDATA);
|
||
} else if (*p == 0x2a){ /* Get Eff. Dir Rights ??*/
|
||
/* from Dir_handles + PATH */
|
||
struct XDATA {
|
||
uint8 eff_rights; /* Effektive Right to Dir */
|
||
uint8 unkwown_data; /* 0x1 */
|
||
} *xdata = (struct XDATA*) responsedata;
|
||
NW_DIR_INFO d;
|
||
int len=(int)*(p+2);
|
||
int searchsequence;
|
||
if (len)
|
||
searchsequence = nw_search((uint8*)&(d),
|
||
(int)*(p+1), /* dir_handle */
|
||
MAX_U16,
|
||
(int) 0x10, /* only dirs ?? */
|
||
p+3, /* path */
|
||
len); /* pathlen */
|
||
else {
|
||
searchsequence = nw_get_eff_dir_rights(
|
||
(int)*(p+1),
|
||
p+3,
|
||
len);
|
||
if (searchsequence > -1)
|
||
d.ext_attrib = searchsequence;
|
||
}
|
||
if (searchsequence > -1){
|
||
xdata->eff_rights = d.ext_attrib;
|
||
xdata->unkwown_data = 0x1;
|
||
data_len = sizeof(struct XDATA);
|
||
} else completition = (uint8) - searchsequence;
|
||
} else if (*p == 0x2c){
|
||
/* Get Volume and Purge Information */
|
||
/* new Call since V3.11 */
|
||
/* ncpfs need this call */
|
||
int volume = (int) *(p+1);
|
||
struct XDATA {
|
||
uint8 total_blocks[4];
|
||
uint8 avail_blocks[4];
|
||
uint8 purgeable_blocks[4];
|
||
uint8 not_purgeable_blocks[4];
|
||
uint8 total_dirs[4];
|
||
uint8 avail_dirs[4];
|
||
uint8 reserved_by_novell[4];
|
||
uint8 sec_per_block;
|
||
uint8 namlen;
|
||
uint8 name[1];
|
||
} *xdata = (struct XDATA*) responsedata;
|
||
char name[100];
|
||
int result = nw_get_volume_name(volume, name);
|
||
if (result > -1){
|
||
struct fs_usage fsp;
|
||
memset(xdata, 0, sizeof(struct XDATA));
|
||
if (!nw_get_fs_usage(name, &fsp)) {
|
||
xdata->sec_per_block = 38; /* hard coded */
|
||
U32_TO_BE32(fsp.fsu_blocks, xdata->total_blocks);
|
||
U32_TO_BE32(fsp.fsu_bavail, xdata->avail_blocks);
|
||
U32_TO_BE32(fsp.fsu_files, xdata->total_dirs);
|
||
U32_TO_BE32(fsp.fsu_ffree, xdata->avail_dirs);
|
||
}
|
||
xdata->namlen = strlen(name);
|
||
strmaxcpy(xdata->name, name, xdata->namlen);
|
||
data_len = xdata->namlen + 30;
|
||
} else completition = (uint8) -result;
|
||
} else if (*p == 0x2d){
|
||
/* Get Direktory Information */
|
||
int dir_handle = (int) *(p+1);
|
||
struct XDATA {
|
||
uint8 total_blocks[4];
|
||
uint8 avail_blocks[4];
|
||
uint8 total_dirs[4];
|
||
uint8 avail_dirs[4];
|
||
uint8 reserved_by_novell[4];
|
||
uint8 sec_per_block;
|
||
uint8 namlen;
|
||
uint8 name[1]; /* Volume Name */
|
||
} *xdata = (struct XDATA*) responsedata;
|
||
int result = nw_get_vol_number(dir_handle);
|
||
char name[100];
|
||
if (result > -1)
|
||
result = nw_get_volume_name(result, name);
|
||
if (result > -1) {
|
||
struct fs_usage fsp;
|
||
memset(xdata, 0, sizeof(struct XDATA));
|
||
if (!nw_get_fs_usage(name, &fsp)) {
|
||
xdata->sec_per_block = 38; /* hard coded */
|
||
U32_TO_BE32(fsp.fsu_blocks, xdata->total_blocks);
|
||
U32_TO_BE32(fsp.fsu_bavail, xdata->avail_blocks);
|
||
U32_TO_BE32(fsp.fsu_files, xdata->total_dirs);
|
||
U32_TO_BE32(fsp.fsu_ffree, xdata->avail_dirs);
|
||
}
|
||
xdata->namlen = strlen(name);
|
||
strmaxcpy(xdata->name, name, xdata->namlen);
|
||
data_len = xdata->namlen + 22;
|
||
} else completition = (uint8) -result;
|
||
} else if (*p == 0x2e){ /* RENAME DATEI */
|
||
completition = 0xfb; /* TODO: !!! */
|
||
} else completition = 0xfb; /* unkwown request */
|
||
}
|
||
break;
|
||
|
||
#if 1
|
||
case 0x17 : { /* FILE SERVER ENVIRONMENT */
|
||
uint8 len = *(requestdata+1);
|
||
uint8 ufunc = *(requestdata+2);
|
||
switch (ufunc) {
|
||
case 0x0f: { /* Scan File Information */
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 div[3]; /* 0, len + ufunc */
|
||
uint8 sequence[2]; /* z.B. 0xff, 0xff */
|
||
|
||
uint8 dir_handle;
|
||
uint8 search_attrib; /* 0: NONE */
|
||
/* 02: HIDDEN */
|
||
/* 04: SYSTEM */
|
||
/* 06: BOTH */
|
||
/* 0x10: DIR */
|
||
uint8 len;
|
||
uint8 data[2]; /* Name */
|
||
} *input = (struct INPUT *)ncprequest;
|
||
|
||
struct OUTPUT {
|
||
uint8 sequence[2]; /* next sequence */
|
||
NW_FILE_INFO f;
|
||
uint8 owner_id[4];
|
||
uint8 archive_date[2];
|
||
uint8 archive_time[2];
|
||
uint8 reserved[56];
|
||
} *xdata = (struct OUTPUT*)responsedata;
|
||
int len = input->len;
|
||
int searchsequence;
|
||
memset(xdata, 0, sizeof(struct OUTPUT));
|
||
|
||
searchsequence = nw_search( (uint8*) &(xdata->f),
|
||
(int)input->dir_handle,
|
||
(int) GET_BE16(input->sequence),
|
||
(int) input->search_attrib,
|
||
input->data, len);
|
||
|
||
if (searchsequence > -1) {
|
||
U16_TO_BE16((uint16) searchsequence, xdata->sequence);
|
||
U32_TO_BE32(1L, xdata->owner_id); /* Supervisor */
|
||
data_len = sizeof(struct OUTPUT);
|
||
} else completition = (uint8) (- searchsequence);
|
||
}
|
||
break;
|
||
|
||
case 0x10: { /* Set File Information */
|
||
completition = 0xfb;
|
||
}
|
||
break;
|
||
|
||
case 0x79: { /* creat queue job and file */
|
||
/* somme of this call is handled in ncpserv !! */
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 packetlen[2]; /* low high */
|
||
uint8 func; /* 0x79 */
|
||
uint8 queue_id[4]; /* Queue ID */
|
||
uint8 queue_job[280];
|
||
/* this is added by ncpserv */
|
||
uint8 dir_nam_len; /* len of dirname */
|
||
uint8 dir_name[1];
|
||
} *input = (struct INPUT *) (ncprequest);
|
||
int result = nw_creat_queue(ncpresponse->connection,
|
||
input->queue_id,
|
||
input->queue_job,
|
||
input->dir_name,
|
||
(int)input->dir_nam_len);
|
||
if (!result) {
|
||
data_len = 78;
|
||
memcpy(responsedata, input->queue_job, data_len);
|
||
} else completition= (uint8)-result;
|
||
}
|
||
break;
|
||
|
||
case 0x7f: { /* close file and start queue */
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 packetlen[2]; /* low high */
|
||
uint8 func; /* 0x7f */
|
||
uint8 queue_id[4]; /* Queue ID */
|
||
uint8 job_id[4]; /* result from creat queue */
|
||
/* this is added by ncpserv */
|
||
uint8 prc_len; /* len of printcommand */
|
||
uint8 prc[1]; /* printcommand */
|
||
} *input = (struct INPUT *) (ncprequest);
|
||
int result = nw_close_file_queue(input->queue_id,
|
||
input->job_id,
|
||
input->prc,
|
||
input->prc_len);
|
||
if (result < 0) completition = (uint8)-result;
|
||
}
|
||
break;
|
||
|
||
case 0xf3: { /* Map Direktory Number TO PATH */
|
||
DPRINTF(("TODO: Map Direktory Number TO PATH\n"));
|
||
completition = 0xff;
|
||
}
|
||
break;
|
||
|
||
case 0xf4: { /* Map PATH TO Dir Entry */
|
||
DPRINTF(("TODO: Map PATH TO Dir Entry\n"));
|
||
completition = 0xff;
|
||
}
|
||
break;
|
||
|
||
default : completition = 0xfb;
|
||
break;
|
||
} /* switch (ufunc) */
|
||
} /* case 0x17 */
|
||
break;
|
||
#endif
|
||
|
||
case 0x18 : /* End of Job */
|
||
nw_free_handles((task > 0) ? task : 1);
|
||
break;
|
||
|
||
case 0x19 : /* logout, some of this call is handled in ncpserv. */
|
||
nw_free_handles(0);
|
||
set_default_guid();
|
||
break;
|
||
|
||
case 0x1a : /* lock file */
|
||
case 0x1e : /* unlock file */
|
||
{
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 reserve; /* 0x1 */
|
||
uint8 fhandle[4]; /* Filehandle */
|
||
uint8 ext_fhandle[2]; /* all zero */
|
||
uint8 offset[4];
|
||
uint8 size[4];
|
||
uint8 weisnicht[2]; /* lock timeout ??? */
|
||
} *input = (struct INPUT *)ncprequest;
|
||
int fhandle = GET_BE32(input->fhandle);
|
||
int offset = GET_BE32(input->offset);
|
||
int size = GET_BE32(input->size);
|
||
completition = (uint8)(-nw_lock_datei(fhandle,
|
||
offset, size,
|
||
(int)(function == 0x1a)));
|
||
}
|
||
break;
|
||
|
||
case 0x21 : { /* Negotiate Buffer Size, Packetsize */
|
||
int wantsize = GET_BE16((uint8*)ncprequest);
|
||
uint8 *getsize=responsedata;
|
||
U16_TO_BE16(min(0x200, wantsize), getsize);
|
||
data_len = 2;
|
||
}
|
||
break;
|
||
|
||
#if 0
|
||
case 0x22 : /* div TTS Calls */
|
||
break;
|
||
#endif
|
||
|
||
|
||
case 0x3e : { /* FILE SEARCH INIT */
|
||
/* returns dhandle for searchings */
|
||
int dir_handle = (int)*requestdata;
|
||
int len = (int)*(requestdata+1); /* pathlen */
|
||
uint8 *p = requestdata+2; /* path */
|
||
struct XDATA {
|
||
uint8 volume; /* Volume */
|
||
uint8 dir_id[2]; /* Direktory ID */
|
||
uint8 searchsequenz[2];
|
||
uint8 dir_rights; /* Rights */
|
||
} *xdata= (struct XDATA*) responsedata;
|
||
int volume;
|
||
int searchsequenz;
|
||
int dir_id;
|
||
int rights = nw_open_dir_handle(dir_handle, p, len,
|
||
&volume, &dir_id, &searchsequenz);
|
||
if (rights >-1) {
|
||
xdata->volume = (uint8)volume;
|
||
U16_TO_BE16((uint16)dir_id, xdata->dir_id);
|
||
U16_TO_BE16((uint16)searchsequenz, xdata->searchsequenz);
|
||
xdata->dir_rights = (uint8)rights;
|
||
data_len = sizeof(struct XDATA);
|
||
} else completition = (uint8) -rights;
|
||
} break;
|
||
|
||
case 0x3d : { /* commit file, flush file buffers */
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 reserve;
|
||
uint8 fhandle[4]; /* filehandle */
|
||
uint8 ext_fhandle[2]; /* all zero */
|
||
} *input = (struct INPUT *)ncprequest;
|
||
uint32 fhandle = GET_BE32(input->fhandle);
|
||
DPRINTF(("TODO: COMMIT FILE:fhandle=%ld\n", fhandle));
|
||
/* TODO */
|
||
;
|
||
} break;
|
||
|
||
case 0x3f : { /* file search continue */
|
||
/* Dir_id is from file search init */
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 volume; /* Volume ID */
|
||
uint8 dir_id[2]; /* von File Search Init */
|
||
uint8 searchsequence[2]; /* FRAGE Sequence FFFF ertster Eintrag */
|
||
uint8 search_attrib; /* Attribute */
|
||
/* 0 none,
|
||
2 HIDDEN,
|
||
* 4 System ,
|
||
6 Both,
|
||
* 0x10 Dir
|
||
*/
|
||
uint8 len; /* Weitere L<>nge */
|
||
uint8 data[2]; /* Dateiname mit Wild */
|
||
} *input = (struct INPUT *) (ncprequest);
|
||
int len=input->len ; /* FN Length */
|
||
struct OUTPUT {
|
||
uint8 searchsequence[2]; /* FRAGE Sequence */
|
||
uint8 dir_id[2]; /* Direktory ID */
|
||
/* is correct !! */
|
||
union {
|
||
NW_DIR_INFO d;
|
||
NW_FILE_INFO f;
|
||
} u;
|
||
} *xdata = (struct OUTPUT*)responsedata;
|
||
|
||
int searchsequence = nw_dir_search( (uint8*) &(xdata->u),
|
||
(int) GET_BE16(input->dir_id),
|
||
(int) GET_BE16(input->searchsequence),
|
||
(int) input->search_attrib,
|
||
input->data, len);
|
||
if (searchsequence > -1) {
|
||
U16_TO_BE16((uint16) searchsequence, xdata->searchsequence);
|
||
memcpy(xdata->dir_id, input->dir_id, 2);
|
||
data_len = sizeof(struct OUTPUT);
|
||
} else completition = (uint8) (- searchsequence);
|
||
}
|
||
break;
|
||
|
||
case 0x40 : /* GET File Mode ?? */
|
||
{
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 sequenz[2]; /* z.B. 0xff, 0xff */
|
||
uint8 dir_handle; /* z.B 0x1 */
|
||
uint8 search_attrib; /* z.B. 0x6 */
|
||
uint8 len;
|
||
uint8 data[2]; /* Name */
|
||
} *input = (struct INPUT *)ncprequest;
|
||
struct OUTPUT {
|
||
uint8 sequenz[2]; /* Antwort Sequenz */
|
||
uint8 reserve2[2]; /* z.B 0x0 0x0 */
|
||
union {
|
||
NW_DIR_INFO d;
|
||
NW_FILE_INFO f;
|
||
} u;
|
||
} *xdata = (struct OUTPUT*)responsedata;
|
||
int len = input->len;
|
||
uint8 my_sequenz[2];
|
||
int searchsequence;
|
||
memcpy(my_sequenz, input->sequenz, 2);
|
||
searchsequence = nw_search( (uint8*) &(xdata->u),
|
||
(int)input->dir_handle,
|
||
(int) GET_BE16(my_sequenz),
|
||
(int) input->search_attrib,
|
||
input->data, len);
|
||
if (searchsequence > -1) {
|
||
U16_TO_BE16((uint16) searchsequence, xdata->sequenz);
|
||
data_len = sizeof(struct OUTPUT);
|
||
} else completition = (uint8) (- searchsequence);
|
||
}
|
||
break;
|
||
|
||
case 0x42 : /* close file */
|
||
{
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 reserve;
|
||
uint8 fhandle[4]; /* filehandle */
|
||
uint8 ext_fhandle[2]; /* all zero */
|
||
} *input = (struct INPUT *)ncprequest;
|
||
uint32 fhandle = GET_BE32(input->fhandle);
|
||
completition = (uint8)(-nw_close_datei(fhandle));
|
||
if (!completition && fhandle == test_handle) {
|
||
do_druck++;
|
||
test_handle = -1;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case 0x43 : /* creat file, overwrite if exist */
|
||
case 0x4D : /* create new file */
|
||
{
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 dirhandle;
|
||
uint8 attribute; /* creat Attribute */
|
||
uint8 len;
|
||
uint8 data[1]; /* Name */
|
||
} *input = (struct INPUT *)ncprequest;
|
||
struct OUTPUT {
|
||
uint8 fhandle[4]; /* Filehandle */
|
||
uint8 extfhandle[2];
|
||
uint8 reserved[2]; /* rese. by NOVELL */
|
||
NW_FILE_INFO fileinfo;
|
||
} *xdata= (struct OUTPUT*)responsedata;
|
||
int fhandle=nw_creat_open_file(
|
||
(int)input->dirhandle,
|
||
input->data,
|
||
(int)input->len,
|
||
&(xdata->fileinfo),
|
||
(int)input->attribute,
|
||
0,
|
||
(function==0x43) ? 1 : 2);
|
||
if (fhandle > -1){
|
||
data_len = sizeof(struct OUTPUT);
|
||
U32_TO_BE32(fhandle, xdata->fhandle);
|
||
U16_TO_BE16(0, xdata->extfhandle);
|
||
U16_TO_BE16(0, xdata->reserved);
|
||
|
||
#ifdef TEST_FNAME
|
||
input->data[input->len] = '\0';
|
||
if (strstr(input->data, TEST_FNAME)){
|
||
test_handle = fhandle;
|
||
do_druck++;
|
||
}
|
||
#endif
|
||
} else completition = (uint8) (-fhandle);
|
||
}
|
||
break;
|
||
|
||
case 0x44 : /* file(s) delete */
|
||
{
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 dirhandle; /* 0x0 */
|
||
uint8 searchattributes;
|
||
/* 0 none, 2 Hidden, 4 System, 6 Both */
|
||
uint8 len;
|
||
uint8 data[2]; /* Name */
|
||
} *input = (struct INPUT *)ncprequest;
|
||
int err_code = nw_delete_datei((int)input->dirhandle,
|
||
input->data, (int)input->len);
|
||
if (err_code < 0)
|
||
completition = (uint8) -err_code;
|
||
}
|
||
break;
|
||
|
||
case 0x45 : /* rename file */
|
||
{
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 dir_handle; /* ?? 0x1 */
|
||
uint8 reserve1; /* z.B. 0x2 */
|
||
uint8 len;
|
||
uint8 data[2]; /* Name */
|
||
} *input = (struct INPUT *)ncprequest;
|
||
uint8 *p = input->data+input->len; /* reserve z.B. 0x1 */
|
||
/* + 1 = len2 */
|
||
/* + 1 = data2 */
|
||
int errcode = mv_file(
|
||
(int)input->dir_handle, input->data,(int)input->len,
|
||
(int)input->dir_handle, p+2, (int)*(p+1) );
|
||
|
||
if (errcode < 0) completition = (uint8) -errcode;
|
||
}
|
||
break;
|
||
|
||
case 0x46 : /* chmod Datei ??? */
|
||
{
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 attrib; /* 0x80, od 0x0 */
|
||
/* 0x80 z.B. f<>r Sharable */
|
||
uint8 dir_handle; /* ??? z.B.0x1 */
|
||
uint8 modus; /* z.B.0x6 */
|
||
uint8 len;
|
||
uint8 data[2]; /* Name */
|
||
} *input = (struct INPUT *)ncprequest;
|
||
completition =
|
||
(uint8) (-nw_chmod_datei((int)input->dir_handle,
|
||
input->data, (int)input->len,
|
||
(int)input->modus));
|
||
}
|
||
break;
|
||
|
||
case 0x47 : /* move pointer to end of file ???? */
|
||
/* and return filesize ? */
|
||
{
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 filler;
|
||
uint8 fhandle[4]; /* Dateihandle */
|
||
uint8 ext_filehandle[2]; /* ?? alles 0 */
|
||
} *input = (struct INPUT *)ncprequest;
|
||
struct OUTPUT {
|
||
uint8 size[4]; /* Position ??? */
|
||
} *xdata=(struct OUTPUT*)responsedata;
|
||
int fhandle = GET_BE32(input->fhandle);
|
||
int size = nw_seek_datei(fhandle, 0);
|
||
if (size > -1) {
|
||
data_len = sizeof(struct OUTPUT);
|
||
U32_TO_BE32(size, xdata->size);
|
||
}
|
||
else completition = (uint8) -size;
|
||
}
|
||
break;
|
||
|
||
|
||
case 0x48 : /* read file */
|
||
{
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 filler;
|
||
uint8 fhandle[4]; /* filehandle */
|
||
uint8 reserve[2]; /* alles 0 */
|
||
uint8 offset[4]; /* alles 0 */
|
||
uint8 max_size[2]; /* zu lesende Bytes */
|
||
} *input = (struct INPUT *)ncprequest;
|
||
struct OUTPUT {
|
||
uint8 size[2]; /* Lese Bytes */
|
||
uint8 data[1072]; /* max data */
|
||
} *xdata=(struct OUTPUT*)responsedata;
|
||
int fhandle = GET_BE32(input->fhandle);
|
||
int max_size = GET_BE16(input->max_size);
|
||
off_t offset = GET_BE32(input->offset);
|
||
int zusatz = (offset & 1) ? 1 : 0;
|
||
int size = nw_read_datei(fhandle,
|
||
xdata->data+zusatz,
|
||
max_size,
|
||
offset);
|
||
|
||
if (fhandle == test_handle) do_druck++;
|
||
if (size > -1) {
|
||
U16_TO_BE16(size, xdata->size);
|
||
data_len=size+zusatz+2;
|
||
} else completition = (uint8) -size;
|
||
}
|
||
break;
|
||
|
||
case 0x49 : { /* write file */
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
|
||
uint8 filler; /* 0 Filler ?? */
|
||
uint8 fhandle[4]; /* Dateihandle */
|
||
uint8 ext_handle[2];
|
||
uint8 offset[4]; /* SEEK OFFSET */
|
||
uint8 size[2]; /* Datasize */
|
||
uint8 data[2]; /* Schreibdaten */
|
||
} *input = (struct INPUT *)ncprequest;
|
||
off_t offset = GET_BE32(input->offset);
|
||
int fhandle = GET_BE32(input->fhandle);
|
||
int input_size = GET_BE16(input->size);
|
||
int size = nw_write_datei(fhandle,
|
||
input->data,
|
||
input_size,
|
||
offset);
|
||
if (fhandle == test_handle) do_druck++;
|
||
if (size < 0)
|
||
completition = (uint8) -size;
|
||
}
|
||
break;
|
||
|
||
|
||
case 0x4a : { /* File SERVER COPY */
|
||
/* should be OK */
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 reserved; /* Reserved by Novell */
|
||
uint8 qfhandle[4]; /* Quellfile */
|
||
uint8 reserve1[2]; /* ext Filehandle */
|
||
uint8 zfhandle[4]; /* Zielfile */
|
||
uint8 reserve2[2]; /* ext Filehandle */
|
||
uint8 qoffset[4]; /* Quellfile Offset */
|
||
uint8 zoffset[4]; /* Zielfile Offset */
|
||
uint8 size[4]; /* Anzahl */
|
||
} *input = (struct INPUT *)ncprequest;
|
||
int qfhandle = GET_BE32(input->qfhandle);
|
||
int zfhandle = GET_BE32(input->zfhandle);
|
||
off_t qoffset = GET_BE32(input->qoffset);
|
||
off_t zoffset = GET_BE32(input->zoffset);
|
||
uint32 input_size = GET_BE32(input->size);
|
||
int size = nw_server_copy(qfhandle, qoffset,
|
||
zfhandle, zoffset,
|
||
input_size);
|
||
if (size < 0) completition = (uint8) -size;
|
||
else {
|
||
struct OUTPUT {
|
||
uint8 zsize[4]; /* real transfered Bytes */
|
||
} *xdata= (struct OUTPUT*)responsedata;
|
||
U32_TO_BE32(size, xdata->zsize);
|
||
data_len = sizeof(struct OUTPUT);
|
||
}
|
||
}
|
||
break;
|
||
|
||
|
||
case 0x4b : { /* set date of file, file will be closed later */
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 filler;
|
||
uint8 fhandle[4]; /* Dateihandle */
|
||
uint8 reserve[2]; /* ext Filehandle ??? */
|
||
uint8 zeit[2]; /* time */
|
||
uint8 datum[2]; /* date */
|
||
} *input = (struct INPUT *)ncprequest;
|
||
int result = nw_set_fdate_time(GET_BE32(input->fhandle),
|
||
input->datum, input->zeit);
|
||
if (result <0) completition = (uint8) -result;
|
||
}
|
||
break;
|
||
|
||
case 0x4c : { /* open file */
|
||
struct INPUT {
|
||
uint8 header[7]; /* Requestheader */
|
||
uint8 dirhandle; /* Dirhandle */
|
||
uint8 attrib; /* z.B. 0x6 od. 0x4e */
|
||
/* O_RDWR|TRUNC 0x6, O_RDONLY 0x6 */
|
||
|
||
uint8 access; /* z.B. 0x9 od 0x11 od. 0x13 */
|
||
/* O_RDWR|TRUNC 0x13, O_RDONLY 0x11 */
|
||
/* O_RDWR|TRUNC|O_DENYNONE 0x3 */
|
||
/* 0x10 BINAERMODUS ?? */
|
||
/* 0x02 do write */
|
||
uint8 len; /* namelaenge */
|
||
uint8 data[2]; /* Name */
|
||
} *input = (struct INPUT *)ncprequest;
|
||
struct OUTPUT {
|
||
uint8 fhandle[4]; /* Dateihandle */
|
||
uint8 ext_fhandle[2]; /* z.B 0x0 0x0 */
|
||
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,
|
||
(int)input->access, 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);
|
||
#ifdef TEST_FNAME
|
||
input->data[input->len] = '\0';
|
||
if (strstr(input->data, TEST_FNAME)){
|
||
test_handle = fhandle;
|
||
do_druck++;
|
||
}
|
||
#endif
|
||
|
||
} else completition = (uint8) (-fhandle);
|
||
}
|
||
break;
|
||
|
||
#if 0
|
||
case 0x57 : /* some new calls */
|
||
{
|
||
uint8 ufunc = *(requestdata);
|
||
completition = 0xfb; /* erstmal */
|
||
if (ufunc == 0x02) { /* Initialize Search */
|
||
uint8 namespace=*(requestdata+1);
|
||
uint8 reserved=*(requestdata+2);
|
||
/* NW PATH STRUC */
|
||
} else if (ufunc == 0x07) { /* Modify File or Dir Info */
|
||
uint8 namespace=*(requestdata+1);
|
||
} else if (ufunc == 0x09) { /* Set short Dir Handle*/
|
||
uint8 namespace=*(requestdata+1);
|
||
uint8 datastream=*(requestdata+2);
|
||
uint8 desthandle=*(requestdata+3);
|
||
/* 1 Byte Reserved */
|
||
/* NWPATH STRUC */
|
||
} else if (ufunc == 0x15) { /* Get Path String from short dir neu*/
|
||
uint8 namespace=*(requestdata+1);
|
||
uint8 short_dir_handle=*(requestdata+2);
|
||
} else if (ufunc == 0x16) {
|
||
/* Generate Dir BASE and VolNumber */
|
||
uint8 namespace = *(requestdata+1);
|
||
uint8 *nwpathstruct = requestdata+4;
|
||
struct OUTPUT {
|
||
uint8 ns_dir_base[4]; /* BASEHANDLE */
|
||
uint8 dos_dir_base[4]; /* BASEHANDLE */
|
||
uint8 volume; /* Volumenumber*/
|
||
} *xdata= (struct OUTPUT*)responsedata;
|
||
int result = nw_generate_dir_path(nwpathstruct,
|
||
xdata->ns_dir_base, xdata->dos_dir_base);
|
||
if (result >-1) {
|
||
data_len = sizeof(struct OUTPUT);
|
||
xdata->volume = result;
|
||
completition=0;
|
||
} else completition = (uint8)(-result);
|
||
} else if (ufunc == 0x0c) { /* alloc short dir Handle */
|
||
uint8 namespace = *(requestdata+1);
|
||
int allocatemode = GET_BE16(requestdata+2);
|
||
/* NWPATH STRUC */
|
||
} else if (ufunc == 0x1a) { /* Get Huge NS Info neu*/
|
||
uint8 namespace=*(requestdata+1);
|
||
} else if (ufunc == 0x1c) { /* GetFullPathString neu*/
|
||
uint8 snamespace=*(requestdata+1);
|
||
uint8 dnamespace=*(requestdata+2);
|
||
} else if (ufunc == 0x1d) { /* GetEffDirRights neu*/
|
||
uint8 namespace=*(requestdata+1);
|
||
}
|
||
} break;
|
||
#endif
|
||
|
||
#if 0
|
||
case 0x61 : { /* Negotiate Buffer Size, Packetsize new ??? */
|
||
/* same request as 0x21 */
|
||
}
|
||
#endif
|
||
|
||
default : completition = 0xfb; /* unknown request */
|
||
break;
|
||
|
||
} /* switch function */
|
||
} else if (ncp_type == 0x1111) {
|
||
(void) nw_init_connect();
|
||
last_sequence = -9999;
|
||
} else {
|
||
printf("WRONG TYPE 0x%x IN NWCONN\n", ncp_type);
|
||
completition = 0xfb;
|
||
}
|
||
if (completition == 0xfb || (do_druck == 1)) { /* UNKWON FUNCTION od. TYPE */
|
||
int x_nw_debug = nw_debug;
|
||
if (!nw_debug || do_druck == 1) {
|
||
int j = requestlen;
|
||
nw_debug = 1;
|
||
DPRINTF(("NCP REQUEST: seq:%d, task:%d, reserved:0x%x, func:0x%x\n",
|
||
sequence, task, reserved, function));
|
||
if (j > 0){
|
||
uint8 *p=requestdata;
|
||
DPRINTF(("len %d, DATA:", j));
|
||
while (j--) {
|
||
int c = *p++;
|
||
if (c > 32 && c < 127) DPRINTF((",\'%c\'", (char) c));
|
||
else DPRINTF((",0x%x", c));
|
||
}
|
||
DPRINTF(("\n"));
|
||
}
|
||
}
|
||
if (completition == 0xfb)
|
||
DPRINTF(("UNKNOWN FUNCTION od. TYPE: 0x%x\n", function));
|
||
else if (data_len){
|
||
int j = data_len;
|
||
uint8 *p = responsedata;
|
||
DPRINTF(("RSPONSE: len %d, DATA:", data_len));
|
||
while (j--) {
|
||
int c = *p++;
|
||
if (c > 32 && c < 127) DPRINTF((",\'%c\'", (char) c));
|
||
else DPRINTF((",0x%x", c));
|
||
}
|
||
DPRINTF(("\n"));
|
||
}
|
||
nw_debug = x_nw_debug;
|
||
}
|
||
|
||
ncp_response(sequence, completition, data_len);
|
||
if (nw_debug != 99 && nw_debug != -99) nw_debug = org_nw_debug;
|
||
else if (nw_debug == -99) nw_debug = 0;
|
||
}
|
||
|
||
static int fl_get_debug=0;
|
||
static void get_new_debug(void)
|
||
{
|
||
get_ini_debug(3);
|
||
fl_get_debug=0;
|
||
}
|
||
|
||
static void sig_hup(int rsig)
|
||
{
|
||
signal(SIGHUP, SIG_IGN);
|
||
fl_get_debug++;
|
||
signal(SIGHUP, sig_hup);
|
||
}
|
||
|
||
extern int t_errno;
|
||
int main(int argc, char **argv)
|
||
{
|
||
int completition = 0;
|
||
if (argc != 8) {
|
||
printf("usage nwconn PID FROM_ADDR Connection UID GID Debug1 Debugipx\n");
|
||
exit(1);
|
||
} else father_pid = atoi(*(argv+1));
|
||
|
||
DPRINTF(("FATHER PID=%d, ADDR=%s CON:%s\n", father_pid, *(argv+2), *(argv+3)));
|
||
adr_to_ipx_addr(&from_addr, *(argv+2));
|
||
|
||
default_gid = atoi(*(argv+4));
|
||
default_uid = atoi(*(argv+5));
|
||
nw_debug = atoi(*(argv+6));
|
||
ipxdebug = atoi(*(argv+7));
|
||
|
||
#ifdef LINUX
|
||
set_emu_tli(ipxdebug);
|
||
#endif
|
||
if (nw_init_connect()) exit(1);
|
||
|
||
last_sequence = -9999;
|
||
if (open_ipx_socket()) exit(1);
|
||
|
||
set_default_guid();
|
||
|
||
ud.opt.len = sizeof(uint8);
|
||
ud.opt.maxlen = sizeof(uint8);
|
||
ud.opt.buf = (char*)&ipx_pack_typ;
|
||
|
||
ud.addr.len = sizeof(ipxAddr_t);
|
||
ud.addr.maxlen = sizeof(ipxAddr_t);
|
||
ud.addr.buf = (char*)&from_addr;
|
||
ud.udata.buf = (char*)&ipxdata;
|
||
U16_TO_BE16(0x3333, ncpresponse->type);
|
||
ncpresponse->task = (uint8) 1; /* allways 1 */
|
||
ncpresponse->reserved = (uint8) 0; /* allways 0 */
|
||
ncpresponse->connection = (uint8) atoi(*(argv+3));
|
||
|
||
signal(SIGHUP, sig_hup);
|
||
|
||
while (1) {
|
||
int data_len = read(0, readbuff, sizeof(readbuff));
|
||
ncpresponse->connect_status = (uint8) 0;
|
||
if (data_len > 0) {
|
||
if (fl_get_debug) get_new_debug();
|
||
XDPRINTF((99, "NWCONN GOT DATA len = %d\n",data_len));
|
||
|
||
if ((ncp_type = (int)GET_BE16(ncprequest->type)) == 0x3333) {
|
||
/* OK for direct sending */
|
||
data_len -= sizeof(NCPRESPONSE);
|
||
XDPRINTF((99, "NWCONN:direct sending:type 0x3333, completition=0x%x, len=%d\n",
|
||
(int)(ncprequest->function), data_len));
|
||
if (data_len) memcpy(responsedata, readbuff+sizeof(NCPRESPONSE), data_len);
|
||
ncpresponse->connect_status = ((NCPRESPONSE*)readbuff)->connect_status;
|
||
ncp_response((int)(ncprequest->sequence), (int)(ncprequest->function), data_len);
|
||
} else { /* this calls I must handle */
|
||
requestlen = data_len - sizeof(NCPREQUEST);
|
||
handle_ncp_serv();
|
||
}
|
||
|
||
} else if (data_len < 0) {
|
||
if (fl_get_debug) get_new_debug();
|
||
else break;
|
||
}
|
||
}
|
||
close(0);
|
||
|
||
if (ipx_fd > -1){
|
||
while ((completition = t_unbind(ipx_fd)) < 0) {
|
||
if (t_errno != TOUTSTATE) break;
|
||
}
|
||
t_close(ipx_fd);
|
||
}
|
||
return(0);
|
||
}
|