Ultrix-3.1/src/cmd/uucp/gename.c

Compare this file to the similar file:
Show the results in this format:


/**********************************************************************
 *   Copyright (c) Digital Equipment Corporation 1984, 1985, 1986.    *
 *   All Rights Reserved. 					      *
 *   Reference "/usr/src/COPYRIGHT" for applicable restrictions.      *
 **********************************************************************/

static char Sccsid[] = "@(#)gename.c	3.0	4/22/86";

/* ASSERT mod Sep 3 -- rti!trt */
/*
 * GENAME.C - as obtained from ittvax!watt, and modified by duke!dbl
 * 7/30/82
 *
 * decvax!larry - no changes since  BSD 4.2
 */

#include "uucp.h"
#include <sys/types.h>


#define TSSEQ
#define SEQHUNK 10
#define BASE 62


/*******
 *	gename(pre, sys, grade, file)	generate file name
 *	char grade, *sys, pre, *file;
 *
 *	return codes:  none
 */

gename(pre, sys, grade, file)
char pre, *sys, grade, *file;
{
	char sqnum[5];

	getseq(sqnum);
	sprintf(file, "%c.%.7s%c%.4s", pre, sys, grade, sqnum);
	DEBUG(4, "file - %s\n", file);
	return;
}


#define SLOCKTIME 15
#define SLOCKTRIES 15
#define SEQLEN 4

/*******
 *	getseq(snum)	get next sequence number
 *	char *snum;
 *
 *	return codes:  none
 *
 * Fri Jan 15 15:34:02 EST 1982 ittvax!swatt:
 * if "TSSEQ" is defined, use "ts" routines to keep sequence numbers
 * in either base 36 or 62.
 * if "SEQHUNK" is defined, then sequence numbers are allocated in
 * hunks of that size.  Using SEQHUNK on very busy systems is not
 * advisable unless TSSEQ is also enabled.
 *
 * Also fix so wraparound is correct; the old code did 9999=>1000
 *
 * The hunk idea saves a lot of filesystem activity.  To get a
 * new sequence number from the sequnce file invovles:
 *
 *  1)	Lock the file (creat + link)
 *  2)	Open file
 *  3)	Read from file
 *  4)	Reopen file for writing
 *  6)	Write to file
 *  7)  Unlock file (unlink)
 */

#ifndef SEQHUNK
# define SEQHUNK 1
#endif !SEQHUNK

#ifdef TSSEQ
 typedef long ts_t;
 ts_t	atots();
 char	*tstoa();
#else !TSSEQ
 typedef int ts_t;
#endif TSSEQ


getseq(snum)
char *snum;
{
	FILE *fp;
	char tseqbuf[64];
	static ts_t n;
	static int nseq = 0;

	if (nseq <= 0) {
		for (n = 0; n < SLOCKTRIES; n++) {
			if (!ulockf( Seqlock, (time_t)SLOCKTIME))
				break;
			sleep(5);
		}

		ASSERT(n < SLOCKTRIES, "CAN NOT GET", Seqlock, 0);

		/* @@@(ittvax!swatt):
		 * can save something by using "r+" on fopen
		 */
		if ((fp = fopen(Seqfile, "r")) != NULL) {
#ifdef TSSEQ
			fgets (tseqbuf, sizeof tseqbuf, fp);
			n = atots (tseqbuf);
#else !TSSEQ
			/* read sequence number file */
			fscanf(fp, "%4d", &n);
#endif TSSEQ
			fp = freopen(Seqfile, "w", fp);
			ASSERT(fp != NULL, "CAN NOT OPEN", Seqfile, 0);
		}
		else {
			/* can not read file - create a new one */
			if ((fp = fopen(Seqfile, "w")) == NULL)
				/* can not write new seqeunce file */
				return(FAIL);
			n = 0;
		}
#ifdef TSSEQ
		tstoa (n+SEQHUNK, tseqbuf, SEQLEN);
#else !TSSEQ
		sprintf (tseqbuf, "%04d", n+SEQHUNK);
#endif TSSEQ
		/* discard high order digits on overflow */
		while (strlen (tseqbuf) > SEQLEN)
			strcpy (tseqbuf, tseqbuf+1);
		fprintf (fp, "%s", tseqbuf);
		fclose (fp);
		rmlock (Seqlock);
		nseq = SEQHUNK;
	}

#ifdef TSSEQ
	/* Convert n to base 36 (or base 62) digit string */
	tstoa (n, tseqbuf, SEQLEN);
#else !TSSEQ
	sprintf (tseqbuf, "%04d", n);
#endif TSSEQ
	/* discard high-order digits on overflow */
	while (strlen (tseqbuf) > SEQLEN)
		strcpy (tseqbuf, tseqbuf+1);
	strcpy (snum, tseqbuf);
	++n;
	--nseq;
	return(0);
}

#ifdef TSSEQ
/*********************************************************************
function:	ts
description:	Convert between binary integers and base thirty-six
		strings (hence the name "ts")
programmer:	Alan S. Watt

history:
	01/14/82	original version
*********************************************************************/


/* Alphanumeric string-to-integer conversion routines */

/* BASE is either 36 or 62
 * Base 36 allows magnitudes from 0 to 1679615
 * Base 62 allows magnitudes from 0 to 14776365
 */
#ifndef BASE
# define BASE	62
#endif BASE
#define EOS	'\0'
static char tsdigits[]	=
	"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

#include <ctype.h>

/* Ordinal values for characters
 * Change for non-ASCII
 */
#define DIGORD(c)	(c-'0')
#define UCORD(c)	(c-'A')
#define LCORD(c)	(c-'a')


/* Convert TS string to binary integer */
ts_t
atots (str)
register char *str;
{

	register ts_t ret;
	register digit;

	for (ret = 0; *str != EOS; str++) {
		if (isupper (*str))
			digit = UCORD(*str) + 10;
		else if (islower (*str))
			digit = LCORD(*str) + 10 + (BASE-36);
		else if (isdigit (*str))
			digit = DIGORD(*str);
		else
			break;
		ret = ret * BASE + digit;
	}
	return (ret);
}

/* Convert binary integer to TS string.
 * String is left-padded with zeros up to the
 * width given by 'prec'.  Truncation does not
 * take place here; calling routine must do it
 * if required.
 */
char *
tstoa (num, buf, prec)
register ts_t num;
register char *buf;
int prec;
{
	register ts_t quot = num / BASE;

	if (--prec > 0 || quot != 0)
		buf = tstoa (quot, buf, prec);
	*buf++ = tsdigits[num % BASE];
	*buf = EOS;
	return (buf);
}
#endif TSSEQ