jehanne/sys/src/cmd/hjfs/main.c

182 lines
3.8 KiB
C

/* Copyright (c) 20XX 9front
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <u.h>
#include <lib9.h>
#include <libsec.h>
#include <thread.h>
#include "dat.h"
#include "fns.h"
char Eio[] = "i/o error";
char Enotadir[] = "not a directory";
char Enoent[] = "not found";
char Einval[] = "invalid operation";
char Eperm[] = "permission denied";
char Eexists[] = "file exists";
char Elocked[] = "file locked";
int mainstacksize = 65536;
void*
emalloc(int c)
{
void *v;
v = mallocz(c, 1);
if(v == 0)
sysfatal("malloc: %r");
setmalloctag(v, getcallerpc());
return v;
}
void*
erealloc(void *v, int c)
{
v = realloc(v, c);
if(v == 0 && c != 0)
sysfatal("realloc: %r");
setrealloctag(v, getcallerpc());
return v;
}
char*
estrdup(char *s)
{
s = strdup(s);
if(s == 0)
sysfatal("strdup: %r");
setmalloctag(s, getcallerpc());
return s;
}
ThrData *
getthrdata(void)
{
ThrData **v;
v = (ThrData **) threaddata();
if(*v == nil){
*v = emalloc(sizeof(**v));
(*v)->resp = chancreate(sizeof(void *), 0);
}
return *v;
}
Fs *fsmain;
int
dprint(char *fmt, ...)
{
static char buf[2048];
static QLock lk;
va_list va;
int rc;
qlock(&lk);
va_start(va, fmt);
snprint(buf, 2048, "hjfs: %s", fmt);
rc = vfprint(2, buf, va);
va_end(va);
qunlock(&lk);
return rc;
}
static void
syncproc(void * _)
{
for(;;){
sync(0);
sleep(SYNCINTERVAL);
}
}
void
usage(void)
{
fprint(2, "usage: %s [-rsS] [-m mem] [-n service] [-a announce-string]... -f dev\n", argv0);
exits("usage");
}
void
threadmain(int argc, char **argv)
{
Dev *d;
static char *nets[8];
char *file, *service;
int doream, flags, stdio, nbuf, netc;
netc = 0;
doream = 0;
stdio = 0;
flags = FSNOAUTH;
service = "hjfs";
file = nil;
nbuf = 1000;
ARGBEGIN {
case 'A': flags &= ~FSNOAUTH; break;
case 'r': doream++; break;
case 'S': flags |= FSNOPERM | FSCHOWN; break;
case 's': stdio++; break;
case 'f': file = estrdup(EARGF(usage())); break;
case 'n': service = estrdup(EARGF(usage())); break;
case 'm':
nbuf = muldiv(atoi(EARGF(usage())), 1048576, sizeof(Buf));
if(nbuf < 10)
nbuf = 10;
break;
case 'a':
if(netc >= nelem(nets)-1){
fprint(2, "%s: too many networks to announce\n", argv0);
exits("too many nets");
}
nets[netc++] = estrdup(EARGF(usage()));
break;
default: usage();
} ARGEND;
sys_rfork(RFNOTEG);
bufinit(nbuf);
if(file == nil)
sysfatal("no default file");
if(argc != 0)
usage();
d = newdev(file);
if(d == nil)
sysfatal("newdev: %r");
fsmain = initfs(d, doream, flags);
if(fsmain == nil)
sysfatal("fsinit: %r");
initcons(service);
proccreate(syncproc, nil, mainstacksize);
start9p(service, nets, stdio);
threadexits(nil);
}
void
shutdown(void)
{
wlock(fsmain);
sync(1);
dprint("ending\n");
sleep(1000);
sync(1);
threadexitsall(nil);
}