413 lines
6.6 KiB
C
413 lines
6.6 KiB
C
#include <u.h>
|
|
#include <libc.h>
|
|
#include "dat.h"
|
|
#include "fns.h"
|
|
|
|
void
|
|
logit(char *fmt, ...)
|
|
{
|
|
char buf[8192];
|
|
va_list arg;
|
|
|
|
va_start(arg, fmt);
|
|
vseprint(buf, buf + sizeof(buf), fmt, arg);
|
|
va_end(arg);
|
|
if(debug)
|
|
fprint(2, "%s\n", buf);
|
|
syslog(0, progname, "(%s\\%s) %s", remotesys, remoteuser, buf);
|
|
}
|
|
|
|
char*
|
|
getremote(char *dir)
|
|
{
|
|
int fd, n;
|
|
char remfile[256];
|
|
static char buf[256];
|
|
|
|
sprint(remfile, "%s/remote", dir);
|
|
fd = open(remfile, OREAD);
|
|
if(fd < 0)
|
|
return nil;
|
|
if((n = read(fd, buf, sizeof(buf)-1))>0)
|
|
buf[n-1] = 0;
|
|
else
|
|
strcpy(buf, remfile);
|
|
close(fd);
|
|
return buf;
|
|
}
|
|
|
|
char*
|
|
conspath(char *base, char *name)
|
|
{
|
|
return cleanname(smprint("%s/%s", base, name ? name : ""));
|
|
}
|
|
|
|
int
|
|
splitpath(char *path, char **base, char **name)
|
|
{
|
|
char *p, *b;
|
|
|
|
b = strdup(path);
|
|
if((p = strrchr(b, '/')) == nil){
|
|
free(b);
|
|
if(name)
|
|
*name = nil;
|
|
if(base)
|
|
*base = nil;
|
|
return 0;
|
|
}
|
|
if(p == b){
|
|
if(name) *name = strdup(p+1);
|
|
p[1] = 0;
|
|
} else {
|
|
*p++ = 0;
|
|
if(name) *name = strdup(p);
|
|
}
|
|
if(base)
|
|
*base = b;
|
|
else
|
|
free(b);
|
|
return 1;
|
|
}
|
|
|
|
void
|
|
dumphex(char *s, uchar *h, uchar *e)
|
|
{
|
|
int i, n;
|
|
|
|
n = e - h;
|
|
for(i=0; i<n; i++){
|
|
if((i % 16) == 0)
|
|
fprint(2, "%s%s: [%.4x] ", i ? "\n" : "", s, i);
|
|
fprint(2, "%.2x ", (int)h[i]);
|
|
}
|
|
fprint(2, "\n");
|
|
}
|
|
|
|
void
|
|
todatetime(long time, int *pdate, int *ptime)
|
|
{
|
|
Tm *tm;
|
|
|
|
tm = gmtime(time);
|
|
if(pdate)
|
|
*pdate = (tm->mday) | ((tm->mon + 1) << 5) | ((tm->year - 80) << 9);
|
|
if(ptime)
|
|
*ptime = (tm->sec >> 1) | (tm->min << 5) | (tm->hour << 11);
|
|
}
|
|
|
|
long
|
|
fromdatetime(int date, int time)
|
|
{
|
|
Tm tm;
|
|
|
|
memset(&tm, 0, sizeof(tm));
|
|
strcpy(tm.zone, "GMT");
|
|
tm.mday = date & 0x1f;
|
|
tm.mon = ((date >> 5) & 0xf) - 1;
|
|
tm.year = (date >> 9) + 80;
|
|
tm.yday = 0;
|
|
tm.sec = (time & 0x1f) << 1;
|
|
tm.min = (time >> 5) & 0x3f;
|
|
tm.hour = time >> 11;
|
|
return tm2sec(&tm);
|
|
}
|
|
|
|
vlong
|
|
tofiletime(long time)
|
|
{
|
|
return ((vlong)time + 11644473600LL) * 10000000;
|
|
}
|
|
|
|
long
|
|
fromfiletime(vlong filetime)
|
|
{
|
|
return filetime / 10000000 - 11644473600LL;
|
|
}
|
|
|
|
|
|
int
|
|
filesize32(vlong size)
|
|
{
|
|
if(size > 0xFFFFFFFFUL)
|
|
return 0xFFFFFFFF;
|
|
return size;
|
|
}
|
|
|
|
vlong
|
|
allocsize(vlong size, int blocksize)
|
|
{
|
|
return ((size + blocksize-1)/blocksize)*blocksize;
|
|
}
|
|
|
|
int
|
|
extfileattr(Dir *d)
|
|
{
|
|
int a;
|
|
|
|
a = (d->qid.type & QTDIR) ? ATTR_DIRECTORY : ATTR_NORMAL;
|
|
if((d->qid.type & QTTMP) == 0)
|
|
a |= ATTR_ARCHIVE;
|
|
if((d->mode & 0222) == 0)
|
|
a |= ATTR_READONLY;
|
|
if(d->name[0] == '.' && d->name[1] && d->name[1] != '.')
|
|
a |= ATTR_HIDDEN;
|
|
return a;
|
|
}
|
|
|
|
int
|
|
dosfileattr(Dir *d)
|
|
{
|
|
return extfileattr(d) & DOSMASK;
|
|
}
|
|
|
|
ulong
|
|
namehash(char *s)
|
|
{
|
|
ulong h, t;
|
|
Rune r;
|
|
|
|
h = 0;
|
|
while(*s){
|
|
s += chartorune(&r, s);
|
|
r = toupperrune(r);
|
|
t = h & 0xf8000000;
|
|
h <<= 5;
|
|
h ^= t>>27;
|
|
h ^= (ulong)r;
|
|
}
|
|
return h;
|
|
}
|
|
|
|
char*
|
|
strtr(char *s, Rune (*tr)(Rune))
|
|
{
|
|
char buf[UTFmax], *p, *w;
|
|
Rune r;
|
|
int n;
|
|
|
|
p = s;
|
|
w = s;
|
|
while(*p){
|
|
p += chartorune(&r, p);
|
|
r = (*tr)(r);
|
|
n = runetochar(buf, &r);
|
|
if(w + n <= p){
|
|
memmove(w, buf, n);
|
|
w += n;
|
|
}
|
|
}
|
|
*w = 0;
|
|
return s;
|
|
}
|
|
|
|
char*
|
|
strchrs(char *s, char *c)
|
|
{
|
|
Rune r;
|
|
int n;
|
|
|
|
while(*s){
|
|
n = chartorune(&r, s);
|
|
if(strchr(c, r))
|
|
return s;
|
|
s += n;
|
|
}
|
|
return nil;
|
|
}
|
|
|
|
static int
|
|
strpack8(uchar *, uchar *p, uchar *e, char *s, int term, Rune (*tr)(Rune))
|
|
{
|
|
uchar *t;
|
|
Rune r;
|
|
|
|
t = p;
|
|
while((p < e) && *s){
|
|
s += chartorune(&r, s);
|
|
r = tr(r);
|
|
*p++ = r & 0x7F;
|
|
}
|
|
if(p >= e)
|
|
return 0;
|
|
if(term)
|
|
*p++ = 0;
|
|
return p - t;
|
|
}
|
|
|
|
static int
|
|
strpack16(uchar *b, uchar *p, uchar *e, char *s, int term, Rune (*tr)(Rune))
|
|
{
|
|
unsigned int rr;
|
|
uchar *t;
|
|
Rune r;
|
|
|
|
t = p;
|
|
if((p - b) % 2){
|
|
if(p >= e)
|
|
return 0;
|
|
*p++ = 0;
|
|
}
|
|
while((p+1 < e) && *s){
|
|
s += chartorune(&r, s);
|
|
rr = tr(r);
|
|
if(rr > 0xFFFF){
|
|
if(p+3 >= e)
|
|
break;
|
|
rr -= 0x10000;
|
|
*p++ = (rr>>10) & 0xFF;
|
|
*p++ = ((rr>>18)&3) + 0xD8;
|
|
*p++ = rr & 0xFF;
|
|
*p++ = ((rr>>8)&3) + 0xDC;
|
|
} else {
|
|
*p++ = rr & 0xFF;
|
|
*p++ = rr>>8;
|
|
}
|
|
}
|
|
if(p+1 >= e)
|
|
return 0;
|
|
if(term){
|
|
*p++ = 0;
|
|
*p++ = 0;
|
|
}
|
|
return p - t;
|
|
}
|
|
|
|
static int
|
|
strunpack8(uchar *, uchar *p, uchar *e, char **dp, int term, Rune (*tr)(Rune))
|
|
{
|
|
uchar *t;
|
|
char *d;
|
|
Rune r;
|
|
int n;
|
|
|
|
t = p;
|
|
n = 0;
|
|
while((p < e) && (!term || *p)){
|
|
p++;
|
|
n++;
|
|
}
|
|
if(term && ((p >= e) || *p))
|
|
return 0;
|
|
p -= n;
|
|
*dp = d = malloc(n*UTFmax+1);
|
|
while(n--){
|
|
r = *p & 0x7F;
|
|
r = tr(r);
|
|
d += runetochar(d, &r);
|
|
p++;
|
|
}
|
|
*d = 0;
|
|
if(term)
|
|
p++;
|
|
return p - t;
|
|
}
|
|
|
|
static int
|
|
strunpack16(uchar *b, uchar *p, uchar *e, char **dp, int term, Rune (*tr)(Rune))
|
|
{
|
|
unsigned int rr;
|
|
uchar *t;
|
|
char *d;
|
|
Rune r;
|
|
int n;
|
|
|
|
t = p;
|
|
if((p - b) % 2)
|
|
p++;
|
|
n = 0;
|
|
while((p+1 < e) && (!term || (p[0] || p[1]))){
|
|
p += 2;
|
|
n++;
|
|
}
|
|
if(term && ((p+1 >= e) || p[0] || p[1]))
|
|
return 0;
|
|
p -= 2*n;
|
|
*dp = d = malloc(n*UTFmax+1);
|
|
while(n--){
|
|
if(p[1] >= 0xD8 && p[1] <= 0xDB){
|
|
if(!n--)
|
|
break;
|
|
rr = ((p[0]<<10) | ((p[1]-0xD8)<<18) | p[2] | ((p[3]-0xDC)<<8))+0x10000;
|
|
p += 2;
|
|
} else
|
|
rr = p[0] | (p[1]<<8);
|
|
r = tr(rr);
|
|
d += runetochar(d, &r);
|
|
p += 2;
|
|
}
|
|
*d = 0;
|
|
if(term)
|
|
p += 2;
|
|
return p - t;
|
|
}
|
|
|
|
static Rune
|
|
notr(Rune r)
|
|
{
|
|
return r;
|
|
}
|
|
|
|
static Rune
|
|
fromnametr(Rune r)
|
|
{
|
|
switch(r){
|
|
case '\\':
|
|
return '/';
|
|
case ' ':
|
|
if(trspaces)
|
|
return 0xa0;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
static Rune
|
|
tonametr(Rune r)
|
|
{
|
|
switch(r){
|
|
case '/':
|
|
return '\\';
|
|
case 0xa0:
|
|
if(trspaces)
|
|
return ' ';
|
|
}
|
|
return r;
|
|
}
|
|
|
|
int smbstrpack8(uchar *b, uchar *p, uchar *e, void *arg){
|
|
return strpack8(b, p, e, (char*)arg, 1, notr);
|
|
}
|
|
int smbstrpack16(uchar *b, uchar *p, uchar *e, void *arg){
|
|
return strpack16(b, p, e, (char*)arg, 1, notr);
|
|
}
|
|
int smbstrunpack8(uchar *b, uchar *p, uchar *e, void *arg){
|
|
return strunpack8(b, p, e, (char**)arg, 1, notr);
|
|
}
|
|
int smbstrunpack16(uchar *b, uchar *p, uchar *e, void *arg){
|
|
return strunpack16(b, p, e, (char**)arg, 1, notr);
|
|
}
|
|
int smbnamepack8(uchar *b, uchar *p, uchar *e, void *arg){
|
|
return strpack8(b, p, e, (char*)arg, 1, tonametr);
|
|
}
|
|
int smbnamepack16(uchar *b, uchar *p, uchar *e, void *arg){
|
|
return strpack16(b, p, e, (char*)arg, 1, tonametr);
|
|
}
|
|
int smbnameunpack8(uchar *b, uchar *p, uchar *e, void *arg){
|
|
return strunpack8(b, p, e, (char**)arg, 1, fromnametr);
|
|
}
|
|
int smbnameunpack16(uchar *b, uchar *p, uchar *e, void *arg){
|
|
return strunpack16(b, p, e, (char**)arg, 1, fromnametr);
|
|
}
|
|
int smbuntermstrpack8(uchar *b, uchar *p, uchar *e, void *arg){
|
|
return strpack8(b, p, e, (char*)arg, 0, notr);
|
|
}
|
|
int smbuntermstrpack16(uchar *b, uchar *p, uchar *e, void *arg){
|
|
return strpack16(b, p, e, (char*)arg, 0, notr);
|
|
}
|
|
int smbuntermnamepack8(uchar *b, uchar *p, uchar *e, void *arg){
|
|
return strpack8(b, p, e, (char*)arg, 0, tonametr);
|
|
}
|
|
int smbuntermnamepack16(uchar *b, uchar *p, uchar *e, void *arg){
|
|
return strpack16(b, p, e, (char*)arg, 0, tonametr);
|
|
}
|