1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
#include "tra.h"
uint DMMASK =
DMIMMUTABLE |
DMSIMMUTABLE |
DMAPPEND |
DMSAPPEND |
DMEXCL |
DMRWXBITS;
int
syscreateexcl(char *name)
{
int fd;
fd = open(name, O_RDWR|O_CREAT|O_EXCL|O_EXLOCK, 0666);
if(fd < 0)
return -1;
return fd;
}
void*
mksig(struct stat *s, uint *np)
{
uint n;
uchar *p;
void *a;
n = sizeof(s->st_dev)
+sizeof(s->st_ino)
+sizeof(s->st_mtimespec);
a = emalloc(n);
*np = n;
p = a;
*(dev_t*)p = s->st_dev;
p += sizeof(s->st_dev);
*(ino_t*)p = s->st_ino;
p += sizeof(s->st_ino);
/*
* Using mtimespec here means that we end up
* rescanning some things more than once when
* the mtimes of recently written files fall out of the
* local machine cache and we get the network file
* server value, which is often less precise or just
* not in sync.
*/
*(struct timespec*)p = s->st_mtimespec;
p += sizeof(s->st_mtimespec);
USED(p);
return a;
}
ulong
modeflags2mode(ulong m, ulong f)
{
ulong tra;
tra = m&0777;
if((m&S_IFMT) == S_IFDIR)
tra |= DMDIR;
if(f&UF_IMMUTABLE)
tra |= DMIMMUTABLE;
if(f&UF_APPEND)
tra |= DMAPPEND;
if(f&SF_IMMUTABLE)
tra |= DMSIMMUTABLE;
if(f&SF_APPEND)
tra |= DMSAPPEND;
return tra;
}
void
mode2modeflags(ulong tra, ulong *m, ulong *f)
{
*m = tra&0777;
*f = 0;
if(tra&DMIMMUTABLE)
*f |= UF_IMMUTABLE;
if(tra&DMAPPEND)
*f |= UF_APPEND;
if(tra&DMSIMMUTABLE)
*f |= SF_IMMUTABLE;
if(tra&DMSAPPEND)
*f |= SF_APPEND;
}
ulong
stat2mode(char *tpath, struct stat *st)
{
USED(tpath);
return modeflags2mode(st->st_mode, st->st_flags);
}
ulong
trasetmode(char *tpath, ulong o, ulong n)
{
ulong om, of, nm, nf;
mode2modeflags(o, &om, &of);
mode2modeflags(n, &nm, &nf);
if(om != nm){
if(chmod(tpath, nm) >= 0)
om = nm;
else
fprint(2, "warning: chmod %s %o: %r\n", tpath, nm);
}
if(of != nf){
if(chflags(tpath, nf) >= 0)
of = nf;
else
fprint(2, "warning: chflags %s %o: %r\n", tpath, nf);
}
return modeflags2mode(om, of);
}
|