Path: utzoo!attcan!uunet!cs.utexas.edu!rutgers!njin!princeton!notecnirp!nfs
From: nfs@notecnirp.Princeton.EDU (Norbert Schlenker)
Newsgroups: comp.os.minix
Subject: Another new stdio (part 4 of 4)
Summary: Miscellaneous routines
Message-ID: <19738@princeton.Princeton.EDU>
Date: 30 Sep 89 16:26:10 GMT
Sender: news@princeton.Princeton.EDU
Reply-To: nfs@notecnirp.UUCP (Norbert Schlenker)
Organization: Dept. of Computer Science, Princeton University
Lines: 713

echo x - ctype.c
sed '/^X/s///' > ctype.c << '/'
X#include 
X#undef isalnum
X#undef isalpha
X#undef isascii
X#undef iscntrl
X#undef isdigit
X#undef isgraph
X#undef islower
X#undef isprint
X#undef ispunct
X#undef isspace
X#undef isupper
X#undef isxdigit
X#undef toascii
X#undef _tolower
X#undef _toupper
X#undef tolower
X#undef toupper
X
X#define _CT_CS	(_CT_C | _CT_S)		/* control character and white space */
X#define _CT_UX	(_CT_U | _CT_X)		/* upper case hex digit */
X#define _CT_LX	(_CT_L | _CT_X)		/* lower case hex digit */
X
Xchar _ctype[] = {
X	0,
X	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,
X	_CT_C,	_CT_CS,	_CT_CS,	_CT_CS,	_CT_CS,	_CT_CS,	_CT_C,	_CT_C,
X	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,
X	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,
X	_CT_SP,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,
X	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,
X	_CT_N,	_CT_N,	_CT_N,	_CT_N,	_CT_N,	_CT_N,	_CT_N,	_CT_N,
X	_CT_N,	_CT_N,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,
X	_CT_P,	_CT_UX,	_CT_UX,	_CT_UX,	_CT_UX,	_CT_UX,	_CT_UX,	_CT_U,
X	_CT_U,	_CT_U,	_CT_U,	_CT_U,	_CT_U,	_CT_U,	_CT_U,	_CT_U,
X	_CT_U,	_CT_U,	_CT_U,	_CT_U,	_CT_U,	_CT_U,	_CT_U,	_CT_U,
X	_CT_U,	_CT_U,	_CT_U,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,
X	_CT_P,	_CT_LX,	_CT_LX,	_CT_LX,	_CT_LX,	_CT_LX,	_CT_LX,	_CT_L,
X	_CT_L,	_CT_L,	_CT_L,	_CT_L,	_CT_L,	_CT_L,	_CT_L,	_CT_L,
X	_CT_L,	_CT_L,	_CT_L,	_CT_L,	_CT_L,	_CT_L,	_CT_L,	_CT_L,
X	_CT_L,	_CT_L,	_CT_L,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_C
X};
Xint _ct_c;
X
X
Xint isalnum(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_U | _CT_L | _CT_N);
X}
X
Xint isalpha(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_U | _CT_L);
X}
X
Xint isascii(c)
Xint c;
X{
X  return (unsigned) c <= 0x7f;
X}
X
Xint iscntrl(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_C);
X}
X
Xint isdigit(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_N);
X}
X
Xint isgraph(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_U | _CT_L | _CT_N | _CT_P);
X}
X
Xint islower(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_L);
X}
X
Xint isprint(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_U | _CT_L | _CT_N | _CT_P | _CT_SP);
X}
X
Xint ispunct(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_P);
X}
X
Xint isspace(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_S | _CT_SP);
X}
X
Xint isupper(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_U);
X}
X
Xint isxdigit(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_N | _CT_X);
X}
X
Xint toascii(c)
Xint c;
X{
X  return c & 0x7f;
X}
X
Xint _tolower(c)
Xint c;
X{
X  return c - 'A' + 'a';
X}
X
Xint _toupper(c)
Xint c;
X{
X  return c - 'a' + 'A';
X}
X
Xint tolower(c)
Xint c;
X{
X  return ((_ctype+1)[c] & (_CT_U)) ? c - 'A' + 'a' : c;
X}
X
Xint toupper(c)
Xint c;
X{
X  return ((_ctype+1)[c] & (_CT_L)) ? c - 'a' + 'A' : c;
X}
/
echo x - div.c
sed '/^X/s///' > div.c << '/'
X#include 
X
Xdiv_t div(numer, denom)
Xint numer;
Xint denom;
X{
X  div_t result;
X
X  result.quot = numer / denom;
X  result.rem  = numer % denom;
X  return result;
X}
/
echo x - ldiv.c
sed '/^X/s///' > ldiv.c << '/'
X#include 
X
Xldiv_t ldiv(numer, denom)
Xlong int numer;
Xlong int denom;
X{
X  ldiv_t result;
X
X  result.quot = numer / denom;
X  result.rem  = numer % denom;
X  return result;
X}
/
echo x - strtol.c
sed '/^X/s///' > strtol.c << '/'
X#include 
X#include 
X#include 
X#include 
X#undef strtol
X#undef atoi
X#undef atol
X
Xlong int strtol(nptr, endptr, base)
Xregister const char *nptr;
Xchar **endptr;
Xint base;
X{
X  register int c;
X  long result = 0L;
X  long limit;
X  int negative = 0;
X  int overflow = 0;
X  int digit;
X
X  while ((c = *nptr) && isspace(c))	/* skip leading white space */
X	nptr++;
X  if ((c = *nptr) == '+' || c == '-') {	/* handle signs */
X	negative = (c == '-');
X	nptr++;
X  }
X  if (base == 0) {			/* determine base if unknown */
X	base = 10;
X	if (*nptr == '0') {
X		base = 8;
X		nptr++;
X		if ((c = *nptr) == 'x' || c == 'X') {
X			base = 16;
X			nptr++;
X		}
X	}
X  }
X  else
X  if (base == 16 && *nptr == '0') {	/* discard 0x/0X prefix if hex */
X	nptr++;
X	if ((c = *nptr == 'x') || c == 'X')
X		nptr++;
X  }
X
X  limit = LONG_MAX / base;		/* ensure no overflow */
X
X  nptr--;				/* convert the number */
X  while (c = *++nptr) {
X	if (isdigit(c))
X		digit = c - '0';
X	else
X		digit = c - (isupper(c) ? 'A' : 'a') + 10;
X	if (digit < 0 || digit >= base)
X		break;
X	if (result > limit)
X		overflow = 1;
X	if (!overflow) {
X		result = base * result;
X		if (digit > LONG_MAX - result)
X			overflow = 1;
X		else	
X			result += digit;
X	}
X  }
X  if (negative && !overflow)
X	result = 0L - result;
X  if (overflow) {
X	errno = ERANGE;
X	if (negative)
X		result = LONG_MIN;
X	else
X		result = LONG_MAX;
X  }
X
X  if (endptr != NULL)			/* set up return values */
X	*endptr = nptr;
X  return result;
X}
X
Xint atoi(nptr)
Xconst char *nptr;
X{
X  return (int) strtol(nptr, NULL, 10);
X}
X
Xlong atol(nptr)
Xconst char *nptr;
X{
X  return strtol(nptr, NULL, 10);
X}
/
echo x - strtoul.c
sed '/^X/s///' > strtoul.c << '/'
X#include 
X#include 
X#include 
X#include 
X#undef strtoul
X
Xunsigned long int strtoul(nptr, endptr, base)
Xregister const char *nptr;
Xchar **endptr;
Xint base;
X{
X  register int c;
X  unsigned long result = 0L;
X  unsigned long limit;
X  int negative = 0;
X  int overflow = 0;
X  int digit;
X
X  while ((c = *nptr) && isspace(c))	/* skip leading white space */
X	nptr++;
X  if ((c = *nptr) == '+' || c == '-') {	/* handle signs */
X	negative = (c == '-');
X	nptr++;
X  }
X  if (base == 0) {			/* determine base if unknown */
X	base = 10;
X	if (*nptr == '0') {
X		base = 8;
X		nptr++;
X		if ((c = *nptr) == 'x' || c == 'X') {
X			base = 16;
X			nptr++;
X		}
X	}
X  }
X  else
X  if (base == 16 && *nptr == '0') {	/* discard 0x/0X prefix if hex */
X	nptr++;
X	if ((c = *nptr == 'x') || c == 'X')
X		nptr++;
X  }
X
X  limit = ULONG_MAX / base;		/* ensure no overflow */
X
X  nptr--;				/* convert the number */
X  while (c = *++nptr) {
X	if (isdigit(c))
X		digit = c - '0';
X	else
X		digit = c - (isupper(c) ? 'A' : 'a') + 10;
X	if (digit < 0 || digit >= base)
X		break;
X	if (result > limit)
X		overflow = 1;
X	if (!overflow) {
X		result = base * result;
X		if (digit > ULONG_MAX - result)
X			overflow = 1;
X		else	
X			result += digit;
X	}
X  }
X  if (negative && !overflow)	/* BIZARRE, but ANSI says we should do this! */
X	result = 0L - result;
X  if (overflow) {
X	errno = ERANGE;
X	result = ULONG_MAX;
X  }
X
X  if (endptr != NULL)			/* point at tail */
X	*endptr = nptr;
X  return result;
X}
/
echo x - printk.c
sed '/^X/s///' > printk.c << '/'
X/* --- printk.c --- */
X/* Kernel's version of printf() */
X
X#define _KERNEL_
X#include 
X#include "_doprnt.c"
/
echo x - prints.c
sed '/^X/s///' > prints.c << '/'
X/* prints() is like printf(), except that it doesn't have anything to do
X * with streams and it can only handle %s and %c.  It cannot print any
X * of the numeric types such as %d, %o, etc.  It always left justifies
X * strings; it cannot right justify them.  It has the advantage of not
X * requiring the runtime code for converting binary numbers to ASCII,
X * which saves 1K bytes in the object program.  Since many of the small
X * utilities do not need numeric printing, they often use prints().  It
X * has the disadvantage that its output is not synchronized with any stream.  
X */
X
X#include 
X#include 
X#include 
X
X#define STDOUT		1
X#define TRUNC_SIZE	128
X#define PUT(c)		{ if (bp != &buf[TRUNC_SIZE]) *bp++ = c; }
X
Xint prints(s)
Xchar *s;
X{
X  va_list ap;
X  char buf[TRUNC_SIZE];
X  register char *fp = s;
X  register char *bp = buf;
X  register int width;
X  char *p, *p1;
X
X  va_start(ap, s);
X  while (*fp) {
X	if (*fp != '%') {
X		PUT(*fp++);
X		continue;
X	}
X	fp++;
X	width = 0;
X	while (*fp >= '0' && *fp <= '9')
X		width = 10 * width + (*fp++ - '0');
X	switch (*fp) {
X	    case 'c':
X		PUT(va_arg(ap, char));
X		break;
X	    case 's':
X		p1 = p = va_arg(ap, char *);
X		while(*p1) PUT(*p1++);
X		for (width -= (p1 - p); --width >= 0; )
X			PUT(' ');
X		break;
X	    default:
X		PUT('%'); PUT(*s);
X		break;
X	}
X	fp++;
X  }
X  write(STDOUT, buf, bp - buf);		/* write everything at once */
X  return bp - buf;
X}
/
echo x - cuserid.c
sed '/^X/s///' > cuserid.c << '/'
X#define _POSIX_SOURCE
X#include 
X#include 
X#include 
X#include 
X#include 
X
Xchar *cuserid(s)
Xchar *s;
X{
X  static char id[L_cuserid];
X  struct passwd *pwd;
X
X  if (s == NULL)
X    s = id;
X
X  if ((pwd = getpwuid(geteuid())) == NULL) {
X	*s = '\0';
X	return NULL;
X  }
X  strcpy(s, pwd->pw_name);
X  return s;
X}
/
echo x - getlogin.c
sed '/^X/s///' > getlogin.c << '/'
X#define _POSIX_SOURCE
X#include 
X#include 
X#include 
X#include 
X#include 
X
Xchar *getlogin()
X{
X  static char id[L_cuserid];
X  struct passwd *pwd;
X
X  if ((pwd = getpwuid(getuid())) == NULL)
X	return NULL;
X  return strcpy(id, pwd->pw_name);
X}
/
echo x - getgrent.c
sed '/^X/s///' > getgrent.c << '/'
X/*
X * get entry from group file
X *   By Patrick van Kleef
X *   POSIX conversion by Norbert Schlenker
X */
X
X#define _POSIX_SOURCE
X#include 
X#include 
X#include 
X#include 
X#include 
X#include 
X
X#define PRIVATE static
X
X
XPRIVATE char _gr_file[] = "/etc/group";
XPRIVATE char _grbuf[256];
XPRIVATE char _buffer[1024];
XPRIVATE char *_pnt;
XPRIVATE char *_buf;
XPRIVATE int  _gfd = -1;
XPRIVATE int  _bufcnt;
XPRIVATE struct group grp;
XPRIVATE char *_mem = NULL;
X
Xint setgrent()
X{
X  if (_gfd >= 0)
X	lseek (_gfd, 0L, SEEK_SET);
X  else
X	_gfd = open(_gr_file, O_RDONLY);
X
X  _bufcnt = 0;
X  return (_gfd);
X}
X
X
Xvoid endgrent() 
X{
X  if (_gfd >= 0)
X	close (_gfd);
X
X  _gfd = -1;
X  _bufcnt = 0;
X}
X
X
XPRIVATE int _getline() 
X{
X  if (_gfd < 0 && setgrent() < 0)
X	return 0;
X
X  _buf = _grbuf;
X  do {
X	if (--_bufcnt <= 0) {
X		if ((_bufcnt = read(_gfd, _buffer, 1024)) <= 0)
X			return 0;
X		else
X			_pnt = _buffer;
X	}
X	*_buf++ = *_pnt++;
X  } while (*_pnt != '\n');
X  _pnt++;
X  _bufcnt--;
X  *_buf = 0;
X  _buf = _grbuf;
X  return 1;
X}
X
XPRIVATE void _skip_period() 
X{
X  while ((*_buf) && (*_buf != ':'))
X	_buf++;
X  *_buf++ = '\0';
X}
X
Xstruct group *getgrent() 
X{
X  if (_getline() == 0)
X       return 0;
X
X  grp.gr_name = _buf;
X  _skip_period();
X  grp.gr_passwd = _buf;
X  _skip_period();
X  grp.gr_gid = (gid_t) atoi (_buf);
X  _skip_period();
X  return &grp;
X}
X
XPRIVATE void _grp_members()  /* PENDING - needs to be rather more elaborate */
X{
X  grp.gr_mem = &_mem;
X}
X
Xstruct group *getgrnam(name)
Xchar *name;
X{
X  struct group *grp;
X
X  setgrent();
X  while ((grp = getgrent()) != 0)
X	if (!strcmp(grp->gr_name, name))
X		break;
X  endgrent();
X  _grp_members();
X  return grp;
X}
X
Xstruct group *getgrgid(gid)
Xgid_t gid;
X{
X  struct group *grp;
X
X  setgrent();
X  while ((grp = getgrent()) != 0)
X	if (grp->gr_gid == gid)
X		break;
X  endgrent();
X  _grp_members();
X  return grp;
X}
/
echo x - getpwent.c
sed '/^X/s///' > getpwent.c << '/'
X/*
X * get entry from password file
X *   By Patrick van Kleef
X *   POSIX conversion by Norbert Schlenker
X */
X
X#define _POSIX_SOURCE
X#include 
X#include 
X#include 
X#include 
X#include 
X#include 
X
X#define PRIVATE static
X
XPRIVATE char  _pw_file[] = "/etc/passwd";
XPRIVATE char  _pwbuf[256];
XPRIVATE char  _buffer[1024];
XPRIVATE char *_pnt;
XPRIVATE char *_buf;
XPRIVATE int   _pw = -1;
XPRIVATE int   _bufcnt;
XPRIVATE struct passwd pwd;
X
Xint setpwent() 
X{
X  if (_pw >= 0)
X	lseek(_pw, 0L, SEEK_SET);
X  else
X	_pw = open(_pw_file, O_RDONLY);
X
X  _bufcnt = 0;
X  return _pw;
X}
X
X
Xvoid endpwent() 
X{
X  if (_pw >= 0)
X	close (_pw);
X
X  _pw = -1;
X  _bufcnt = 0;
X}
X
XPRIVATE int _getline() 
X{
X  if (_pw < 0 && setpwent() < 0)
X	return 0;
X  _buf = _pwbuf;
X  do {
X	if (--_bufcnt <= 0) {
X		if ((_bufcnt = read(_pw, _buffer, 1024)) <= 0)
X			return 0;
X		else
X			_pnt = _buffer;
X	}
X	*_buf++ = *_pnt++;
X  } while (*_pnt != '\n');
X  _pnt++;
X  _bufcnt--;
X  *_buf = 0;
X  _buf = _pwbuf;
X  return 1;
X}
X
XPRIVATE void _skip_period() 
X{
X  while (*_buf != ':')
X	_buf++;
X  *_buf++ = '\0';
X}
X
Xstruct passwd *getpwent() 
X{
X  if (_getline() == 0)
X	return 0;
X
X  pwd.pw_name = _buf;
X  _skip_period();
X  pwd.pw_passwd = _buf;
X  _skip_period();
X  pwd.pw_uid = (uid_t) atoi (_buf);
X  _skip_period();
X  pwd.pw_gid = (gid_t) atoi (_buf);
X  _skip_period();
X  pwd.pw_gecos = _buf;
X  _skip_period();
X  pwd.pw_dir = _buf;
X  _skip_period();
X  pwd.pw_shell = _buf;
X
X  return &pwd;
X}
X
Xstruct passwd *getpwnam(name)
Xchar *name;
X{
X  struct passwd *pwd;
X
X  setpwent();
X  while ((pwd = getpwent()) != 0)
X	if (!strcmp(pwd->pw_name, name))
X		break;
X  endpwent();
X  return pwd;
X}
X
Xstruct passwd *getpwuid(uid)
Xuid_t uid;
X{
X  struct passwd *pwd;
X
X  setpwent();
X  while ((pwd = getpwent()) != 0)
X	if (pwd->pw_uid == uid)
X		break;
X  endpwent();
X  return pwd;
X}
/