File:  [ELWIX - Embedded LightWeight unIX -] / libaitsync / src / tool.c
Revision 1.1.1.1.2.2: download - view: text, annotated - select for diffs - revision graph
Mon May 9 13:46:12 2011 UTC (13 years, 2 months ago) by misho
Branches: sync1_0
Diff to: branchpoint 1.1.1.1: preferred, unified
under NetBSD mkstemps() function not exists!!!
added this feature for NetBSD systems

/*************************************************************************
* (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
*  by Michael Pounov <misho@openbsd-bg.org>
*
* $Author: misho $
* $Id: tool.c,v 1.1.1.1.2.2 2011/05/09 13:46:12 misho Exp $
*
*************************************************************************/
#include "global.h"
#include "tool.h"


/*
 * sync_mksig() Make signature from chunk
 * @id = chunk id
 * @off = file offset
 * @buf = chunk buffer for calculate signature
 * @buflen = buffer length in bytes
 * @sc = Chunk structure for fill
*/
inline void sync_mksig(int id, off_t off, u_char * __restrict buf, int buflen, sync_chunk_t * __restrict sc)
{
	MD5_CTX ctx;

	MD5_Init(&ctx);
	memset(sc, 0, sizeof(sync_chunk_t));
	sc->sc_magic = DLTSYNC_MAGIC;
	sc->sc_id = id;
	sc->sc_off = off;
	sc->sc_len = buflen;
	sc->sc_roll = crcAdler(buf, buflen);
	MD5_Update(&ctx, buf, buflen);
	MD5_Final(sc->sc_cksum, &ctx);
}

/*
 * syncWriteNum() Write to handle converted number to bigendian
 * @f = handle
 * @ulNum = number to convert
 * @nNumLen = length of number to bytes
 * return: -1 error, != -1 writed bytes to handle
*/
inline int syncWriteNum(int f, u_long ulNum, int nNumLen)
{
	u_char buf[sizeof ulNum];
	register int i;

	if (nNumLen < 1 || nNumLen > ULONG_MAX) {
		syncSetErr(-1, "Illegal number len %d\n", nNumLen);
		return -1;
	}

	for (i = nNumLen - 1; i; i--) {
		buf[i] = (u_char) ulNum;
		ulNum >>= 8;
	}

	return write(f, buf, nNumLen);
}

#ifndef HAVE_MKSTEMPS
#define TEMPCHARS       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
#define NUM_CHARS       (sizeof(TEMPCHARS) - 1)

int
mkstemps(char *path, int slen)
{
	char *start, *cp, *ep;
	const char *tempchars = TEMPCHARS;
	unsigned int tries = 1;
	size_t len;
	int fd;

	assert(path);
	len = strlen(path);
	if (len == 0 || slen >= len) {
		errno = EINVAL;
		goto end;
	} else
		ep = path + len - slen;

	for (start = ep; start > path && start[-1] == 'X'; start--) {
		if (tries < INT_MAX / NUM_CHARS)
			tries *= NUM_CHARS;
	}
	tries *= 2;

	do {
		for (cp = start; cp != ep; cp++)
			*cp = tempchars[arc4random_uniform(NUM_CHARS)];

		fd = open(path, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
		if (fd != -1 || errno != EEXIST)
			return fd;
	} while (--tries);

	errno = EEXIST;
end:
	return -1;
}
#endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>