mars-nwe/src/nwattrib.c

242 lines
6.9 KiB
C

/* nwattrib.c 10-May-98 */
/* (C)opyright (C) 1998 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.
*/
/* Attrib routines for mars_nwe */
#include "net.h"
#include <dirent.h>
#include "unxfile.h"
#include "nwvolume.h"
#include "connect.h"
#include "trustee.h"
#include "nwattrib.h"
static void put_attr_to_disk(int dev, ino_t inode, uint32 attrib)
{
char buf[255];
char battrib[255];
int l;
uint8 buf_uc[4];
U32_TO_BE32(inode, buf_uc);
l=snprintf(buf, sizeof(buf), "%s/%x/%x/%x/%x", path_attributes,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2]);
seteuid(0);
unx_xmkdir(buf, 0755);
sprintf(buf+l, "/%x", (int) buf_uc[3]);
unlink(buf);
l=sprintf(battrib, "%08x", (unsigned int) attrib);
symlink(battrib, buf);
reseteuid();
}
static void free_attr_from_disk(int dev, ino_t inode)
{
char buf[255];
uint8 buf_uc[4];
U32_TO_BE32(inode, buf_uc);
snprintf(buf, sizeof(buf), "%s/%x/%x/%x/%x/%x", path_attributes,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2],
(int) buf_uc[3]);
seteuid(0);
unlink(buf);
reseteuid();
}
static int get_attr_from_disk(int dev, ino_t inode, uint32 *attrib)
/* returns 0 if all ok */
{
char buf[255];
char battrib[255];
int l;
uint8 buf_uc[4];
U32_TO_BE32(inode, buf_uc);
snprintf(buf, sizeof(buf), "%s/%x/%x/%x/%x/%x", path_attributes,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2],
(int) buf_uc[3]);
seteuid(0);
l=readlink(buf, battrib, 224);
reseteuid();
if (l > 0) {
unsigned int uattrib=0;
battrib[l]='\0';
if (1 == sscanf(battrib, "%x", &uattrib)) {
*attrib = uattrib;
return(0);
}
}
return(-1);
}
uint32 get_nw_attrib_dword(int volume, char *unixname, struct stat *stb)
/* returns full attrib_dword */
{
uint32 attrib = S_ISDIR(stb->st_mode) ? FILE_ATTR_DIR
: FILE_ATTR_A;
int voloptions = get_volume_options(volume);
if (voloptions & VOL_OPTION_IS_PIPE) {
attrib |= (FILE_ATTR_DELETE_INH|FILE_ATTR_RENAME_INH);
if (!S_ISDIR(stb->st_mode)){
attrib|=FILE_ATTR_SHARE;
}
return(attrib);
}
if ( (voloptions & VOL_OPTION_ATTRIBUTES) &&
!get_attr_from_disk(stb->st_dev, stb->st_ino, &attrib)) {
if (S_ISDIR(stb->st_mode)) attrib |= FILE_ATTR_DIR;
else attrib &= (~FILE_ATTR_DIR);
}
if (voloptions & VOL_OPTION_READONLY){
attrib |= (FILE_ATTR_DELETE_INH|FILE_ATTR_RENAME_INH|FILE_ATTR_R);
}
if (!(voloptions & VOL_OPTION_ATTRIBUTES)) {
/* only for volumes without attribute handling */
if (act_uid) {
/* if not root */
int acc=get_unix_eff_rights(stb);
if (!(acc & W_OK)) {
attrib |= FILE_ATTR_R; /* RO */
}
if (!(acc & R_OK)) {
attrib |= FILE_ATTR_H; /* We say hidden here */
}
}
}
return(attrib);
}
static int set_nw_attrib(
int volume, char *unixname, struct stat *stb, uint32 attrib, uint32 mode)
/* mode == 0 : set_nw_attrib_dword
1 : set_nw_attrib_byte
2 : set_nw_attrib_word
*/
{
int is_dir=S_ISDIR(stb->st_mode);
uint32 oldattrib,newattrib;
int voloptions=get_volume_options(volume);
if (voloptions & VOL_OPTION_IS_PIPE)
return(0); /* we return with no error */
if (tru_eff_rights_exists(volume, unixname, stb, TRUSTEE_M))
return(-0x8c); /* no modify rights */
if (!(voloptions & VOL_OPTION_ATTRIBUTES)) {
if (!(get_unix_eff_rights(stb) & W_OK)) {
if (!(attrib & FILE_ATTR_R)) { /* if not setting RO */
if (!chmod(unixname, stb->st_mode | S_IWUSR)) {
stb->st_mode |= S_IWUSR;
} else
return(-0x8c); /* no modify rights */
}
}
}
if (mode || !(voloptions & VOL_OPTION_ATTRIBUTES)) {
oldattrib=get_nw_attrib_dword(volume, unixname, stb);
if (mode==1) { /* byte */
newattrib = (oldattrib & ~0xff);
newattrib |= (attrib & 0xff);
} else if (mode==2) { /* word */
newattrib = (oldattrib & ~0xffff);
newattrib |= (attrib & 0xffff);
} else newattrib=attrib;
} else {
newattrib=attrib;
}
if ((!mode) || (newattrib != oldattrib) ) {
if (!(voloptions & VOL_OPTION_ATTRIBUTES)) {
if ((!is_dir) && ((newattrib&FILE_ATTR_R)!=(oldattrib&FILE_ATTR_R))) {
int oldmode=stb->st_mode;
if (newattrib & FILE_ATTR_R) /* R/O */
stb->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
else
stb->st_mode |= (S_IWUSR | S_IWGRP);
if (chmod(unixname, stb->st_mode)) {
stb->st_mode = oldmode;
return(-0x8c); /* no modify rights */
}
}
} else {
if (is_dir) newattrib |= 0x10;
else newattrib &= ~0x10;
put_attr_to_disk(stb->st_dev, stb->st_ino, newattrib);
}
}
return(0);
}
int set_nw_attrib_dword(int volume, char *unixname, struct stat *stb, uint32 attrib)
/* wattrib = ext_attrib, attrib */
{
return(set_nw_attrib(volume,unixname,stb,attrib, 0));
}
int set_nw_attrib_byte(int volume, char *unixname, struct stat *stb, int battrib)
{
return(set_nw_attrib(volume,unixname,stb,(uint32)battrib, 1));
}
int set_nw_attrib_word(int volume, char *unixname, struct stat *stb, int wattrib)
/* wattrib = ext_attrib, attrib */
{
return(set_nw_attrib(volume,unixname,stb,(uint32)wattrib, 2));
}
void set_nw_archive_bit(int volume, char *unixname, int dev, ino_t inode)
/* sets archive bit on files, is called when file is closed */
{
uint32 attrib=0L;
int voloptions=get_volume_options(volume);
if (voloptions & VOL_OPTION_ATTRIBUTES) {
if ( (!get_attr_from_disk(dev, inode, &attrib))
&& !(attrib & FILE_ATTR_A)) {
attrib|=FILE_ATTR_A;
put_attr_to_disk(dev, inode, attrib);
}
}
}
void free_nw_ext_inode(int volume, char *unixname, int dev, ino_t inode)
/* removes all attrib or trustees entries for files or dirs */
/* must be called after deleting nw file or dir */
{
int voloptions=get_volume_options(volume);
if (voloptions & VOL_OPTION_ATTRIBUTES)
free_attr_from_disk(dev, inode);
if (voloptions & VOL_OPTION_TRUSTEES) {
int i=used_nw_volumes;
while(i--)
tru_free_file_trustees_from_disk(i, dev, inode);
}
}