#include <u.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <libc.h>
#include "rc.h"
#include "exec.h"
#include "io.h"
#include "fns.h"
#include "getflags.h"

extern char **mkargv(word*);
extern int mapfd(int);

static char *eargs = "cdflmnstuv";
static int rlx[] = {
	RLIMIT_CORE,
	RLIMIT_DATA,
	RLIMIT_FSIZE,
	RLIMIT_MEMLOCK,
	RLIMIT_RSS,
	RLIMIT_NOFILE,
	RLIMIT_STACK,
	RLIMIT_CPU,
	RLIMIT_NPROC,
	RLIMIT_RSS,
};

static void
eusage(void)
{
	fprint(mapfd(2), "usage: ulimit [-SHa%s [limit]]\n", eargs);
}

#define Notset -4
#define Unlimited -3
#define Hard -2
#define Soft -1

void
execulimit(void)
{
	int fd, n, argc, sethard, setsoft, limit;
	int flag[256];
	char **argv, **oargv, *p;
	char *argv0;
	struct rlimit rl;

	argv0 = nil;
	setstatus("");
	oargv = mkargv(runq->argv->words);
	argv = oargv+1;
	for(argc=0; argv[argc]; argc++)
		;

	memset(flag, 0, sizeof flag);
	ARGBEGIN{
	default:
		if(strchr(eargs, ARGC()) == nil){
			eusage();
			return;
		}
	case 'S':
	case 'H':
	case 'a':
		flag[ARGC()] = 1;
		break;
	}ARGEND

	if(argc > 1){
		eusage();
		goto out;
	}

	fd = mapfd(1);

	sethard = 1;
	setsoft = 1;
	if(flag['S'] && flag['H'])
		;
	else if(flag['S'])
		sethard = 0;
	else if(flag['H'])
		setsoft = 0;

	limit = Notset;
	if(argc>0){
		if(strcmp(argv[0], "unlimited") == 0)
			limit = Unlimited;
		else if(strcmp(argv[0], "hard") == 0)
			limit = Hard;
		else if(strcmp(argv[0], "soft") == 0)
			limit = Soft;
		else if((limit = strtol(argv[0], &p, 0)) < 0 || *p != 0){
			eusage();
			goto out;
		}
	}
	if(flag['a']){
		for(p=eargs; *p; p++){
			getrlimit(rlx[p-eargs], &rl);
			n = flag['H'] ? rl.rlim_max : rl.rlim_cur;
			if(n == -1)
				fprint(fd, "ulimit -%c unlimited\n", *p);
			else
				fprint(fd, "ulimit -%c %d\n", *p, n);
		}
		goto out;
	}
	for(p=eargs; *p; p++){
		if(flag[(uchar)*p]){
			n = 0;
			getrlimit(rlx[p-eargs], &rl);
			switch(limit){
			case Notset:
				n = flag['H'] ? rl.rlim_max : rl.rlim_cur;
				if(n == -1)
					fprint(fd, "ulimit -%c unlimited\n", *p);
				else
					fprint(fd, "ulimit -%c %d\n", *p, n);
				break;
			case Hard:
				n = rl.rlim_max;
				goto set;
			case Soft:
				n = rl.rlim_cur;
				goto set;
			case Unlimited:
				n = -1;
				goto set;
			default:
				n = limit;
			set:
				if(setsoft)
					rl.rlim_cur = n;
				if(sethard)
					rl.rlim_max = n;
				if(setrlimit(rlx[p-eargs], &rl) < 0)
					fprint(mapfd(2), "setrlimit: %r\n");
			}
		}
	}

out:
	free(oargv);
	poplist();
	flush(err);
}

void
execumask(void)
{
	int n, argc;
	char **argv, **oargv, *p;
	char *argv0;

	argv0 = nil;
	setstatus("");
	oargv = mkargv(runq->argv->words);
	argv = oargv+1;
	for(argc=0; argv[argc]; argc++)
		;

	ARGBEGIN{
	default:
	usage:
		fprint(mapfd(2), "usage: umask [mode]\n");
		goto out;
	}ARGEND

	if(argc > 1)
		goto usage;

	if(argc == 1){
		n = strtol(argv[0], &p, 8);
		if(*p != 0 || p == argv[0])
			goto usage;
		umask(n);
		goto out;
	}

	n = umask(0);
	umask(n);
	if(n < 0){
		fprint(mapfd(2), "umask: %r\n");
		goto out;
	}

	fprint(mapfd(1), "umask %03o\n", n);

out:
	free(oargv);
	poplist();
	flush(err);
}
