/*
Copyright (c) 2001-2006, Gerrit Pape
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

   1. Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
   2. Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
   3. The name of the author may not be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/* Busyboxed by Denis Vlasenko <vda.linux@googlemail.com> */
/* Collected into one file from runit's many tiny files */
/* TODO: review, eliminate unneeded stuff, move good stuff to libbb */

#include <sys/poll.h>
#include <sys/file.h>
#include "libbb.h"
#include "runit_lib.h"

unsigned byte_chr(char *s,unsigned n,int c)
{
	char ch;
	char *t;

	ch = c;
	t = s;
	for (;;) {
		if (!n) break;
		if (*t == ch) break;
		++t;
		--n;
	}
	return t - s;
}

int coe(int fd)
{
	return fcntl(fd, F_SETFD, FD_CLOEXEC);
}

#ifdef UNUSED
static /* as it isn't used anywhere else */
void tai_pack(char *s, const struct tai *t)
{
	uint64_t x;

	x = t->x;
	s[7] = x & 255; x >>= 8;
	s[6] = x & 255; x >>= 8;
	s[5] = x & 255; x >>= 8;
	s[4] = x & 255; x >>= 8;
	s[3] = x & 255; x >>= 8;
	s[2] = x & 255; x >>= 8;
	s[1] = x & 255; x >>= 8;
	s[0] = x;
}

void tai_unpack(const char *s,struct tai *t)
{
	uint64_t x;

	x = (unsigned char) s[0];
	x <<= 8; x += (unsigned char) s[1];
	x <<= 8; x += (unsigned char) s[2];
	x <<= 8; x += (unsigned char) s[3];
	x <<= 8; x += (unsigned char) s[4];
	x <<= 8; x += (unsigned char) s[5];
	x <<= 8; x += (unsigned char) s[6];
	x <<= 8; x += (unsigned char) s[7];
	t->x = x;
}


void taia_add(struct taia *t,const struct taia *u,const struct taia *v)
{
	t->sec.x = u->sec.x + v->sec.x;
	t->nano = u->nano + v->nano;
	t->atto = u->atto + v->atto;
	if (t->atto > 999999999UL) {
		t->atto -= 1000000000UL;
		++t->nano;
	}
	if (t->nano > 999999999UL) {
		t->nano -= 1000000000UL;
		++t->sec.x;
	}
}

int taia_less(const struct taia *t, const struct taia *u)
{
	if (t->sec.x < u->sec.x) return 1;
	if (t->sec.x > u->sec.x) return 0;
	if (t->nano < u->nano) return 1;
	if (t->nano > u->nano) return 0;
	return t->atto < u->atto;
}

void taia_now(struct taia *t)
{
	struct timeval now;
	gettimeofday(&now, NULL);
	tai_unix(&t->sec, now.tv_sec);
	t->nano = 1000 * now.tv_usec + 500;
	t->atto = 0;
}

/* UNUSED
void taia_pack(char *s, const struct taia *t)
{
	unsigned long x;

	tai_pack(s, &t->sec);
	s += 8;

	x = t->atto;
	s[7] = x & 255; x >>= 8;
	s[6] = x & 255; x >>= 8;
	s[5] = x & 255; x >>= 8;
	s[4] = x;
	x = t->nano;
	s[3] = x & 255; x >>= 8;
	s[2] = x & 255; x >>= 8;
	s[1] = x & 255; x >>= 8;
	s[0] = x;
}
*/

void taia_sub(struct taia *t, const struct taia *u, const struct taia *v)
{
	unsigned long unano = u->nano;
	unsigned long uatto = u->atto;

	t->sec.x = u->sec.x - v->sec.x;
	t->nano = unano - v->nano;
	t->atto = uatto - v->atto;
	if (t->atto > uatto) {
		t->atto += 1000000000UL;
		--t->nano;
	}
	if (t->nano > unano) {
		t->nano += 1000000000UL;
		--t->sec.x;
	}
}

/* XXX: breaks tai encapsulation */
void taia_uint(struct taia *t, unsigned s)
{
	t->sec.x = s;
	t->nano = 0;
	t->atto = 0;
}

static
uint64_t taia2millisec(const struct taia *t)
{
	return (t->sec.x * 1000) + (t->nano / 1000000);
}

void iopause(iopause_fd *x, unsigned len, struct taia *deadline, struct taia *stamp)
{
	int millisecs;
	int i;

	if (taia_less(deadline, stamp))
		millisecs = 0;
	else {
		uint64_t m;
		struct taia t;
		t = *stamp;
		taia_sub(&t, deadline, &t);
		millisecs = m = taia2millisec(&t);
		if (m > 1000) millisecs = 1000;
		millisecs += 20;
	}

	for (i = 0; i < len; ++i)
		x[i].revents = 0;

	poll(x, len, millisecs);
	/* XXX: some kernels apparently need x[0] even if len is 0 */
	/* XXX: how to handle EAGAIN? are kernels really this dumb? */
	/* XXX: how to handle EINVAL? when exactly can this happen? */
}
#endif

int lock_ex(int fd)
{
	return flock(fd,LOCK_EX);
}

int lock_exnb(int fd)
{
	return flock(fd,LOCK_EX | LOCK_NB);
}

int open_append(const char *fn)
{
	return open(fn, O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0600);
}

int open_read(const char *fn)
{
	return open(fn, O_RDONLY|O_NDELAY);
}

int open_trunc(const char *fn)
{
	return open(fn,O_WRONLY | O_NDELAY | O_TRUNC | O_CREAT,0644);
}

int open_write(const char *fn)
{
	return open(fn, O_WRONLY|O_NDELAY);
}

unsigned pmatch(const char *p, const char *s, unsigned len)
{
	for (;;) {
		char c = *p++;
		if (!c) return !len;
		switch (c) {
		case '*':
			if (!(c = *p)) return 1;
			for (;;) {
				if (!len) return 0;
				if (*s == c) break;
				++s; --len;
			}
			continue;
		case '+':
			if ((c = *p++) != *s) return 0;
			for (;;) {
				if (!len) return 1;
				if (*s != c) break;
				++s; --len;
			}
			continue;
			/*
		case '?':
			if (*p == '?') {
				if (*s != '?') return 0;
				++p;
			}
			++s; --len;
			continue;
			*/
		default:
			if (!len) return 0;
			if (*s != c) return 0;
			++s; --len;
			continue;
		}
	}
	return 0;
}
