2011-11-13 00:38:58 +01:00
|
|
|
/* nwfile.c 31-Dec-96 */
|
2011-11-13 00:38:56 +01:00
|
|
|
/* (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 <utime.h>
|
|
|
|
|
|
|
|
#include <sys/errno.h>
|
|
|
|
|
|
|
|
#include "nwvolume.h"
|
|
|
|
#include "nwfile.h"
|
|
|
|
#include "connect.h"
|
2011-11-13 00:38:57 +01:00
|
|
|
#include "nwconn.h"
|
|
|
|
#if USE_MMAP
|
|
|
|
# include <sys/mman.h>
|
2011-11-13 00:38:57 +01:00
|
|
|
static got_sig_bus=0;
|
|
|
|
void sig_bus_mmap(int rsig)
|
|
|
|
{
|
|
|
|
got_sig_bus++;
|
|
|
|
XDPRINTF((2,0, "Got sig_bus"));
|
|
|
|
signal(SIGBUS, sig_bus_mmap);
|
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
#endif
|
2011-11-13 00:38:56 +01:00
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
static FILE_HANDLE file_handles[MAX_FILE_HANDLES_CONN];
|
2011-11-13 00:38:57 +01:00
|
|
|
#define HOFFS 0
|
2011-11-13 00:38:56 +01:00
|
|
|
static int anz_fhandles=0;
|
|
|
|
|
2011-11-13 00:38:57 +01:00
|
|
|
static int new_file_handle(uint8 *unixname, int task)
|
2011-11-13 00:38:56 +01:00
|
|
|
{
|
2011-11-13 00:38:57 +01:00
|
|
|
int rethandle = HOFFS -1;
|
2011-11-13 00:38:56 +01:00
|
|
|
FILE_HANDLE *fh=NULL;
|
|
|
|
while (++rethandle < anz_fhandles) {
|
2011-11-13 00:38:58 +01:00
|
|
|
fh=&(file_handles[rethandle]);
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fh->fd == -1 && !(fh->fh_flags & FH_DO_NOT_REUSE)) { /* empty slot */
|
2011-11-13 00:38:56 +01:00
|
|
|
rethandle++;
|
|
|
|
break;
|
|
|
|
} else fh=NULL;
|
|
|
|
}
|
|
|
|
if (fh == NULL) {
|
2011-11-13 00:38:56 +01:00
|
|
|
if (anz_fhandles < MAX_FILE_HANDLES_CONN) {
|
2011-11-13 00:38:56 +01:00
|
|
|
fh=&(file_handles[anz_fhandles]);
|
|
|
|
rethandle = ++anz_fhandles;
|
2011-11-13 00:38:57 +01:00
|
|
|
} else {
|
|
|
|
XDPRINTF((1, 0, "No more free file handles"));
|
|
|
|
return(0); /* no free handle anymore */
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
/* init handle */
|
2011-11-13 00:38:57 +01:00
|
|
|
fh->task = task;
|
2011-11-13 00:38:56 +01:00
|
|
|
fh->fd = -2;
|
|
|
|
fh->offd = 0L;
|
|
|
|
fh->tmodi = 0L;
|
|
|
|
strcpy((char*)fh->fname, (char*)unixname);
|
2011-11-13 00:38:57 +01:00
|
|
|
fh->fh_flags = 0;
|
2011-11-13 00:38:56 +01:00
|
|
|
fh->f = NULL;
|
|
|
|
XDPRINTF((5, 0, "new_file_handle=%d, anz_fhandles=%d, fn=%s",
|
|
|
|
rethandle, anz_fhandles, unixname));
|
|
|
|
return(rethandle);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int free_file_handle(int fhandle)
|
|
|
|
{
|
|
|
|
int result=-0x88;
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fhandle > HOFFS && (fhandle <= anz_fhandles)) {
|
2011-11-13 00:38:56 +01:00
|
|
|
FILE_HANDLE *fh=&(file_handles[fhandle-1]);
|
|
|
|
if (fh->fd > -1) {
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fh->fh_flags & FH_IS_PIPE_COMMAND) {
|
2011-11-13 00:38:56 +01:00
|
|
|
if (fh->f) ext_pclose(fh->f);
|
2011-11-13 00:38:56 +01:00
|
|
|
fh->f = NULL;
|
2011-11-13 00:38:57 +01:00
|
|
|
} else {
|
|
|
|
#if USE_MMAP
|
|
|
|
if (fh->p_mmap) {
|
|
|
|
munmap(fh->p_mmap, fh->size_mmap);
|
|
|
|
fh->p_mmap = NULL;
|
|
|
|
fh->size_mmap = 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
close(fh->fd);
|
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fh->tmodi > 0L && !(FH_IS_PIPE_COMMAND & fh->fh_flags)
|
|
|
|
&& !(FH_IS_READONLY & fh->fh_flags) ) {
|
2011-11-13 00:38:56 +01:00
|
|
|
/* now set date and time */
|
|
|
|
struct utimbuf ut;
|
|
|
|
ut.actime = ut.modtime = fh->tmodi;
|
|
|
|
utime(fh->fname, &ut);
|
|
|
|
fh->tmodi = 0L;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fh->fd = -1;
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fhandle == anz_fhandles && !(fh->fh_flags & FH_DO_NOT_REUSE)) {
|
2011-11-13 00:38:56 +01:00
|
|
|
/* was last */
|
|
|
|
anz_fhandles--;
|
2011-11-13 00:38:57 +01:00
|
|
|
while (anz_fhandles > HOFFS && file_handles[anz_fhandles-1].fd == -1
|
2011-11-13 00:38:57 +01:00
|
|
|
&& !(file_handles[anz_fhandles-1].fh_flags & FH_DO_NOT_REUSE) )
|
2011-11-13 00:38:56 +01:00
|
|
|
anz_fhandles--;
|
|
|
|
}
|
|
|
|
result=0;
|
|
|
|
}
|
|
|
|
XDPRINTF((5, 0, "free_file_handle=%d, anz_fhandles=%d, result=%d",
|
|
|
|
fhandle, anz_fhandles, result));
|
|
|
|
return(result); /* wrong filehandle */
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:57 +01:00
|
|
|
void init_file_module(int task)
|
|
|
|
/*
|
|
|
|
* if task == -1 all handles will be free'd
|
|
|
|
* else only handles of the task will be free'd
|
|
|
|
*/
|
2011-11-13 00:38:56 +01:00
|
|
|
{
|
2011-11-13 00:38:57 +01:00
|
|
|
int k = HOFFS;
|
|
|
|
if (task < 0) {
|
|
|
|
while (k++ < anz_fhandles)
|
|
|
|
free_file_handle(k);
|
|
|
|
anz_fhandles = HOFFS;
|
|
|
|
} else {
|
|
|
|
/* I hope next is ok, added 20-Oct-96 ( 0.98.pl5 ) */
|
|
|
|
while (k++ < anz_fhandles) {
|
|
|
|
FILE_HANDLE *fh=&(file_handles[k-1]);
|
|
|
|
if (fh->task == task) {
|
|
|
|
free_file_handle(k);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:57 +01:00
|
|
|
static int xsetegid(gid_t gid)
|
|
|
|
{
|
|
|
|
int result = -1;
|
|
|
|
if (!seteuid(0)) {
|
|
|
|
if (setegid(gid)) {
|
|
|
|
XDPRINTF((2, 0, "Cannot change eff Group ID to %d", gid));
|
|
|
|
} else
|
|
|
|
result=0;
|
|
|
|
if (seteuid(act_uid)) {
|
|
|
|
reset_guid();
|
|
|
|
result = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
|
2011-11-13 00:38:57 +01:00
|
|
|
int attrib, int access, int creatmode, int task)
|
2011-11-13 00:38:56 +01:00
|
|
|
/*
|
2011-11-13 00:38:57 +01:00
|
|
|
* creatmode: 0 = open
|
|
|
|
* | 1 = creat (ever)
|
|
|
|
* | 2 = creatnew ( creat if not exist )
|
|
|
|
* & 4 == save handle (creat)
|
|
|
|
* & 8 == ignore rights (create ever)
|
2011-11-13 00:38:56 +01:00
|
|
|
* attrib ??
|
2011-11-13 00:38:57 +01:00
|
|
|
*
|
|
|
|
* access: 0x1=read,
|
|
|
|
* 0x2=write,
|
2011-11-13 00:38:57 +01:00
|
|
|
* 0x4=deny read, -> F_WRLCK, no other process can make
|
|
|
|
* a read or write lock
|
|
|
|
* can only be used if file is open for writing
|
|
|
|
* 0x8=deny write -> F_RDLCK, no other process can make a writelock
|
|
|
|
* can only be used if file is open for reading
|
2011-11-13 00:38:57 +01:00
|
|
|
* 0x10=SH_COMPAT
|
2011-11-13 00:38:57 +01:00
|
|
|
*
|
|
|
|
* 0x09 (O_RDONLY | O_DENYWRITE);
|
|
|
|
* 0x05 (O_RDONLY | O_DENYREAD);
|
|
|
|
*
|
|
|
|
* 0x0b (O_RDWR | O_DENYWRITE);
|
|
|
|
* 0x07 (O_RDWR | O_DENYREAD);
|
|
|
|
*
|
|
|
|
* 0x05 (O_RDONLY | O_DENYREAD | O_DENYWRITE);
|
|
|
|
* 0x07 (O_RDWR | O_DENYREAD | O_DENYWRITE);
|
2011-11-13 00:38:56 +01:00
|
|
|
*
|
2011-11-13 00:38:56 +01:00
|
|
|
*/
|
|
|
|
{
|
2011-11-13 00:38:57 +01:00
|
|
|
int fhandle = new_file_handle(unixname, task);
|
|
|
|
int dowrite = ((access & 2) || creatmode) ? 1 : 0;
|
|
|
|
if (fhandle > HOFFS){
|
2011-11-13 00:38:56 +01:00
|
|
|
FILE_HANDLE *fh=&(file_handles[fhandle-1]);
|
2011-11-13 00:38:57 +01:00
|
|
|
int completition = 0; /* first ok */
|
2011-11-13 00:38:56 +01:00
|
|
|
int voloptions = get_volume_options(volume, 1);
|
2011-11-13 00:38:57 +01:00
|
|
|
int acc = (!stat(fh->fname, stbuff))
|
|
|
|
? get_real_access(stbuff) : -1;
|
|
|
|
|
|
|
|
int did_grpchange = 0;
|
2011-11-13 00:38:56 +01:00
|
|
|
if (dowrite && (voloptions & VOL_OPTION_READONLY)) {
|
|
|
|
completition = (creatmode) ? -0x84 : -0x94;
|
2011-11-13 00:38:57 +01:00
|
|
|
} else if (acc > -1) {
|
|
|
|
/* do exist */
|
|
|
|
if (!S_ISDIR(stbuff->st_mode)) {
|
|
|
|
if (!(voloptions & VOL_OPTION_IS_PIPE)
|
|
|
|
|| S_ISFIFO(stbuff->st_mode) ) {
|
|
|
|
/* We look for normal file accesses */
|
|
|
|
if (creatmode & 2) {
|
|
|
|
XDPRINTF((5,0,"CREAT File exist!! :%s:", fh->fname));
|
|
|
|
completition = -0x85; /* No Priv */
|
2011-11-13 00:38:57 +01:00
|
|
|
} else if (dowrite && !(acc & W_OK) && !(creatmode & 0x8) ) {
|
|
|
|
if (!S_ISFIFO(stbuff->st_mode)) {
|
|
|
|
if (entry8_flags&2 && (acc & R_OK)) {
|
|
|
|
/* we use strange compatibility modus */
|
|
|
|
dowrite=0;
|
|
|
|
XDPRINTF((1, 0, "Uses strange open comp. mode for file `%s`",
|
|
|
|
fh->fname));
|
|
|
|
} else
|
|
|
|
completition = (creatmode) ? -0x84 : -0x94;
|
|
|
|
} else
|
|
|
|
completition = (creatmode) ? -0x84 : -0x94;
|
|
|
|
} else if (!(acc & R_OK) && !(creatmode & 0x8) )
|
2011-11-13 00:38:57 +01:00
|
|
|
completition = -0x93;
|
|
|
|
} else if (acc & X_OK) {
|
|
|
|
/* special Handling for PIPE commands */
|
|
|
|
if (!(acc & W_OK)) {
|
|
|
|
if (acc & 0x10) /* access owner */
|
2011-11-13 00:38:57 +01:00
|
|
|
stbuff->st_mode |= S_IWUSR;
|
2011-11-13 00:38:57 +01:00
|
|
|
else if (acc & 0x20) /* access group */
|
2011-11-13 00:38:57 +01:00
|
|
|
stbuff->st_mode |= S_IWGRP;
|
2011-11-13 00:38:57 +01:00
|
|
|
else
|
2011-11-13 00:38:57 +01:00
|
|
|
stbuff->st_mode |= S_IWOTH;
|
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
} else {
|
|
|
|
XDPRINTF((4, 0, "No PIPE command rights st_mode=0x%x uid=%d, gid=%d",
|
2011-11-13 00:38:57 +01:00
|
|
|
stbuff->st_uid, stbuff->st_gid));
|
2011-11-13 00:38:57 +01:00
|
|
|
completition = -0xff;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
completition= -0xff;
|
|
|
|
} else if ( (voloptions & VOL_OPTION_IS_PIPE) || !creatmode) {
|
|
|
|
/* must exist, but don't */
|
|
|
|
completition=-0xff;
|
|
|
|
} else {
|
|
|
|
/* File do not exist yet, but must be created */
|
|
|
|
char *p=strrchr(unixname, '/');
|
|
|
|
/* first we say: not OK */
|
|
|
|
completition = -0xff;
|
|
|
|
if (p) {
|
|
|
|
*p='\0';
|
|
|
|
acc = (!stat(unixname, stbuff))
|
|
|
|
? get_real_access(stbuff) : -1;
|
|
|
|
if (acc > 0) {
|
|
|
|
if (acc & W_OK) /* we need write access for this directory */
|
|
|
|
completition=0;
|
|
|
|
else
|
|
|
|
completition=-0x84; /* no creat rights */
|
|
|
|
}
|
|
|
|
*p='/';
|
|
|
|
}
|
|
|
|
if (completition && (creatmode & 8)) {
|
|
|
|
acc=0;
|
|
|
|
completition=0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( (!completition) && (acc & 0x20) && (stbuff->st_gid != act_gid)) {
|
|
|
|
/* here we try a change egid */
|
|
|
|
if (xsetegid(stbuff->st_gid)) {
|
|
|
|
completition = -0x85; /* no privillegs */
|
|
|
|
} else {
|
|
|
|
did_grpchange++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!completition) {
|
|
|
|
if (voloptions & VOL_OPTION_IS_PIPE) {
|
|
|
|
/* <========= this is a PIPE Volume ====================> */
|
|
|
|
fh->fh_flags |= FH_IS_PIPE;
|
|
|
|
if (S_ISFIFO(stbuff->st_mode)){
|
|
|
|
fh->fd = open(fh->fname,
|
|
|
|
O_NONBLOCK | dowrite ? O_RDWR : O_RDONLY);
|
|
|
|
} else {
|
|
|
|
fh->fh_flags |= FH_IS_PIPE_COMMAND;
|
|
|
|
fh->fd=-3;
|
2011-11-13 00:38:57 +01:00
|
|
|
}
|
|
|
|
if (fh->fd != -1) {
|
2011-11-13 00:38:57 +01:00
|
|
|
if (!dowrite)
|
|
|
|
stbuff->st_size = 0x7fff0000 | (rand() & 0xffff);
|
2011-11-13 00:38:57 +01:00
|
|
|
(void)time(&(stbuff->st_mtime));
|
2011-11-13 00:38:57 +01:00
|
|
|
stbuff->st_atime = stbuff->st_mtime;
|
2011-11-13 00:38:57 +01:00
|
|
|
if (creatmode & 4)
|
|
|
|
fh->fh_flags |= FH_DO_NOT_REUSE;
|
|
|
|
if (did_grpchange)
|
|
|
|
xsetegid(act_gid);
|
2011-11-13 00:38:58 +01:00
|
|
|
goto file_creat_open_ret;
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
} else {
|
|
|
|
/* <========= this is NOT a PIPE Volume ====================> */
|
|
|
|
if (creatmode) { /* creat File */
|
|
|
|
if (creatmode & 0x2) { /* creatnew */
|
2011-11-13 00:38:56 +01:00
|
|
|
XDPRINTF((5,0,"CREAT FILE:%s: Handle=%d", fh->fname, fhandle));
|
|
|
|
fh->fd = creat(fh->fname, 0777);
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fh->fd < 0)
|
|
|
|
completition = -0x84; /* no create Rights */
|
|
|
|
else
|
|
|
|
chmod(fh->fname, act_umode_file);
|
|
|
|
} else {
|
|
|
|
XDPRINTF((5,0,"CREAT FILE, ever with attrib:0x%x, access:0x%x, fh->fname:%s: handle:%d",
|
|
|
|
attrib, access, fh->fname, fhandle));
|
|
|
|
fh->fd = open(fh->fname, O_CREAT|O_TRUNC|O_RDWR, 0777);
|
|
|
|
if (fh->fd < 0) {
|
|
|
|
if (creatmode & 0x8) {
|
|
|
|
if ( (!seteuid(0)) && (-1 < (fh->fd =
|
|
|
|
open(fh->fname, O_CREAT|O_TRUNC|O_RDWR, 0777)))) {
|
|
|
|
chown(fh->fname, act_uid, act_gid);
|
|
|
|
}
|
|
|
|
did_grpchange=0;
|
|
|
|
reset_guid();
|
|
|
|
}
|
|
|
|
if (fh->fd < 0)
|
|
|
|
completition = -0x85; /* no delete /create Rights */
|
|
|
|
} else
|
|
|
|
chmod(fh->fname, act_umode_file);
|
|
|
|
}
|
|
|
|
if (fh->fd > -1) {
|
|
|
|
close(fh->fd);
|
|
|
|
fh->fd = open(fh->fname, O_RDWR);
|
|
|
|
fh->offd = 0L;
|
|
|
|
stat(fh->fname, stbuff);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
} else {
|
2011-11-13 00:38:57 +01:00
|
|
|
/* ======== 'normal' open of file ================ */
|
2011-11-13 00:38:57 +01:00
|
|
|
int acm = (dowrite) ? (int) O_RDWR : (int)O_RDONLY;
|
|
|
|
if (S_ISFIFO(stbuff->st_mode)){
|
|
|
|
acm |= O_NONBLOCK;
|
|
|
|
fh->fh_flags |= FH_IS_PIPE;
|
|
|
|
if (!dowrite) stbuff->st_size = 0x7fffffff;
|
|
|
|
(void)time(&(stbuff->st_mtime));
|
2011-11-13 00:38:57 +01:00
|
|
|
stbuff->st_atime = stbuff->st_mtime;
|
2011-11-13 00:38:57 +01:00
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
fh->fd = open(fh->fname, acm);
|
2011-11-13 00:38:57 +01:00
|
|
|
XDPRINTF((5,0, "OPEN FILE:fd=%d, attrib:0x%x, access:0x%x, fh->fname:%s:fhandle=%d",
|
|
|
|
fh->fd, attrib, access, fh->fname, fhandle));
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fh->fd < 0)
|
|
|
|
completition = dowrite ? -0x94 : -0x93;
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
|
|
|
|
if (fh->fd > -1) {
|
|
|
|
if (!(fh->fh_flags & FH_IS_PIPE)) {
|
|
|
|
/* Not a PIPE */
|
|
|
|
if ((access & 0x4) || (access & 0x8)) {
|
2011-11-13 00:38:57 +01:00
|
|
|
/* we use file sharing */
|
2011-11-13 00:38:57 +01:00
|
|
|
struct flock flockd;
|
2011-11-13 00:38:57 +01:00
|
|
|
int result = (access & 0x4) ? 1 : 0; /* here for writelock */
|
|
|
|
#if 0
|
|
|
|
if (result != dowrite) {
|
|
|
|
XDPRINTF((1,0, "OpenFile:Share(access)=0x%x clashes openmode=%s, file=%s",
|
|
|
|
access, (dowrite) ? "W" : "R", fh->fname));
|
|
|
|
result = dowrite;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
if ((!dowrite) && result) {
|
|
|
|
XDPRINTF((1,0, "OpenFile:Share(access)=0x%x clashes R-open file=%s",
|
|
|
|
access, fh->fname));
|
|
|
|
result = dowrite;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
flockd.l_type = (result) ? F_WRLCK : F_RDLCK;
|
2011-11-13 00:38:57 +01:00
|
|
|
flockd.l_whence = SEEK_SET;
|
|
|
|
flockd.l_start = 0;
|
|
|
|
flockd.l_len = 0;
|
|
|
|
result = fcntl(fh->fd, F_SETLK, &flockd);
|
2011-11-13 00:38:58 +01:00
|
|
|
XDPRINTF(((result==-1)?2:5, 0, "open shared lock:result=%d,fn='%s'",
|
|
|
|
result, fh->fname));
|
2011-11-13 00:38:57 +01:00
|
|
|
if (result == -1) {
|
|
|
|
close(fh->fd);
|
|
|
|
fh->fd = -1;
|
|
|
|
completition=-0xfe;
|
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
}
|
|
|
|
#if USE_MMAP
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fh->fd > -1 && !dowrite) {
|
|
|
|
fh->size_mmap = fh->offd=lseek(fh->fd, 0L, SEEK_END);
|
|
|
|
if (fh->size_mmap > 0) {
|
|
|
|
fh->p_mmap = mmap(NULL,
|
|
|
|
fh->size_mmap,
|
|
|
|
PROT_READ,
|
|
|
|
MAP_SHARED,
|
|
|
|
fh->fd, 0);
|
|
|
|
if (fh->p_mmap == (uint8*) -1) {
|
|
|
|
fh->p_mmap = NULL;
|
|
|
|
fh->size_mmap=0;
|
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2011-11-13 00:38:57 +01:00
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fh->fd > -1) {
|
2011-11-13 00:38:58 +01:00
|
|
|
if (!dowrite)
|
|
|
|
fh->fh_flags |= FH_OPENED_RO;
|
|
|
|
if (voloptions & VOL_OPTION_READONLY)
|
|
|
|
fh->fh_flags |= FH_IS_READONLY;
|
|
|
|
if (creatmode & 4)
|
|
|
|
fh->fh_flags |= FH_DO_NOT_REUSE;
|
2011-11-13 00:38:57 +01:00
|
|
|
if (did_grpchange)
|
|
|
|
xsetegid(act_gid);
|
2011-11-13 00:38:58 +01:00
|
|
|
goto file_creat_open_ret;
|
2011-11-13 00:38:57 +01:00
|
|
|
}
|
2011-11-13 00:38:58 +01:00
|
|
|
} /* else (note pipecommand) */
|
2011-11-13 00:38:57 +01:00
|
|
|
} /* if !completition */
|
|
|
|
if (did_grpchange)
|
|
|
|
xsetegid(act_gid);
|
|
|
|
XDPRINTF((5,0,"OPEN FILE not OK (-0x%x), fh->name:%s: fhandle=%d",
|
|
|
|
-completition, fh->fname, fhandle));
|
2011-11-13 00:38:56 +01:00
|
|
|
free_file_handle(fhandle);
|
2011-11-13 00:38:58 +01:00
|
|
|
fhandle=completition;
|
|
|
|
} else fhandle=-0x81; /* no more File Handles */
|
|
|
|
|
|
|
|
file_creat_open_ret:
|
|
|
|
MDEBUG(D_FH_OPEN, {
|
|
|
|
char fname[200];
|
|
|
|
if (!fd_2_fname(fhandle, fname, sizeof(fname))){
|
|
|
|
dprintf("Open/creat fd=%d, fn=`%s`", fhandle, fname);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
return(fhandle);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit)
|
|
|
|
{
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fhandle > HOFFS && (--fhandle < anz_fhandles) ) {
|
2011-11-13 00:38:56 +01:00
|
|
|
FILE_HANDLE *fh=&(file_handles[fhandle]);
|
|
|
|
if (fh->fd > -1) {
|
2011-11-13 00:38:57 +01:00
|
|
|
if (!(fh->fh_flags & FH_IS_READONLY)) {
|
2011-11-13 00:38:56 +01:00
|
|
|
fh->tmodi = nw_2_un_time(datum, zeit);
|
|
|
|
return(0);
|
|
|
|
} else return(-0x8c);
|
2011-11-13 00:38:57 +01:00
|
|
|
} else if (fh->fd == -3) return(0);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
return(-0x88); /* wrong filehandle */
|
|
|
|
}
|
|
|
|
|
|
|
|
int nw_close_datei(int fhandle, int reset_reuse)
|
|
|
|
{
|
2011-11-13 00:38:56 +01:00
|
|
|
XDPRINTF((5, 0, "nw_close_datei handle=%d, anz_fhandles",
|
|
|
|
fhandle, anz_fhandles));
|
2011-11-13 00:38:58 +01:00
|
|
|
|
|
|
|
MDEBUG(D_FH_OPEN, {
|
|
|
|
char fname[200];
|
|
|
|
int r=fd_2_fname(fhandle, fname, sizeof(fname));
|
|
|
|
dprintf("nw_close_datei: fd=%d, fn=`%s`,r=%d", fhandle, fname, r);
|
|
|
|
})
|
|
|
|
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fhandle > HOFFS && (fhandle <= anz_fhandles)) {
|
2011-11-13 00:38:56 +01:00
|
|
|
FILE_HANDLE *fh=&(file_handles[fhandle-1]);
|
2011-11-13 00:38:57 +01:00
|
|
|
if (reset_reuse) fh->fh_flags &= (~FH_DO_NOT_REUSE);
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fh->fd > -1 || (fh->fd == -3 && fh->fh_flags & FH_IS_PIPE_COMMAND)) {
|
2011-11-13 00:38:56 +01:00
|
|
|
int result = 0;
|
|
|
|
int result2;
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fh->fh_flags & FH_IS_PIPE_COMMAND) {
|
2011-11-13 00:38:56 +01:00
|
|
|
if (fh->f) {
|
2011-11-13 00:38:56 +01:00
|
|
|
result=ext_pclose(fh->f);
|
|
|
|
if (result > 0) result = 0;
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
fh->f = NULL;
|
2011-11-13 00:38:57 +01:00
|
|
|
} else {
|
|
|
|
#if USE_MMAP
|
|
|
|
if (fh->p_mmap) {
|
|
|
|
munmap(fh->p_mmap, fh->size_mmap);
|
|
|
|
fh->p_mmap = NULL;
|
|
|
|
fh->size_mmap = 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
result=close(fh->fd);
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
fh->fd = -1;
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fh->tmodi > 0L && !(fh->fh_flags & FH_IS_PIPE)
|
|
|
|
&& !(fh->fh_flags & FH_IS_READONLY)) {
|
2011-11-13 00:38:56 +01:00
|
|
|
struct utimbuf ut;
|
|
|
|
ut.actime = ut.modtime = fh->tmodi;
|
|
|
|
utime(fh->fname, &ut);
|
|
|
|
fh->tmodi = 0L;
|
|
|
|
}
|
|
|
|
#ifdef TEST_FNAME
|
|
|
|
if (fhandle == test_handle) {
|
|
|
|
test_handle = -1;
|
|
|
|
nw_debug = -99;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
result2=free_file_handle(fhandle);
|
|
|
|
return((result == -1) ? -0xff : result2);
|
|
|
|
} else return(free_file_handle(fhandle));
|
|
|
|
}
|
|
|
|
return(-0x88); /* wrong filehandle */
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8 *file_get_unix_name(int fhandle)
|
|
|
|
{
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fhandle > HOFFS && (--fhandle < anz_fhandles)) {
|
2011-11-13 00:38:56 +01:00
|
|
|
return((uint8*)file_handles[fhandle].fname);
|
|
|
|
}
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:57 +01:00
|
|
|
static void open_pipe_command(FILE_HANDLE *fh, int dowrite)
|
|
|
|
{
|
|
|
|
if (NULL == fh->f) {
|
|
|
|
char pipecommand[512];
|
|
|
|
sprintf(pipecommand, "%s %s %d %d",
|
|
|
|
fh->fname,
|
|
|
|
dowrite ? "WRITE" : "READ",
|
|
|
|
act_connection, act_pid);
|
|
|
|
fh->f = ext_popen(pipecommand, geteuid(), getegid());
|
|
|
|
}
|
|
|
|
fh->fd = (fh->f) ? fileno(fh->f->fildes[dowrite ? 0 : 1]) : -3;
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset)
|
|
|
|
{
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fhandle > HOFFS && (--fhandle < anz_fhandles)) {
|
2011-11-13 00:38:56 +01:00
|
|
|
FILE_HANDLE *fh=&(file_handles[fhandle]);
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fh->fh_flags & FH_IS_PIPE_COMMAND)
|
|
|
|
open_pipe_command(fh, 0);
|
2011-11-13 00:38:56 +01:00
|
|
|
if (fh->fd > -1) {
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */
|
2011-11-13 00:38:57 +01:00
|
|
|
int readsize=size;
|
|
|
|
if (-1 == (size = read(fh->fd, data, readsize)) ) {
|
|
|
|
int k=2;
|
|
|
|
do {
|
|
|
|
sleep(1);
|
|
|
|
} while(k-- && -1 == (size = read(fh->fd, data, readsize)));
|
|
|
|
if (size == -1) size=0;
|
|
|
|
}
|
|
|
|
if (!size) {
|
|
|
|
if (fh->f->flags & 1) return(-0x57);
|
|
|
|
fh->f->flags |= 1;
|
2011-11-13 00:38:57 +01:00
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
} else {
|
2011-11-13 00:38:57 +01:00
|
|
|
#if USE_MMAP
|
|
|
|
if (fh->p_mmap) {
|
2011-11-13 00:38:57 +01:00
|
|
|
while (1) {
|
|
|
|
if (offset < fh->size_mmap) {
|
|
|
|
if (size + offset > fh->size_mmap)
|
|
|
|
size = fh->size_mmap - offset;
|
|
|
|
memcpy(data, fh->p_mmap+offset, size);
|
|
|
|
if (got_sig_bus) {
|
|
|
|
fh->size_mmap = lseek(fh->fd, 0L, SEEK_END);
|
|
|
|
got_sig_bus = 0;
|
|
|
|
} else
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
size=-1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} /* while */
|
2011-11-13 00:38:57 +01:00
|
|
|
} else {
|
|
|
|
#endif
|
|
|
|
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"));
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
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;
|
|
|
|
#if USE_MMAP
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
#endif
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
if (size == -1) size=0;
|
2011-11-13 00:38:56 +01:00
|
|
|
return(size);
|
2011-11-13 00:38:57 +01:00
|
|
|
} else if (fh->fd == -3) return(0);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
return(-0x88); /* wrong filehandle */
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int nw_seek_datei(int fhandle, int modus)
|
|
|
|
{
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fhandle > HOFFS && (--fhandle < anz_fhandles)) {
|
2011-11-13 00:38:56 +01:00
|
|
|
FILE_HANDLE *fh=&(file_handles[fhandle]);
|
|
|
|
if (fh->fd > -1) {
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */
|
2011-11-13 00:38:57 +01:00
|
|
|
return(0x7fff0000 | (rand() & 0xffff) );
|
2011-11-13 00:38:56 +01:00
|
|
|
} else {
|
|
|
|
int size=-0xfb;
|
|
|
|
if (!modus) {
|
|
|
|
if ( (size=fh->offd=lseek(fh->fd, 0L, SEEK_END)) < 0L)
|
|
|
|
size = -1;
|
|
|
|
}
|
|
|
|
return(size);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
} else if (fh->fd == -3) return(0x7fff0000 | (rand() & 0xffff) );
|
|
|
|
/* PIPE COMMAND */
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
return(-0x88); /* wrong filehandle */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int nw_write_datei(int fhandle, uint8 *data, int size, uint32 offset)
|
|
|
|
{
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fhandle > HOFFS && (--fhandle < anz_fhandles)) {
|
2011-11-13 00:38:56 +01:00
|
|
|
FILE_HANDLE *fh=&(file_handles[fhandle]);
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fh->fh_flags & FH_IS_PIPE_COMMAND)
|
|
|
|
open_pipe_command(fh, 1);
|
2011-11-13 00:38:56 +01:00
|
|
|
if (fh->fd > -1) {
|
2011-11-13 00:38:58 +01:00
|
|
|
if (fh->fh_flags & FH_OPENED_RO) return(-0x94);
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */
|
2011-11-13 00:38:57 +01:00
|
|
|
return(size ? write(fh->fd, data, size) : 0);
|
2011-11-13 00:38:56 +01:00
|
|
|
} 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);
|
2011-11-13 00:38:56 +01:00
|
|
|
#endif
|
2011-11-13 00:38:56 +01:00
|
|
|
XDPRINTF((5,0,"File %s is truncated, result=%d", fh->fname, result));
|
|
|
|
fh->offd = -1L;
|
|
|
|
return(result);
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
} else if (fh->fd == -3) return(0);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
return(- 0x88); /* wrong filehandle */
|
|
|
|
}
|
|
|
|
|
|
|
|
int nw_server_copy(int qfhandle, uint32 qoffset,
|
|
|
|
int zfhandle, uint32 zoffset,
|
|
|
|
uint32 size)
|
|
|
|
{
|
2011-11-13 00:38:57 +01:00
|
|
|
if (qfhandle > HOFFS && (--qfhandle < anz_fhandles)
|
|
|
|
&& zfhandle > HOFFS && (--zfhandle < anz_fhandles) ) {
|
2011-11-13 00:38:56 +01:00
|
|
|
FILE_HANDLE *fhq=&(file_handles[qfhandle]);
|
|
|
|
FILE_HANDLE *fhz=&(file_handles[zfhandle]);
|
|
|
|
int retsize = -1;
|
|
|
|
if (fhq->fd > -1 && fhz->fd > -1) {
|
2011-11-13 00:38:57 +01:00
|
|
|
char buff[4096];
|
2011-11-13 00:38:56 +01:00
|
|
|
int wsize;
|
2011-11-13 00:38:58 +01:00
|
|
|
if (fhz->fh_flags & FH_OPENED_RO) return(-0x94);
|
2011-11-13 00:38:56 +01:00
|
|
|
if (lseek(fhq->fd, qoffset, SEEK_SET) > -1L &&
|
|
|
|
lseek(fhz->fd, zoffset, SEEK_SET) > -1L) {
|
|
|
|
retsize = 0;
|
2011-11-13 00:38:57 +01:00
|
|
|
while (size) {
|
2011-11-13 00:38:56 +01:00
|
|
|
int xsize = read(fhq->fd, buff, min(size, (uint32)sizeof(buff)));
|
|
|
|
if (xsize > 0){
|
|
|
|
if ((wsize =write(fhz->fd, buff, xsize)) != xsize) {
|
2011-11-13 00:38:56 +01:00
|
|
|
retsize = -0x1; /* out of Disk Space */
|
2011-11-13 00:38:56 +01:00
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
size -= (uint32)xsize;
|
|
|
|
retsize += wsize;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (xsize < 0) retsize=-0x93; /* no read privilegs */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fhq->offd = -1L;
|
|
|
|
fhz->offd = -1L;
|
|
|
|
return(retsize);
|
|
|
|
}
|
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
return(-0x88); /* wrong filehandle */
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int nw_lock_datei(int fhandle, int offset, int size, int do_lock)
|
|
|
|
{
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fhandle > HOFFS && (--fhandle < anz_fhandles)) {
|
2011-11-13 00:38:56 +01:00
|
|
|
FILE_HANDLE *fh=&(file_handles[fhandle]);
|
|
|
|
if (fh->fd > -1) {
|
|
|
|
struct flock flockd;
|
|
|
|
int result;
|
2011-11-13 00:38:57 +01:00
|
|
|
if (fh->fh_flags & FH_IS_PIPE) return(0);
|
2011-11-13 00:38:57 +01:00
|
|
|
flockd.l_type = (do_lock)
|
2011-11-13 00:38:58 +01:00
|
|
|
? ((fh->fh_flags & FH_OPENED_RO) ? F_RDLCK
|
|
|
|
: F_WRLCK)
|
2011-11-13 00:38:57 +01:00
|
|
|
: F_UNLCK;
|
2011-11-13 00:38:56 +01:00
|
|
|
flockd.l_whence = SEEK_SET;
|
2011-11-13 00:38:58 +01:00
|
|
|
#if 0
|
2011-11-13 00:38:56 +01:00
|
|
|
flockd.l_start = offset;
|
2011-11-13 00:38:58 +01:00
|
|
|
#else
|
|
|
|
/* Hint from:Morio Taneda <morio@sozio.geist-soz.uni-karlsruhe.de>
|
|
|
|
* dBase needs it
|
|
|
|
* 03-Dec-96
|
|
|
|
*/
|
|
|
|
flockd.l_start = (offset & 0x7fffffff);
|
|
|
|
#endif
|
2011-11-13 00:38:56 +01:00
|
|
|
flockd.l_len = size;
|
|
|
|
result = fcntl(fh->fd, F_SETLK, &flockd);
|
2011-11-13 00:38:56 +01:00
|
|
|
XDPRINTF((2, 0, "nw_%s_datei result=%d, fh=%d, offset=%d, size=%d",
|
|
|
|
(do_lock) ? "lock" : "unlock", result, fhandle, offset, size));
|
2011-11-13 00:38:56 +01:00
|
|
|
if (!result) return(0);
|
|
|
|
else return(-0x21); /* LOCK Violation */
|
2011-11-13 00:38:57 +01:00
|
|
|
} else if (fh->fd == -3) return(0);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
return(-0x88); /* wrong filehandle */
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:58 +01:00
|
|
|
int fd_2_fname(int fhandle, char *buf, int bufsize)
|
|
|
|
{
|
|
|
|
if (fhandle > HOFFS && (--fhandle < anz_fhandles)) {
|
|
|
|
FILE_HANDLE *fh=&(file_handles[fhandle]);
|
|
|
|
strmaxcpy(buf, fh->fname, bufsize-1);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
if (bufsize)
|
|
|
|
*buf='\0';
|
|
|
|
return(-0x88);
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
|
|
|
|
|