mars-nwe/connect.c

1749 lines
49 KiB
C
Raw Blame History

/* connect.h 21-Nov-95 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "net.h"
#include <dirent.h>
#include <utime.h>
#include <sys/errno.h>
extern int errno;
#define TEST_FNAME "PRINT.000"
static int test_handle=-1;
typedef struct {
int fd; /* von System bei Open bzw. Create */
long offd; /* aktueller File Offset */
time_t tmodi; /* modification TIME */
char name[256]; /* UNIX Dateiname */
} FILE_HANDLE;
typedef struct {
DIR *f;
char unixname[256]; /* kompletter unixname */
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 */
} DIR_HANDLE;
typedef struct {
uint8 *sysname; /* VOL_NAME */
uint8 *unixname; /* UNIX-Verzeichnis */
uint8 options; /* *_1_* alles in Kleinbuchstaben */
} NW_VOL;
typedef struct {
uint8 path[256]; /* directory */
uint8 fn[256]; /* file */
int volume; /* Volume Number */
int has_wild; /* fn has wildcards */
} NW_PATH;
typedef struct {
ino_t inode; /* Unix Inode dieses Verzeichnisses */
time_t timestamp; /* Zeitmarke */
uint8 *path; /* path ab Volume */
uint8 volume; /* Welches Volume */
uint8 is_temp; /* 0:perm. 1:temp 2: spez. temp */
uint8 drive; /* driveletter */
uint8 task; /* actual task */
} NW_DIR;
#define MAX_NW_DIRS 255
static NW_DIR dirs[MAX_NW_DIRS];
static int used_dirs=0;
static NW_VOL vols[MAX_NW_VOLS];
static int used_vols=0;
static int connect_is_init = 0;
#define MAX_FILEHANDLES 80
#define MAX_DIRHANDLES 80
static FILE_HANDLE file_handles[MAX_FILEHANDLES];
static DIR_HANDLE dir_handles[MAX_DIRHANDLES];
static int anz_fhandles=0;
static int anz_dirhandles=0;
static char *build_unix_name(NW_PATH *nwpath, int modus)
/*
* returns complete UNIX path
* modus & 1 : ignore fn, (only path)
* modus & 2 : no '/' at end
*/
{
static char unixname[300]; /* must be big enouugh */
int volume = nwpath->volume;
char *p, *pp;
if (volume < 0 || volume >= used_vols) {
fprintf(stderr, "build_unix_name volume=%d not ok\n", volume);
strcpy(unixname, "ZZZZZZZZZZZZ"); /* vorsichthalber */
return(unixname);
}
strcpy(unixname, vols[volume].unixname); /* first UNIXNAME VOLUME */
p = pp = unixname+strlen(unixname);
strcpy(p, nwpath->path); /* now the path */
p += strlen(nwpath->path);
if ( (!(modus & 1)) && nwpath->fn[0])
strcpy(p, nwpath->fn); /* und jetzt fn */
else if ((modus & 2) && (*(p-1) == '/')) *(p-1) = '\0';
if (vols[volume].options & 1) downstr((uint8*)pp);
return(unixname);
}
static int new_file_handle(void)
{
int rethandle = -1;
FILE_HANDLE *fh=NULL;
while (++rethandle < anz_fhandles) {
if (file_handles[rethandle].fd < 0) { /* empty slot */
fh = &(file_handles[rethandle]);
rethandle++;
break;
}
}
if (fh == NULL) {
if (anz_fhandles < MAX_FILEHANDLES) {
fh=&(file_handles[anz_fhandles]);
rethandle = ++anz_fhandles;
} else return(0); /* no free handle anymore */
}
/* init handle */
fh->fd = -1;
fh->offd = 0L;
fh->tmodi = 0L;
fh->name[0] = '\0';
return(rethandle);
}
static int free_file_handle(int fhandle)
{
if (fhandle > 0 && (fhandle <= anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle-1]);
if (fh->fd > -1) {
close(fh->fd);
fh->fd = -1;
if (fh->tmodi > 0L) {
/* now set date and time */
struct utimbuf ut;
ut.actime = ut.modtime = fh->tmodi;
utime(fh->name, &ut);
}
}
if (fhandle == anz_fhandles) {
/* was last */
anz_fhandles--;
while (anz_fhandles && file_handles[anz_fhandles-1].fd < 0)
anz_fhandles--;
}
return(0);
}
return(-0x88); /* wrong filehandle */
}
static int new_dir_handle(ino_t inode, NW_PATH *nwpath)
/*
* RETURN=errorcode (<0) or dir_handle
*/
{
int rethandle;
DIR_HANDLE *fh = NULL;
time_t akttime = time(NULL);
time_t last_time = akttime;
int thandle = 0;
int nhandle = 0;
for (rethandle=0; rethandle < anz_dirhandles; rethandle++){
fh=&(dir_handles[rethandle]);
if (fh->f == (DIR*) NULL) {
if (!nhandle) nhandle = rethandle+1;
} else if (fh->inode == inode && fh->volume == nwpath->volume){
/* Dieser hat Vorrang */
if (fh->f) closedir(fh->f);
fh->f = NULL;
fh->timestamp = akttime;
nhandle = rethandle+1;
break;
} else if (fh->timestamp < last_time){
thandle = rethandle+1;
last_time = fh->timestamp;
}
}
if (!nhandle){
if (anz_dirhandles < MAX_DIRHANDLES) {
fh=&(dir_handles[anz_dirhandles]);
rethandle = ++anz_dirhandles;
} else {
fh=&(dir_handles[thandle-1]);
if (fh->f) closedir(fh->f);
fh->f = NULL;
rethandle = thandle;
}
} else rethandle=nhandle;
/* init dir_handle */
fh=&(dir_handles[rethandle-1]);
strcpy(fh->unixname, build_unix_name(nwpath, 0));
if ((fh->f = opendir(fh->unixname)) != (DIR*) NULL){
fh->kpath = fh->unixname + strlen(fh->unixname);
fh->volume = nwpath->volume;
fh->vol_options = vols[fh->volume].options;
fh->inode = inode;
fh->timestamp = akttime;
} else {
fh->f = (DIR*)NULL;
fh->unixname[0] = '\0';
fh->vol_options = 0;
fh->kpath = (char*)NULL;
rethandle = -0x9c;
}
return(rethandle);
}
static int free_dir_handle(int dhandle)
{
if (dhandle > 0 && --dhandle < anz_dirhandles) {
DIR_HANDLE *fh=&(dir_handles[dhandle]);
if (fh->f != (DIR*) NULL) {
closedir(fh->f);
fh->f = (DIR*)NULL;
}
while (anz_dirhandles && dir_handles[anz_dirhandles-1].f == (DIR*)NULL)
anz_dirhandles--;
return(0);
}
return(-0x88); /* wrong dir_handle */
}
static char *get_nwpath_name(NW_PATH *p)
/* for debugging */
{
static char nwpathname[300];
char volname[100];
if (p->volume < 0 || p->volume >= used_vols) {
sprintf(volname, "<%d=NOT-OK>", (int)p->volume);
} else strcpy(volname, vols[p->volume].sysname);
sprintf(nwpathname, "%s:%s%s", volname, p->path, p->fn);
return(nwpathname);
}
static int x_str_match(uint8 *s, uint8 *p)
{
uint8 pc, sc;
uint state = 0;
uint8 anf, ende;
int not = 0;
uint found = 0;
while ( (pc = *p++) != 0) {
switch (state){
case 0 :
switch (pc) {
case '\\': /* beliebiges Folgezeichen */
if (*p++ != *s++) return(0);
break;
case '?' : if (! *s++) return(0); /* one character */
break;
case '.' : if (!*s && !*p) return(1); /* point at end */
if (pc != *s++) return(0);
if (*p == '*') return(1);
break;
case '*' : if (!*p) {
uint8 *ss=s;
while (*ss) if (*ss++ == '.') return(0);
return(1); /* last star */
}
while (*s){
if (x_str_match(s, p) == 1) return(1);
++s;
}
return((*p == '.' && *(p+1) == '*') ? 1 : 0);
case '[' : if ( (*p == '!') || (*p == '^') ){
++p;
not = 1;
}
state = 1;
continue;
default : if (pc != *s++) return(0); /* normal char */
break;
} /* switch */
break;
case 1 : /* Bereich von Zeichen */
sc = *s++;
found = not;
if (!sc) return(0);
do {
if (pc == '\\') pc = *(p++);
if (!pc) return(0);
anf = pc;
if (*p == '-' && *(p+1) != ']'){
ende = *(++p);
p++;
}
else ende = anf;
if (found == not) { /* only if not found */
if (anf == sc || (anf <= sc && sc <= ende))
found = !not;
}
} while ((pc = *(p++)) != ']');
if (! found ) return(0);
not = 0;
found = 0;
state = 0;
break;
default : break;
} /* switch */
} /* while */
return ( (*s) ? 0 : 1);
}
static int str_match(uint8 *s, uint8 *p, uint8 options)
{
uint8 *ss=s;
int len=0;
int pf=0;
for (; *ss; ss++){
len++;
if (*ss == '.') {
if (pf++) return(0); /* Kein 2. Punkt */
len=0;
} else {
if ((pf && len > 3) || len > 8) return(0);
if (options & 1){ /* only downshift chars */
if (*ss >= 'A' && *ss <= 'Z') return(0);
} else { /* only upshift chars */
if (*ss >= 'a' && *ss <= 'z') return(0);
}
}
}
return(x_str_match(s, p));
}
static int get_dir_entry(NW_PATH *nwpath,
int *sequence,
int attrib,
struct stat *statb)
/* returns 1 if OK and 0 if not OK */
{
struct dirent* dirbuff;
DIR *f;
int okflag=0;
char xkpath[256];
uint8 entry[256];
int volume = nwpath->volume;
uint8 soptions;
if (volume < 0 || volume >= used_vols) return(0); /* something wrong */
else soptions = vols[volume].options;
strcpy(entry, nwpath->fn);
if (soptions & 1) downstr(entry); /* now downshift chars */
nwpath->fn[0] = '\0';
strcpy(xkpath, build_unix_name(nwpath, 1|2));
DPRINTF(("get_dir_entry attrib=0x%x path:%s:, xkpath:%s:, entry:%s:\n",
attrib, nwpath->path, xkpath, entry));
if ((f=opendir(xkpath)) != (DIR*)NULL) {
char *kpath=xkpath+strlen(xkpath);
*kpath++ = '/';
if (*sequence == MAX_U16) *sequence = 0;
else seekdir(f, (long)*sequence);
while ((dirbuff = readdir(f)) != (struct dirent*)NULL){
okflag = 0;
if (dirbuff->d_ino) {
uint8 *name=(uint8*)(dirbuff->d_name);
okflag = (name[0] != '.' &&
( (entry[0] == '*' && entry[1] == '\0')
|| (!strcmp(name, entry))
|| str_match(name, entry, soptions)));
if (okflag) {
*kpath = '\0';
strcpy(kpath, name);
if (!stat(xkpath, statb)) {
okflag = ( ( ( (statb->st_mode & S_IFMT) == S_IFDIR) && (attrib & 0x10))
|| ( ( (statb->st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10)));
if (okflag){
strcpy(nwpath->fn, name);
if (soptions & 1) upstr(nwpath->fn);
DPRINTF(("FOUND=:%s: attrib=0x%x\n", nwpath->fn, statb->st_mode));
break; /* ready */
}
} else okflag = 0;
}
XDPRINTF((4, "NAME=:%s: OKFLAG %d\n", name, okflag));
} /* if */
} /* while */
*sequence = (int) telldir(f);
closedir(f);
} /* if */
return(okflag);
}
static int get_dh_entry(DIR_HANDLE *dh,
uint8 *search,
int *sequence,
int attrib,
struct stat *statb)
/* returns 1 if OK and 0 if not OK */
{
DIR *f = dh->f;
int okflag = 0;
if (f != (DIR*)NULL) {
struct dirent* dirbuff;
uint8 entry[256];
strmaxcpy(entry, search, 255);
if (dh->vol_options & 1) downstr(entry);
if ( (uint16)*sequence == MAX_U16) *sequence = 0;
seekdir(f, (long) *sequence);
DPRINTF(("get_dh_entry attrib=0x%x path:%s:, entry:%s:\n",
attrib, dh->unixname, entry));
while ((dirbuff = readdir(f)) != (struct dirent*)NULL){
okflag = 0;
if (dirbuff->d_ino) {
uint8 *name=(uint8*)(dirbuff->d_name);
okflag = (name[0] != '.' && (
(!strcmp(name, entry)) ||
(entry[0] == '*' && entry[1] == '\0')
|| str_match(name, entry, dh->vol_options)));
if (okflag) {
strcpy(dh->kpath, name);
DPRINTF(("get_dh_entry Name=%s unixname=%s\n",
name, dh->unixname));
if (!stat(dh->unixname, statb)) {
okflag = ( (( (statb->st_mode & S_IFMT) == S_IFDIR) && (attrib & 0x10))
|| (((statb->st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10)));
if (okflag){
strcpy(search, name);
if (dh->vol_options & 1) upstr(search);
break; /* Bin fertig */
}
} else okflag = 0;
}
} /* if */
} /* while */
dh->kpath[0] = '\0';
*sequence = (int) telldir(f);
} /* if */
return(okflag);
}
static void build_path_fn( uint8 *vol,
uint8 *path,
uint8 *fn,
int *has_wild,
uint8 *data,
int len)
/* is called from build_path */
{
uint8 *p = NULL;
uint8 *p1 = path;
*vol = '\0';
*has_wild = 0; /* no wild char */
while (len-- && *data){
if (*data == 0xae) *p1++ = '.';
else if (*data > 0x60 && *data < 0x7b) {
*p1++ = *data - 0x20; /* all is upshift */
} else if (*data == 0xaa|| *data == '*' ) {
*p1++ = '*';
(*has_wild)++;
} else if (*data == 0xbf|| *data == '?' ) {
*p1++ = '?';
(*has_wild)++;
} else if (*data == '/' || *data == '\\') {
*p1++ = '/';
p = p1;
} else if (*data == ':') { /* extract volume */
int len = (int) (p1 - path);
memcpy(vol, path, len);
vol[len] = '\0';
p1 = path;
} else *p1++ = *data;
data++;
}
*p1 = '\0';
if (fn != NULL) { /* if with filename */
if (p != NULL){ /* exist directory-path */
strcpy(fn, p);
*p = '\0';
} else { /* only filename */
strcpy(fn, path);
*path= '\0';
}
}
}
static int build_path( NW_PATH *path,
uint8 *data,
int len,
int only_dir)
/*
* fills path structur with the right values
* if only_dir > 0, then the full path will be interpreted
* as directory, in the other way, the last segment of path
* will be interpreted as fn.
* returns -0x98, if volume is wrong
*/
{
uint8 vol[20];
build_path_fn(vol, path->path,
(only_dir) ? (uint8)NULL
: path->fn,
&(path->has_wild),
data, len);
path->volume = -1;
if (only_dir) path->fn[0] = '\0';
if (vol[0]) { /* there is a volume in path */
int j = used_vols;
while (j--) {
if (!strcmp(vols[j].sysname, vol)) {
path->volume = j;
break;
}
}
if (path->volume < 0) return(-0x98);
}
return(0);
}
static int nw_path_ok(NW_PATH *nwpath)
/* returns UNIX inode of path */
{
int j = 0;
NW_DIR *d=&(dirs[0]);
struct stat stbuff;
int result = -0x9c; /* wrong path */
while (j++ < (int)used_dirs){
if (d->inode && d->volume == nwpath->volume
&& !strcmp(nwpath->path, d->path)){
return(d->inode);
}
d++;
} /* while */
if (!stat(build_unix_name(nwpath, 1 | 2 ), &stbuff)){
if ((stbuff.st_mode & S_IFMT) == S_IFDIR) result=stbuff.st_ino;
}
return(result);
}
static int build_verz_name(NW_PATH *nwpath, /* gets complete path */
int dir_handle) /* search with dirhandle */
/* return -completition code or inode */
{
uint8 searchpath[256];
uint8 *p=searchpath;
int completition=0;
strcpy(searchpath, nwpath->path); /* save path */
if (nwpath->volume > -1) { /* absolute path */
nwpath->path[0] = '\0';
} else { /* volume not kwown yet, I must get it about dir_handle */
if (dir_handle > 0 &&
--dir_handle < (int)used_dirs && dirs[dir_handle].inode){
nwpath->volume = dirs[dir_handle].volume;
if (searchpath[0] == '/') { /* absolute path */
p++;
nwpath->path[0] = '\0';
} else /* get path from dir_handle */
strcpy(nwpath->path, dirs[dir_handle].path);
} else return(-0x9b); /* wrong dir handle */
}
if (*p) {
uint8 *panf = nwpath->path;
uint8 *p1 = panf+strlen((char*)panf);
uint8 *a = p;
uint8 w;
int state = 0;
while ((!completition) && (w = *p++) > 0){
if (!state){
DPRINTF(("in build_verz_name path=:%s:\n", nwpath->path));
if (w == '.') state = 20;
else if (w == '/') state = 30;
else state++;
} else if (state < 9){
if (w == '.') state = 10;
else if (w == '/') state = 30;
else state++;
} else if (state == 9) completition= -0x9c; /* something wrong */
else if (state < 14){
if (w == '.') return(-0x9c);
else if (w == '/') state = 30;
else state++;
} else if (state == 14) completition= -0x9c; /* something wrong */
else if (state == 20){
if (w == '/') state = 30;
else if (w != '.') completition= -0x9c; /* something wrong */
}
if (state == 30 || !*p) { /* now action */
uint8 *xpath=a;
int len = (int)(p-a);
if (len && state == 30) --len; /* '/' stoert hier */
a = p;
if (len) {
if (*xpath == '.') {
uint8 *xp=xpath+1;
if (*xp == '.') {
while (*xp++ == '.' && completition > -1) {
p1--; /* steht nun auf letztem Zeichen '/' od. ':' */
if (p1 < panf) completition = -0x9c ;
/* Falscher Pfad, denn weiter zurueck gehts nicht */
else {
while (p1 > panf && *(--p1) != '/');;
if (p1 == panf) *p1='\0';
else *(++p1) = '\0';
}
}
}
} else {
memcpy(p1, xpath, len);
p1 += len;
*p1++ = '/';
*p1 = '\0';
}
} /* if len */
state = 0;
}
}
}
if (!completition) completition = nw_path_ok(nwpath);
return(completition);
}
static int get_kpl_path(NW_PATH *nwpath, int dirhandle,
uint8 *data, int len, int only_dir)
/*
* if ok then the inode of dir will be returned
* else a negativ errcode will be returned
*/
{
int completition = build_path(nwpath, data, len, only_dir);
if (!completition) completition = build_verz_name(nwpath, dirhandle);
return(completition);
}
static void un_date_2_nw(time_t time, uint8 *d)
{
struct tm *s_tm=localtime(&time);
uint16 xdate=s_tm->tm_year - 80;
xdate <<= 4;
xdate |= s_tm->tm_mon+1;
xdate <<= 5;
xdate |= s_tm->tm_mday;
U16_TO_BE16(xdate, d);
}
static time_t nw_2_un_time(uint8 *d, uint8 *t)
{
uint16 xdate = GET_BE16(d);
uint16 xtime = (t != (uint8*) NULL) ? GET_BE16(t) : 0;
int year = (xdate >> 9) + 80;
int month = (xdate >> 5) & 0x0F;
int day = xdate & 0x1f;
int hour = xtime >> 11;
int minu = (xtime >> 5) & 0x3f;
int sec = xtime & 0x1f;
struct tm s_tm;
s_tm.tm_year = year;
s_tm.tm_mon = month-1;
s_tm.tm_mday = day;
s_tm.tm_hour = hour;
s_tm.tm_min = minu;
s_tm.tm_sec = sec;
return(mktime(&s_tm));
}
static void un_time_2_nw(time_t time, uint8 *d)
{
struct tm *s_tm=localtime(&time);
uint16 xdate=s_tm->tm_hour;
xdate <<= 6;
xdate |= s_tm->tm_min;
xdate <<= 5;
xdate |= (s_tm->tm_sec / 2);
U16_TO_BE16(xdate, d);
}
static int get_file_attrib(NW_FILE_INFO *f, struct stat *stb,
NW_PATH *nwpath)
{
strncpy(f->name, nwpath->fn, sizeof(f->name));
/* Attribute */
/* 0x20 Archive Flag */
/* 0x80 Sharable */ /* TLINK (TCC 2.0) don't like it ???? */
if (!strcmp(nwpath->fn, "TURBOC.$LN")) f->attrib = 0x20;
else f->attrib = 0x80;
f->ext_attrib = 0;
un_date_2_nw(stb->st_mtime, f->create_date);
un_date_2_nw(stb->st_atime, f->acces_date );
un_date_2_nw(stb->st_mtime, f->modify_date);
un_time_2_nw(stb->st_mtime, f->modify_time);
U32_TO_BE32(stb->st_size, f->size);
return(1);
}
static int get_dir_attrib(NW_DIR_INFO *d, struct stat *stb,
NW_PATH *nwpath)
{
strncpy(d->name, nwpath->fn, sizeof(d->name));
d->attrib = 0x10; /* Verzeichnis */
d->ext_attrib = 0xff; /* effektive rights ?? */
un_date_2_nw(stb->st_mtime, d->create_date);
un_time_2_nw(stb->st_mtime, d->create_time);
U32_TO_BE32(1L, d->owner_id);
d->access_right_mask = 0;
d->reserved = 0;
U16_TO_BE16(0, d->next_search);
return(1);
}
int nw_creat_open_file(int dir_handle, uint8 *data, int len,
NW_FILE_INFO *info, int attrib, int access, int creatmode)
/*
* creatmode: 0 = open, 1 = creat, 2 = creatnew
* attrib ??
* access: 0x1=read, 0x2=write
*/
{
int fhandle=new_file_handle();
if (fhandle){
FILE_HANDLE *fh=&(file_handles[fhandle-1]);
NW_PATH nwpath;
int completition = get_kpl_path(&nwpath, dir_handle, data, len, 0);
#ifdef TEST_FNAME
int got_testfn = 0;
if (!nw_debug){
if (strstr(nwpath.fn, TEST_FNAME)){
nw_debug = 99;
got_testfn++;
}
}
#endif
if (completition > -1) {
struct stat stbuff;
completition = -0xff; /* no File Found */
strcpy(fh->name, build_unix_name(&nwpath, 0));
if (creatmode) { /* creat File */
if (creatmode & 0x2) { /* creatnew */
if (!stat(fh->name, &stbuff)) {
DPRINTF(("CREAT File exist!! :%s:\n", fh->name));
fh->fd = -1;
completition = -0x85; /* No Priv */
} else {
DPRINTF(("CREAT FILE:%s: Handle=%d\n", fh->name, fhandle));
fh->fd = creat(fh->name, 0777);
if (fh->fd < 0) completition = -0x84; /* no create Rights */
}
} else {
DPRINTF(("CREAT FILE, ever with attrib:0x%x, access:0x%x, fh->name:%s: handle:%d\n",
attrib, access, fh->name, fhandle));
fh->fd = open(fh->name, O_CREAT|O_TRUNC|O_RDWR, 0777);
if (fh->fd < 0) completition = -0x85; /* no delete /create Rights */
}
if (fh->fd > -1) {
close(fh->fd);
fh->fd = open(fh->name, O_RDWR);
fh->offd = 0L;
stat(fh->name, &stbuff);
}
} else {
int statr = stat(fh->name, &stbuff);
int acm = (access & 2) ? (int) O_RDWR /*|O_CREAT*/ : (int)O_RDONLY;
if ( (!statr && (stbuff.st_mode & S_IFMT) != S_IFDIR)
|| (statr && (acm & O_CREAT))){
DPRINTF(("OPEN FILE with attrib:0x%x, access:0x%x, fh->name:%s: fhandle=%d\n",attrib,access, fh->name, fhandle));
fh->fd = open(fh->name, acm, 0777);
fh->offd = 0L;
if (fh->fd > -1) {
if (statr) stat(fh->name, &stbuff);
} else completition = -0x9a;
}
}
if (fh->fd > -1) {
get_file_attrib(info, &stbuff, &nwpath);
#ifdef TEST_FNAME
if (got_testfn) test_handle = fhandle;
#endif
return(fhandle);
}
}
DPRINTF(("OPEN FILE not OK ! fh->name:%s: fhandle=%d\n",fh->name, fhandle));
free_file_handle(fhandle);
#ifdef TEST_FNAME
if (got_testfn) {
test_handle = -1;
nw_debug = -99;
}
#endif
return(completition);
} else return(-0x81); /* no more File Handles */
}
int nw_delete_datei(int dir_handle, uint8 *data, int len)
/* TODO: handle wildcards !!! */
{
NW_PATH nwpath;
int completition = get_kpl_path(&nwpath, dir_handle, data, len, 0);
if (completition > -1) {
char unname[256];
struct stat stbuff;
strcpy(unname, build_unix_name(&nwpath, 0));
DPRINTF(("DELETE FILE unname:%s:\n", unname));
if (!stat(unname, &stbuff)){
if (!unlink(unname)) return(0);
return(-0x8a); /* NO Delete Privileges */
} else completition= -0xff; /* No Files Found */
}
return(completition);
}
int nw_chmod_datei(int dir_handle, uint8 *data, int len, int modus)
{
char unname[256];
struct stat stbuff;
int completition=-0x9c;
NW_PATH nwpath;
build_path(&nwpath, data, len, 0);
if (nwpath.fn[0] != '.') { /* Files with . at the beginning are not ok */
completition = build_verz_name(&nwpath, dir_handle);
}
if (completition < 0) return(completition);
strcpy(unname, build_unix_name(&nwpath, 2));
DPRINTF(("CHMOD DATEI unname:%s:\n", unname));
if (!stat(unname, &stbuff)){
return(0);
}
return(-0x9c); /* wrong path */
}
int nw_close_datei(int fhandle)
{
if (fhandle > 0 && (fhandle <= anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle-1]);
if (fh->fd > -1) {
close(fh->fd);
fh->fd = -1;
if (fh->tmodi > 0L) {
struct utimbuf ut;
ut.actime = ut.modtime = fh->tmodi;
utime(fh->name, &ut);
}
#ifdef TEST_FNAME
if (fhandle == test_handle) {
test_handle = -1;
nw_debug = -99;
}
#endif
return(free_file_handle(fhandle));
}
}
return(-0x88); /* wrong filehandle */
}
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;
return(size);
}
}
return(- 0x88); /* wrong filehandle */
}
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;
}
return(size);
}
}
return(-0x88); /* wrong filehandle */
}
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);
DPRINTF(("File %s is stripped, result=%d\n", fh->name, result));
#endif
return(result);
}
}
}
return(- 0x88); /* wrong filehandle */
}
int nw_server_copy(int qfhandle, uint32 qoffset,
int zfhandle, uint32 zoffset,
uint32 size)
{
if (qfhandle > 0 && (--qfhandle < anz_fhandles)
&& zfhandle > 0 && (--zfhandle < anz_fhandles) ) {
FILE_HANDLE *fhq=&(file_handles[qfhandle]);
FILE_HANDLE *fhz=&(file_handles[zfhandle]);
int retsize = -1;
if (fhq->fd > -1 && fhz->fd > -1) {
char buff[2048];
int wsize;
if (lseek(fhq->fd, qoffset, SEEK_SET) > -1L &&
lseek(fhz->fd, zoffset, SEEK_SET) > -1L) {
retsize = 0;
while (size && !retsize) {
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 */
break;
} else {
size -= (uint32)xsize;
retsize += wsize;
}
} else {
if (xsize < 0) retsize=-0x93; /* no read privilegs */
break;
}
}
}
fhq->offd = -1L;
fhz->offd = -1L;
/*
if (!retsize) (retsize=fhz->offd=lseek(fhz->fd, 0L, SEEK_END));
*/
return(retsize);
}
}
return(- 0x88); /* Falscher Filehandle */
}
int nw_lock_datei(int fhandle, int offset, int size, int do_lock)
{
if (fhandle > 0 && (--fhandle < anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle]);
if (fh->fd > -1) {
struct flock flockd;
int result;
flockd.l_type = (do_lock) ? F_WRLCK : F_UNLCK;
flockd.l_whence = SEEK_SET;
flockd.l_start = offset;
flockd.l_len = size;
result = fcntl(fh->fd, F_SETLK, &flockd);
if (!result) return(0);
else return(-0x21); /* LOCK Violation */
}
}
return(-0x88); /* wrong filehandle */
}
int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode)
{
NW_PATH nwpath;
int completition = get_kpl_path(&nwpath, dir_handle, data, len, !mode);
if (completition > -1) {
char unname[256];
strcpy(unname, build_unix_name(&nwpath, 2));
#if 0
if (unname[0] && unname[1]) {
char *p=unname+strlen(unname)-1;
if (*p=='/') *p = '\0';
}
#endif
if (mode) {
DPRINTF(("MKDIR dirname:%s:\n", unname));
if (!mkdir(unname, 0777)) return(0);
completition = -0x84; /* No Create Priv.*/ /* -0x9f Direktory Aktive */
} else { /* rmdir */
DPRINTF(("RMDIR dirname:%s:\n", unname));
if (!rmdir(unname)) {
NW_DIR *d=&(dirs[0]);
int j = 0;
while (j++ < (int)used_dirs){
if (d->inode == completition) d->inode = 0;
d++;
}
completition = 0;
} else if (errno & EEXIST)
completition = -0xa0; /* dir not empty */
else completition = -0x8a; /* No privilegs */
}
}
return(completition);
}
int mv_file(int qdirhandle, uint8 *q, int qlen,
int zdirhandle, uint8 *z, int zlen)
{
NW_PATH quellpath;
NW_PATH zielpath;
int completition=get_kpl_path(&quellpath, qdirhandle, q, qlen, 0);
if (!completition > -1){
completition=get_kpl_path(&zielpath, zdirhandle, z, zlen, 0);
if (completition > -1){
char unquelle[256];
char unziel[256];
strcpy(unquelle, build_unix_name(&quellpath,0));
strcpy(unziel, build_unix_name(&zielpath,0));
if (!link(unquelle, unziel)){
if (unlink(unquelle)) {
completition=-0x9c;
/* TODO: here completition must be no pernmissions */
unlink(unziel);
}
} else {
if (errno & EEXIST)
completition=-0x91; /* allready exist */
else if (errno & 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,
int driveletter, int is_temp,
int new_entry, int task)
{
if (new_entry || (dir->inode && dir->is_temp != 2)) {
new_str(dir->path, path);
dir->inode = inode;
dir->volume = (uint8) volume;
dir->timestamp = time(NULL);
if (driveletter > -1) {
dir->drive = (uint8) driveletter;
dir->task = (uint8)task;
} else {
if (task < (int)dir->task) dir->task = (uint8) task;
}
if (is_temp > -1) dir->is_temp = (uint8) is_temp;
return(0);
} else {
if (!dir->inode) return(-0x9b); /* wrong handle */
else return(-0xfa); /* temp remap Error */
}
}
int nw_init_connect(void)
/* Cann be called when ever you want */
{
uint8 *login = (uint8*) "LOGIN/";
NW_PATH nwlogin;
FILE *f=open_nw_ini();
if (f != (FILE*) NULL){
uint8 buff[256];
struct stat stbuff;
int k = MAX_NW_DIRS;
NW_DIR *d = &(dirs[0]);
strcpy(nwlogin.path, login);
nwlogin.fn[0] = '\0';
nwlogin.volume = 0;
while (k--) {
if (connect_is_init) xfree(d->path);
else d->path = NULL;
d->volume = 0;
d->inode = 0;
d->is_temp = 0;
d->drive = 0;
d++;
}
if (!connect_is_init) {
k = -1;
connect_is_init++;
while (++k < MAX_NW_VOLS) {
vols[k].unixname = NULL;
vols[k].sysname = NULL;
vols[k].options = 0;
}
} else {
k = 0;
while (k++ < anz_fhandles) free_file_handle(k);
k = 0;
while (k++ < anz_dirhandles) free_dir_handle(k);
}
used_vols = 0;
while (fgets((char*)buff, sizeof(buff), f) != NULL && used_vols < MAX_NW_VOLS){
int len = strlen(buff);
int j =-1;
while (++j < len){
if (buff[j] == '#') {
buff[j] = '\0';
len = j;
break;
}
}
if (len > 3){
int what=0;
uint8 sysname[256];
uint8 unixname[256];
char optionstr[256];
char *p;
int len;
int founds = sscanf((char*)buff, "%d %s %s %s", &what, sysname, unixname, optionstr);
if (founds > 2 && what == 1) {
new_str(vols[used_vols].sysname, sysname);
len = strlen(unixname);
if (unixname[len-1] != '/') {
unixname[len++] = '/';
unixname[len] = '\0';
}
vols[used_vols].options = 0;
new_str(vols[used_vols].unixname, unixname);
if (founds > 3) {
for (p=optionstr; *p; p++) {
switch (*p) {
case 'k' : vols[used_vols].options |= 1;
default : break;
}
}
}
used_vols++;
}
}
}
fclose(f);
if (stat(build_unix_name(&nwlogin, 0), &stbuff)) {
perror("Stat error in nw_init_connect, Abbruch");
return(-1);
}
(void)change_dir_entry(&(dirs[0]), 0, nwlogin.path, stbuff.st_ino,
0, 0, 1, 0);
/* first Handle must be known und must not be temp */
/* and has no Drive-Character */
used_dirs = 1;
anz_fhandles = 0;
anz_dirhandles = 0;
return(0);
} else return(-1);
}
int nw_free_handles(int task)
/*
* if task==0 then all is initialized
* else the temp handles of the actuell task and greater
* are deleted. I hope it is right. !??
*/
{
if (!task) return(nw_init_connect());
else {
NW_DIR *d = &(dirs[0]);
int k = used_dirs;
while (k--) {
if (d->is_temp && d->task >= task) {
xfree(d->path);
d->volume = 0;
d->inode = 0;
d->is_temp = 0;
d->drive = 0;
}
d++;
}
}
return(0);
}
int insert_new_dir(NW_PATH *nwpath, int inode, int drive, int is_temp, int task)
{
int j = 0;
time_t lowtime = time(NULL);
int freehandle = 0;
int timedhandle = 0;
/* first look, wether drive is allready in use */
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);
return(++j);
} else if (!d->inode) freehandle = j+1;
else if (d->is_temp && d->timestamp < lowtime) {
timedhandle = j+1;
lowtime = d->timestamp;
}
}
if (!freehandle && used_dirs < MAX_NW_DIRS) freehandle = ++used_dirs;
if (!freehandle) freehandle = timedhandle;
if (freehandle){
(void)change_dir_entry(&(dirs[freehandle-1]),
nwpath->volume, nwpath->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 nw_search(uint8 *info,
int dirhandle, int searchsequence,
int search_attrib, uint8 *data, int len)
{
NW_PATH nwpath;
int completition = get_kpl_path(&nwpath, dirhandle, data, len, 0);
DPRINTF(("nw_search path:%s:, fn:%s:, completition:0x%x\n",
nwpath.path, nwpath.fn, completition));
if (completition > -1) {
struct stat stbuff;
if (get_dir_entry(&nwpath,
&searchsequence,
search_attrib,
&stbuff)){
if (search_attrib & 0x10) {
get_dir_attrib((NW_DIR_INFO*)info, &stbuff,
&nwpath);
} else {
get_file_attrib((NW_FILE_INFO*)info, &stbuff,
&nwpath);
}
return(searchsequence);
} else return(-0xff); /* not found */
} else return(completition); /* Falscher Pfad */
}
int nw_dir_search(uint8 *info,
int dirhandle, int searchsequence,
int search_attrib, uint8 *data, int len)
{
NW_PATH nwpath;
int completition=-0x9c;
build_path(&nwpath, data, len, 0);
if (dirhandle > 0 && --dirhandle < anz_dirhandles){
DIR_HANDLE *dh = &(dir_handles[dirhandle]);
struct stat stbuff;
if (get_dh_entry(dh,
nwpath.fn,
&searchsequence,
search_attrib,
&stbuff)){
/*
if ( (stbuff.st_mode & S_IFMT) == S_IFDIR) {
*/
if (search_attrib & 0x10) {
get_dir_attrib((NW_DIR_INFO*)info, &stbuff,
&nwpath);
} else {
get_file_attrib((NW_FILE_INFO*)info, &stbuff,
&nwpath);
}
return(searchsequence);
} else return(-0xff); /* not found */
} else return(completition); /* wrong path */
}
int nw_alloc_dir_handle( int dir_handle, /* Suche ab Pfad dirhandle */
uint8 *data, /* zusaetzl. Pfad */
int len, /* L„nge DATA */
int driveletter, /* A .. Z normal */
int is_temphandle, /* temporaeres Handle 1 */
/* spez. temp Handle 2 */
int task) /* Prozess Task */
{
NW_PATH nwpath;
int inode=get_kpl_path(&nwpath, dir_handle, data, len, 1);
if (inode > -1)
inode = insert_new_dir(&nwpath, inode, driveletter, is_temphandle, task);
DPRINTF(("Allocate %shandle:%s, Handle=%d, drive=%d, result=0x%x\n",
(is_temphandle) ? "Temp" : "Perm", get_nwpath_name(&nwpath),
dir_handle, driveletter, inode));
return(inode);
}
int nw_open_dir_handle( int dir_handle,
uint8 *data, /* extra path */
int len, /* len of DATA */
int *volume, /* Volume */
int *dir_id,
int *searchsequence)
/*
* Routine liefert Handle aehnlich Filehandle.
* Handle kann in der Suchroutine verwendet werden
* RETURN=Fehlercode ( <0 ) od. ACCES Rights
*/
{
NW_PATH nwpath;
int completition = get_kpl_path(&nwpath, dir_handle, data, len, 1);
DPRINTF(("NW_OPEN_DIR: completition = 0x%x; nwpath= %s\n",
(int)completition,
get_nwpath_name(&nwpath) ));
if (completition > -1) {
completition = new_dir_handle((ino_t)completition, &nwpath);
if (completition > -1) {
DIR_HANDLE *fh = &(dir_handles[completition-1]);
*volume = fh->volume;
*dir_id = completition;
*searchsequence = MAX_U16;
completition = 0xff; /* Alle Rechte */
}
DPRINTF(("NW_OPEN_DIR_2: completition = 0x%x\n",
(int)completition));
}
return(completition);
}
int nw_free_dir_handle(int dir_handle)
{
if (dir_handle && --dir_handle < (int)used_dirs) {
NW_DIR *d=&(dirs[dir_handle]);
if (!d->inode) return(-0x9b); /* Falscher Handle */
else {
d->inode = 0;
xfree(d->path);
}
return(0);
} else return(-0x9b); /* wrong handle */
}
int nw_set_dir_handle(int targetdir, int dir_handle,
uint8 *data, int len, int task)
/* targetdirs gets path of dirhandle + data */
{
NW_PATH nwpath;
int inode = get_kpl_path(&nwpath, dir_handle, data, len, 1);
if (inode > -1){
if (targetdir > 0 && --targetdir < used_dirs
&& dirs[targetdir].is_temp != 2) { /* not a spez. temphandle */
DPRINTF(("Change dhandle:%d -> %s:\n", targetdir+1, get_nwpath_name(&nwpath)));
return(change_dir_entry(&dirs[targetdir], nwpath.volume, nwpath.path, inode, -1, -1, 0, task));
/* here the existing handle is only modified */
} else return(-0x9b); /* BAD DIR Handle */
}
return(inode); /* invalid PATH */
}
int nw_get_directory_path(int dir_handle, uint8 *name)
{
int result = -0x9b;
name[0] = '\0';
if (dir_handle > 0 && --dir_handle < (int)used_dirs) {
int volume = dirs[dir_handle].volume;
if (volume < used_vols){
result=sprintf((char*)name, "%s:%s", vols[volume].sysname, dirs[dir_handle].path);
if (name[result-1] == '/') name[--result] = '\0';
} else result = -0x98;
}
DPRINTF(("nw_get_directory_path:%s: Handle=%d, result=0x%x\n", name, dir_handle+1, result));
return(result);
}
int nw_get_vol_number(int dir_handle)
/* Get Volume Nummmer with Handle */
{
int result = -0x9b; /* Falsches Handle */
if (dir_handle > 0 && --dir_handle < (int)used_dirs) {
result = dirs[dir_handle].volume;
if (result >= used_vols) result = -0x98; /* Falsches Volume */
}
DPRINTF(("nw_get_vol_number:0x%x: von Handle=%d\n", result, dir_handle+1));
return(result);
}
int nw_get_volume_number(uint8 *volname, int namelen)
/* Get Volume Number with name */
/* returns Volume Nummer or if error < 0 */
{
int result = -0x98; /* Volume not exist */
uint8 vname[255];
int j = used_vols;
strmaxcpy((char*)vname, (char*)volname, namelen);
upstr(vname);
while (j--) {
if (!strcmp(vols[j].sysname, vname)) {
result = j;
break;
}
}
DPRINTF(("GET_VOLUME_NUMBER of:%s: result = 0x%x\n", vname, result));
return(result);
}
int nw_get_volume_name(int volnr, uint8 *volname)
/* returns < 0 if error, else len of volname */
{
int result = -0x98; /* Volume not exist */;
if (volnr < used_vols) {
strcpy(volname, vols[volnr].sysname);
result = strlen(volname);
} else volname[0] = '\0';
DPRINTF(("GET_VOLUME_NAME von:%d = %s: ,result=0x%x\n", volnr, volname, result));
return(result);
}
int nw_get_eff_dir_rights(int dir_handle, uint8 *data, int len)
{
char unname[256];
struct stat stbuff;
NW_PATH nwpath;
int completition = get_kpl_path(&nwpath, dir_handle, data, len, 1);
if (completition < 0) return(completition);
strcpy(unname, build_unix_name(&nwpath, 0));
if (stat(unname, &stbuff) || (stbuff.st_mode & S_IFMT) != S_IFDIR) {
completition = -0x9c;
} else completition=0xff; /* alle Rechte */
return(completition);
}
int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit)
{
if (fhandle > 0 && (--fhandle < anz_fhandles) ) {
FILE_HANDLE *fh=&(file_handles[fhandle]);
if (fh->fd > -1) {
fh->tmodi = nw_2_un_time(datum, zeit);
return(0);
}
}
return(-0x88); /* wrong filehandle */
}
static int s_nw_scan_dir_info(int dir_handle,
uint8 *data, int len, uint8 *subnr,
uint8 *subname, uint8 *subdatetime,
uint8 *owner, uint8 *wild)
{
int volume;
int searchsequenz;
int dir_id;
int rights = nw_open_dir_handle(dir_handle, data, len,
&volume, &dir_id, &searchsequenz);
DPRINTF(("SCAN_DIR: rights = 0x%x, subnr = %d\n",
(int)rights, (int)GET_BE16(subnr)));
if (rights > -1) {
DIR_HANDLE *dh = &(dir_handles[dir_id-1]);
struct stat stbuff;
int searchsequence = MAX_U16;
uint16 dirsequenz = GET_BE16(subnr);
uint16 aktsequenz = 0;
uint8 dirname[256];
if (!dirsequenz) dirsequenz++;
strcpy(dirname, wild);
while ( get_dh_entry( dh,
dirname,
&searchsequence,
0x10,
&stbuff) ) {
DPRINTF(("SCAN_DIR: von %s, found %s:\n", dh->unixname, dirname));
if (++aktsequenz == dirsequenz) { /* actual found */
U16_TO_BE16(aktsequenz, subnr);
strncpy(subname, dirname, 16);
U32_TO_BE32(1L, owner); /* erstmal */
un_date_2_nw(stbuff.st_mtime, subdatetime);
un_time_2_nw(stbuff.st_mtime, subdatetime+2);
return(0xff);
}
strcpy(dirname, wild);
} /* while */
/* return(-0x9c); NO MORE INFO */
return(-0xff);
}
return(rights);
}
int nw_scan_dir_info(int dir_handle, uint8 *data, int len, uint8 *subnr,
uint8 *subname, uint8 *subdatetime, uint8 *owner)
{
int k = len;
char *p = data+len;
uint8 dirname[256];
while (k--) {
uint8 c = *--p;
if (c == '/' || c == '\\' || c == ':') {
p++;
k++;
break;
}
}
if (len /* && k < len */) {
strmaxcpy(dirname, p, len-k);
len = k;
} else strcpy(dirname, "*");
return(s_nw_scan_dir_info(dir_handle, data, len, subnr,
subname, subdatetime, owner, dirname));
}
int nw_get_fs_usage(char *volname, struct fs_usage *fsu)
/* returns 0 if OK, else errocode < 0 */
{
int volnr = nw_get_volume_number(volname, strlen(volname));
return((volnr>-1 && !get_fs_usage(vols[volnr].unixname, fsu)) ? 0 : -1);
}
/* NAMESPACE routines */
int nw_generate_dir_path(uint8 *nwpathstruct,
uint8 *ns_dir_base, uint8 *dos_dir_base)
/* returns Volume Number >=0 or errcode < 0 if error */
{
return(-0xfb); /* TODO: complete call */
}
/* 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;
QUEUE_JOB *queue_jobs[MAX_JOBS];
static QUEUE_JOB *give_new_queue_job(void)
{
int k=-1;
while (++k < anz_jobs) {
QUEUE_JOB *p=queue_jobs[k];
if (!p->record_in_use[0] && !p->record_in_use[1]) /* free slot */
return(p);
}
if (anz_jobs < MAX_JOBS) {
QUEUE_JOB **pp=&(queue_jobs[anz_jobs++]);
*pp = (QUEUE_JOB *) xmalloc(sizeof(QUEUE_JOB));
memset(*pp, 0, sizeof(QUEUE_JOB));
(*pp)->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) {
QUEUE_JOB **pp=&(queue_jobs[q_id-1]);
uint32 fhandle = (uint32) GET_BE16((*pp)->job_file_handle);
if (fhandle > 0) nw_close_datei(fhandle);
if (q_id == anz_jobs) {
xfree(*pp);
--anz_jobs;
} else {
memset(*pp, 0, sizeof(QUEUE_JOB));
(*pp)->job_id[0] = q_id;
}
}
}
int nw_creat_queue(int connection, uint8 *queue_id, uint8 *queue_job,
uint8 *dirname, int dir_nam_len)
{
QUEUE_JOB job_buff;
QUEUE_JOB *jo = give_new_queue_job();
uint32 q_id = GET_BE32(queue_id);
NW_FILE_INFO fnfo;
int result = -0xff;
DPRINTF(("NW_CREAT_Q:dlen=%d, dirname=%s\n", dir_nam_len, dirname));
if (NULL != jo) {
struct tm *s_tm;
time_t timer;
int jo_id = (int) jo->job_id[0];
memcpy(jo, queue_job, sizeof(QUEUE_JOB));
jo->job_id[0] = (uint8) jo_id;
U16_TO_BE16(0xffff, jo->record_in_use);
U32_TO_BE32(0x0, jo->record_previous);
U32_TO_BE32(0x0, jo->record_next);
memset(jo->client_connection, 0, 4);
jo->client_connection[0] = (uint8)connection;
memset(jo->client_task, 0, 4);
jo->client_task[0] = (uint8)0xfe; /* ?? */
U32_TO_BE32(1, jo->client_id); /* SU */
time(&timer);
s_tm = localtime(&timer);
jo->job_entry_time[0] = (uint8) s_tm->tm_year;
jo->job_entry_time[1] = (uint8) s_tm->tm_mon+1;
jo->job_entry_time[2] = (uint8) s_tm->tm_mday;
jo->job_entry_time[3] = (uint8) s_tm->tm_hour;
jo->job_entry_time[4] = (uint8) s_tm->tm_min;
jo->job_entry_time[5] = (uint8) s_tm->tm_sec;
jo->job_typ[0] = 0x0; /* 0xd0;*/
jo->job_typ[1] = 0x0;
jo->job_position[0] = 0x1;
jo->job_position[1] = 0x0;
jo->job_control_flags[0] |= 0x20;
jo->job_control_flags[1] = 0x0;
jo->job_file_name[0]
= sprintf(jo->job_file_name+1, "%07X%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, jo->job_file_name+1,
(int)jo->job_file_name[0],
&fnfo, 0x6, 0x6, 1);
DPRINTF(("creat print queue bez=`%s` handle=%d\n", jo->job_bez, result));
if (result > -1) {
U16_TO_BE16((uint16)result, jo->job_file_handle);
U16_TO_BE16(0, jo->job_file_handle+2);
result = 0;
}
U32_TO_BE32(0, jo->server_station);
U32_TO_BE32(0, jo->server_task);
U32_TO_BE32(0, jo->server_id);
if (!result) memcpy(queue_job, jo, sizeof(QUEUE_JOB));
else 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 = 0;
int jo_id = (int) *job_id;
DPRINTF(("nw_close_file_queue JOB=%d\n", jo_id));
if (jo_id > 0 && jo_id <= anz_jobs){
QUEUE_JOB *jo=queue_jobs[jo_id-1];
int fhandle = (int) GET_BE16(jo->job_file_handle);
if (fhandle > 0 && fhandle <= anz_fhandles) {
FILE_HANDLE *fh=&(file_handles[fhandle-1]);
char unixname[300];
char printcommand[256];
FILE *f=NULL;
strmaxcpy(unixname, fh->name, sizeof(unixname)-1);
strmaxcpy(printcommand, prc, prc_len);
nw_close_datei(fhandle);
U16_TO_BE16((uint16)0, jo->job_file_handle);
U16_TO_BE16(0xff00, jo->record_in_use);
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)) is_ok=0;
}
pclose(fout);
} else
DPRINTF(("Cannot open pipe `%s`\n", "lpr"));
fclose(f);
if (is_ok) unlink(unixname);
} else DPRINTF(("Cannot open queue-file `%s`\n", unixname));
} else
DPRINTF(("nw_close_file_queue fhandle=%d\n", fhandle));
free_queue_job(jo_id);
}
return(result);
}