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#includeX#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} /