166 lines
4.1 KiB
C
166 lines
4.1 KiB
C
/* nwshare.c 21-Jul-97 */
|
|
|
|
/* (C)opyright (C) 1993,1997 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 "nwvolume.h"
|
|
#include "nwfile.h"
|
|
#include "connect.h"
|
|
|
|
#include "unxfile.h"
|
|
#include "nwshare.h"
|
|
|
|
#define MAX_SH_OP_DEV 20
|
|
|
|
typedef struct {
|
|
int fd_r;
|
|
int fd_wr;
|
|
int in_use;
|
|
int dev;
|
|
} SH_OP_DEV;
|
|
|
|
static SH_OP_DEV sh_op_devs[MAX_SH_OP_DEV];
|
|
static int count_sh_op_dev=0;
|
|
|
|
char *path_share_lock_files=NULL;
|
|
|
|
int share_file(int dev, int inode, int sh_mode)
|
|
/* sh_mode
|
|
* 0 : remove share
|
|
* 1 : add_ro_r_share
|
|
* 4 : add_ro_w_share
|
|
*
|
|
* 2 : add_wr_r_share
|
|
* 8 : add_wr_w_share
|
|
* ----
|
|
* 0x10 : test
|
|
*/
|
|
{
|
|
int k = count_sh_op_dev;
|
|
int fr = -1;
|
|
int fo = -1;
|
|
int result = -1;
|
|
SH_OP_DEV *sod;
|
|
struct flock flockd;
|
|
|
|
while (k--) {
|
|
sod=&(sh_op_devs[k]);
|
|
if (sod->fd_r < 0) {
|
|
fr=k;
|
|
} else if (sod->dev == dev) {
|
|
fo=k;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((!sh_mode) && fo==-1) {
|
|
XDPRINTF((1, 0, "Could not found share to remove"));
|
|
return(-1);
|
|
}
|
|
|
|
if (fo==-1 && fr==-1) {
|
|
if (count_sh_op_dev < MAX_SH_OP_DEV)
|
|
fr=count_sh_op_dev++;
|
|
else {
|
|
XDPRINTF((1, 0, "Too much 'share devs'"));
|
|
return(-1);
|
|
}
|
|
}
|
|
|
|
flockd.l_whence = SEEK_SET;
|
|
flockd.l_start = inode;
|
|
flockd.l_len = 1;
|
|
|
|
if (!sh_mode) {
|
|
sod=&(sh_op_devs[fo]);
|
|
flockd.l_type = F_UNLCK;
|
|
(void)fcntl(sod->fd_r, F_SETLK, &flockd);
|
|
(void)fcntl(sod->fd_wr, F_SETLK, &flockd);
|
|
if (--sod->in_use < 1) {
|
|
close(sod->fd_r);
|
|
close(sod->fd_wr);
|
|
sod->fd_r = -1;
|
|
sod->fd_wr = -1;
|
|
sod->dev = -1;
|
|
}
|
|
} else {
|
|
if (fo == -1) {
|
|
char buff[300];
|
|
int l;
|
|
sod=&(sh_op_devs[fr]);
|
|
if (NULL==path_share_lock_files) {
|
|
if (get_ini_entry(NULL, 41, buff, sizeof(buff)) && *buff)
|
|
new_str(path_share_lock_files, buff);
|
|
else
|
|
new_str(path_share_lock_files, "/var/spool/nwserv/.locks");
|
|
seteuid(0);
|
|
unx_xmkdir(path_share_lock_files, 0755);
|
|
reseteuid();
|
|
}
|
|
|
|
l=sprintf(buff, "%s/%x.r", path_share_lock_files, dev);
|
|
seteuid(0);
|
|
if (-1 < (sod->fd_r=open(buff, O_RDWR|O_CREAT, 0600)) ) {
|
|
buff[l-1]='w';
|
|
if (0 > (sod->fd_wr=open(buff, O_RDWR|O_CREAT, 0600) )){
|
|
close(sod->fd_r);
|
|
sod->fd_r=-1;
|
|
}
|
|
}
|
|
reseteuid();
|
|
|
|
if (sod->fd_r < 0) {
|
|
XDPRINTF((1, 0, "Cannot open sharefile=`%s`", buff));
|
|
return(-1);
|
|
}
|
|
sod->dev = dev;
|
|
} else
|
|
sod=&(sh_op_devs[fo]);
|
|
|
|
if (!(sh_mode&0x10)){
|
|
if (sh_mode & 1) {
|
|
flockd.l_type = (sh_mode & 4) ? F_WRLCK : F_RDLCK;
|
|
result=fcntl(sod->fd_r, F_SETLK, &flockd);
|
|
} else result=0;
|
|
|
|
if ((!result) && (sh_mode & 2) ) {
|
|
flockd.l_type = (sh_mode & 8) ? F_WRLCK : F_RDLCK;
|
|
result=fcntl(sod->fd_wr, F_SETLK, &flockd);
|
|
}
|
|
|
|
if (result) {
|
|
XDPRINTF((3, 0, "Cannot lock share sh_mode=%d", sh_mode));
|
|
} else {
|
|
sod->in_use++;
|
|
}
|
|
} else { /* only testing */
|
|
if (sh_mode & 1) {
|
|
flockd.l_type = (sh_mode & 4) ? F_WRLCK : F_RDLCK;
|
|
result=fcntl(sod->fd_r, F_GETLK, &flockd);
|
|
} else if (sh_mode & 2) {
|
|
flockd.l_type = (sh_mode & 8) ? F_WRLCK : F_RDLCK;
|
|
result=fcntl(sod->fd_wr, F_GETLK, &flockd);
|
|
} else result=-1;
|
|
return(flockd.l_type == F_UNLCK) ? 0 : -1;
|
|
}
|
|
}
|
|
return(result);
|
|
}
|
|
|