Add libcompat_minix for NBSD libc

libcompat_minix is a compatibility layer meant to let existing commands to work
with the new libc.
This commit is contained in:
Gianluca Guida 2011-03-18 16:08:26 +00:00
parent 0dc9e0996a
commit 6bcf58bab8
20 changed files with 3029 additions and 0 deletions

View file

@ -0,0 +1,46 @@
.include <bsd.own.mk>
LIB= compat_minix
CPPFLAGS+= -D_MINIX_COMPAT
.PATH: ${.CURDIR}
# std_err()
SRCS+= stderr.c
# V8 regexp (incompatible with BSD regexp)
SRCS+= v8regerror.c v8regexp.c v8regsub.c
# Configfile Library.
SRCS+= configfile.c
# ACK a.out format.
SRCS+= nlist.c
# Minix 'mtab' handling functions.
#
# These should be changed when we switch to
# NetBSD's 'mtab' format.
SRCS+= mtab.c
# Termcap.
# Included in the Minix libc.
#
# Should be removed once we switch to terminfo.
SRCS+= termcap.c
# Minix legacy passwd format
# These should be removed when we switch to
# NetBSD's 'passwd' db-based format.
SRCS+= crypt.c getpwent.c
# fttyslot(fd), a Minix-specific extension
SRCS+= fttyslot.c
# cuserid()
# Now considered "compat" feature in NetBSD.
SRCS+= cuserid.c
.include "include/Makefile.inc"
.include <bsd.lib.mk>

View file

@ -0,0 +1,574 @@
/* config_read(), _delete(), _length() - Generic config file routines.
* Author: Kees J. Bot
* 5 Jun 1999
*/
#define nil ((void*)0)
#if __minix_vmd
#include <minix/stubs.h>
#else
#define fstat _fstat
#define stat _stat
#endif
#include <sys/types.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#if __minix_vmd
#include <minix/asciictype.h>
#else
#include <ctype.h>
#endif
#define _c /* not const */
#include <configfile.h>
typedef struct configfile { /* List of (included) configuration files. */
struct configfile *next; /* A list indeed. */
time_t ctime; /* Last changed time, -1 if no file. */
char name[1]; /* File name. */
} configfile_t;
/* Size of a configfile_t given a file name of length 'len'. */
#define configfilesize(len) (offsetof(configfile_t, name) + 1 + (len))
typedef struct firstconfig { /* First file and first word share a slot. */
configfile_t *filelist;
char new; /* Set when created. */
config_t config1;
} firstconfig_t;
/* Size of a config_t given a word of lenght 'len'. Same for firstconfig_t. */
#define config0size() (offsetof(config_t, word))
#define configsize(len) (config0size() + 1 + (len))
#define firstconfigsize(len) \
(offsetof(firstconfig_t, config1) + configsize(len))
/* Translate address of first config word to enclosing firstconfig_t and vv. */
#define cfg2fcfg(p) \
((firstconfig_t *) ((char *) (p) - offsetof(firstconfig_t, config1)))
#define fcfg2cfg(p) (&(p)->config1)
/* Variables used while building data. */
static configfile_t *c_files; /* List of (included) config files. */
static int c_flags; /* Flags argument of config_read(). */
static FILE *c_fp; /* Current open file. */
static char *c_file; /* Current open file name. */
static unsigned c_line; /* Current line number. */
static int c; /* Next character. */
static void *allocate(void *mem, size_t size)
/* Like realloc(), but checked. */
{
if ((mem= realloc(mem, size)) == nil) {
fprintf(stderr, "\"%s\", line %u: Out of memory\n", c_file, c_line);
exit(1);
}
return mem;
}
#define deallocate(mem) free(mem)
static void delete_filelist(configfile_t *cfgf)
/* Delete configuration file list. */
{
void *junk;
while (cfgf != nil) {
junk= cfgf;
cfgf= cfgf->next;
deallocate(junk);
}
}
static void delete_config(config_t *cfg)
/* Delete configuration file data. */
{
config_t *next, *list, *junk;
next= cfg;
list= nil;
for (;;) {
if (next != nil) {
/* Push the 'next' chain in reverse on the 'list' chain, putting
* a leaf cell (next == nil) on top of 'list'.
*/
junk= next;
next= next->next;
junk->next= list;
list= junk;
} else
if (list != nil) {
/* Delete the leaf cell. If it has a sublist then that becomes
* the 'next' chain.
*/
junk= list;
next= list->list;
list= list->next;
deallocate(junk);
} else {
/* Both chains are gone. */
break;
}
}
}
void config_delete(config_t *cfg1)
/* Delete configuration file data, being careful with the odd first one. */
{
firstconfig_t *fcfg= cfg2fcfg(cfg1);
delete_filelist(fcfg->filelist);
delete_config(fcfg->config1.next);
delete_config(fcfg->config1.list);
deallocate(fcfg);
}
static void nextc(void)
/* Read the next character of the current file into 'c'. */
{
if (c == '\n') c_line++;
c= getc(c_fp);
if (c == EOF && ferror(c_fp)) {
fprintf(stderr, "\"%s\", line %u: %s\n",
c_file, c_line, strerror(errno));
exit(1);
}
}
static void skipwhite(void)
/* Skip whitespace and comments. */
{
while (isspace(c)) {
nextc();
if (c == '#') {
do nextc(); while (c != EOF && c != '\n');
}
}
}
static void parse_err(void)
/* Tell user that you can't parse past the current character. */
{
char sc[2];
sc[0]= c;
sc[1]= 0;
fprintf(stderr, "\"%s\", line %u: parse error at '%s'\n",
c_file, c_line, c == EOF ? "EOF" : sc);
exit(1);
}
static config_t *read_word(void)
/* Read a word or string. */
{
config_t *w;
size_t i, len;
int q;
static char SPECIAL[] = "!#$%&*+-./:<=>?[\\]^_|~";
i= 0;
len= 32;
w= allocate(nil, configsize(32));
w->next= nil;
w->list= nil;
w->file= c_file;
w->line= c_line;
w->flags= 0;
/* Is it a quoted string? */
if (c == '\'' || c == '"') {
q= c; /* yes */
nextc();
} else {
q= -1; /* no */
}
for (;;) {
if (i == len) {
len+= 32;
w= allocate(w, configsize(len));
}
if (q == -1) {
/* A word consists of letters, numbers and a few special chars. */
if (!isalnum(c) && c < 0x80 && strchr(SPECIAL, c) == nil) break;
} else {
/* Strings are made up of anything except newlines. */
if (c == EOF || c == '\n') {
fprintf(stderr,
"\"%s\", line %u: string at line %u not closed\n",
c_file, c_line, w->line);
exit(1);
break;
}
if (c == q) { /* Closing quote? */
nextc();
break;
}
}
if (c != '\\') { /* Simply add non-escapes. */
w->word[i++]= c;
nextc();
} else { /* Interpret an escape. */
nextc();
if (isspace(c)) {
skipwhite();
continue;
}
if (c_flags & CFG_ESCAPED) {
w->word[i++]= '\\'; /* Keep the \ for the caller. */
if (i == len) {
len+= 32;
w= allocate(w, configsize(len));
}
w->flags |= CFG_ESCAPED;
}
if (isdigit(c)) { /* Octal escape */
int n= 3;
int d= 0;
do {
d= d * 010 + (c - '0');
nextc();
} while (--n > 0 && isdigit(c));
w->word[i++]= d;
} else
if (c == 'x' || c == 'X') { /* Hex escape */
int n= 2;
int d= 0;
nextc();
if (!isxdigit(c)) {
fprintf(stderr, "\"%s\", line %u: bad hex escape\n",
c_file, c_line);
exit(1);
}
do {
d= d * 0x10 + (islower(c) ? (c - 'a' + 0xa) :
isupper(c) ? (c - 'A' + 0xA) :
(c - '0'));
nextc();
} while (--n > 0 && isxdigit(c));
w->word[i++]= d;
} else {
switch (c) {
case 'a': c= '\a'; break;
case 'b': c= '\b'; break;
case 'e': c= '\033'; break;
case 'f': c= '\f'; break;
case 'n': c= '\n'; break;
case 'r': c= '\r'; break;
case 's': c= ' '; break;
case 't': c= '\t'; break;
case 'v': c= '\v'; break;
default: /* Anything else is kept as-is. */;
}
w->word[i++]= c;
nextc();
}
}
}
w->word[i]= 0;
if (q != -1) {
w->flags |= CFG_STRING;
} else {
int f;
char *end;
static char base[]= { 0, 010, 10, 0x10 };
if (i == 0) parse_err();
/* Can the word be used as a number? */
for (f= 0; f < 4; f++) {
(void) strtol(w->word, &end, base[f]);
if (*end == 0) w->flags |= 1 << (f + 0);
(void) strtoul(w->word, &end, base[f]);
if (*end == 0) w->flags |= 1 << (f + 4);
}
}
return allocate(w, configsize(i));
}
static config_t *read_file(const char *file);
static config_t *read_list(void);
static config_t *read_line(void)
/* Read and return one line of the config file. */
{
config_t *cline, **pcline, *clist;
cline= nil;
pcline= &cline;
for (;;) {
skipwhite();
if (c == EOF || c == '}') {
if(0) if (cline != nil) parse_err();
break;
} else
if (c == ';') {
nextc();
if (cline != nil) break;
} else
if (cline != nil && c == '{') {
/* A sublist. */
nextc();
clist= allocate(nil, config0size());
clist->next= nil;
clist->file= c_file;
clist->line= c_line;
clist->list= read_list();
clist->flags= CFG_SUBLIST;
*pcline= clist;
pcline= &clist->next;
if (c != '}') parse_err();
nextc();
} else {
*pcline= read_word();
pcline= &(*pcline)->next;
}
}
return cline;
}
static config_t *read_list(void)
/* Read and return a list of config file commands. */
{
config_t *clist, **pclist, *cline;
clist= nil;
pclist= &clist;
while ((cline= read_line()) != nil) {
if (strcmp(cline->word, "include") == 0) {
config_t *file= cline->next;
if (file == nil || file->next != nil || !config_isatom(file)) {
fprintf(stderr,
"\"%s\", line %u: 'include' command requires an argument\n",
c_file, cline->line);
exit(1);
}
if (file->flags & CFG_ESCAPED) {
char *p, *q;
p= q= file->word;
for (;;) {
if ((*q = *p) == '\\') *q = *++p;
if (*q == 0) break;
p++;
q++;
}
}
file= read_file(file->word);
delete_config(cline);
*pclist= file;
while (*pclist != nil) pclist= &(*pclist)->next;
} else {
config_t *cfg= allocate(nil, config0size());
cfg->next= nil;
cfg->list= cline;
cfg->file= cline->file;
cfg->line= cline->line;
cfg->flags= CFG_SUBLIST;
*pclist= cfg;
pclist= &cfg->next;
}
}
return clist;
}
static config_t *read_file(const char *file)
/* Read and return a configuration file. */
{
configfile_t *cfgf;
config_t *cfg;
struct stat st;
FILE *old_fp; /* old_* variables store current file context. */
char *old_file;
unsigned old_line;
int old_c;
size_t n;
char *slash;
old_fp= c_fp;
old_file= c_file;
old_line= c_line;
old_c= c;
n= 0;
if (file[0] != '/' && old_file != nil
&& (slash= strrchr(old_file, '/')) != nil) {
n= slash - old_file + 1;
}
cfgf= allocate(nil, configfilesize(n + strlen(file)));
memcpy(cfgf->name, old_file, n);
strcpy(cfgf->name + n, file);
cfgf->next= c_files;
c_files= cfgf;
c_file= cfgf->name;
c_line= 0;
if ((c_fp= fopen(file, "r")) == nil || fstat(fileno(c_fp), &st) < 0) {
if (errno != ENOENT) {
fprintf(stderr, "\"%s\", line 1: %s\n", file, strerror(errno));
exit(1);
}
cfgf->ctime= -1;
c= EOF;
} else {
cfgf->ctime= st.st_ctime;
c= '\n';
}
cfg= read_list();
if (c != EOF) parse_err();
if (c_fp != nil) fclose(c_fp);
c_fp= old_fp;
c_file= old_file;
c_line= old_line;
c= old_c;
return cfg;
}
config_t *config_read(const char *file, int flags, config_t *cfg)
/* Read and parse a configuration file. */
{
if (cfg != nil) {
/* First check if any of the involved files has changed. */
firstconfig_t *fcfg;
configfile_t *cfgf;
struct stat st;
fcfg= cfg2fcfg(cfg);
for (cfgf= fcfg->filelist; cfgf != nil; cfgf= cfgf->next) {
if (stat(cfgf->name, &st) < 0) {
if (errno != ENOENT) break;
st.st_ctime= -1;
}
if (st.st_ctime != cfgf->ctime) break;
}
if (cfgf == nil) return cfg; /* Everything as it was. */
config_delete(cfg); /* Otherwise delete and reread. */
}
errno= 0;
c_files= nil;
c_flags= flags;
cfg= read_file(file);
if (cfg != nil) {
/* Change first word to have a hidden pointer to a file list. */
size_t len= strlen(cfg->word);
firstconfig_t *fcfg;
fcfg= allocate(cfg, firstconfigsize(len));
memmove(&fcfg->config1, fcfg, configsize(len));
fcfg->filelist= c_files;
fcfg->new= 1;
return fcfg2cfg(fcfg);
}
/* Couldn't read (errno != 0) of nothing read (errno == 0). */
delete_filelist(c_files);
delete_config(cfg);
return nil;
}
int config_renewed(config_t *cfg)
{
int new;
if (cfg == nil) {
new= 1;
} else {
new= cfg2fcfg(cfg)->new;
cfg2fcfg(cfg)->new= 0;
}
return new;
}
size_t config_length(config_t *cfg)
/* Count the number of items on a list. */
{
size_t n= 0;
while (cfg != nil) {
n++;
cfg= cfg->next;
}
return n;
}
#if TEST
#include <unistd.h>
static void print_list(int indent, config_t *cfg);
static void print_words(int indent, config_t *cfg)
{
while (cfg != nil) {
if (config_isatom(cfg)) {
if (config_isstring(cfg)) fputc('"', stdout);
printf("%s", cfg->word);
if (config_isstring(cfg)) fputc('"', stdout);
} else {
printf("{\n");
print_list(indent+4, cfg->list);
printf("%*s}", indent, "");
}
cfg= cfg->next;
if (cfg != nil) fputc(' ', stdout);
}
printf(";\n");
}
static void print_list(int indent, config_t *cfg)
{
while (cfg != nil) {
if (!config_issub(cfg)) {
fprintf(stderr, "Cell at \"%s\", line %u is not a sublist\n");
break;
}
printf("%*s", indent, "");
print_words(indent, cfg->list);
cfg= cfg->next;
}
}
static void print_config(config_t *cfg)
{
if (!config_renewed(cfg)) {
printf("# Config didn't change\n");
} else {
print_list(0, cfg);
}
}
int main(int argc, char **argv)
{
config_t *cfg;
int c;
if (argc != 2) {
fprintf(stderr, "One config file name please\n");
exit(1);
}
cfg= nil;
do {
cfg= config_read(argv[1], CFG_ESCAPED, cfg);
print_config(cfg);
if (!isatty(0)) break;
while ((c= getchar()) != EOF && c != '\n') {}
} while (c != EOF);
return 0;
}
#endif /* TEST */

View file

@ -0,0 +1,115 @@
/* crypt() - one-way password encryption function Author: Kees J. Bot
* 7 Feb 1994
* This routine does not encrypt anything, it uses the pwdauth
* program to do the hard work.
*/
#define nil ((void*)0)
#define pipe _pipe
#define fork _fork
#define close _close
#define dup2 _dup2
#define execl _execl
#define read _read
#define _exit __exit
#define write _write
#define waitpid _waitpid
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <stdarg.h>
#include <sys/wait.h>
/* Set-uid root program to read /etc/shadow or encrypt passwords. */
static char PWDAUTH[] = "/usr/lib/pwdauth";
#define LEN 1024
static void tell(const char *s0, ...)
{
va_list ap;
const char *s;
va_start(ap, s0);
s= s0;
while (s != nil) {
(void) write(2, s, strlen(s));
s= va_arg(ap, const char *);
}
va_end(ap);
}
char *crypt(const char *key, const char *salt)
{
pid_t pid;
int status;
int pfd[2];
static char pwdata[LEN];
char *p= pwdata;
const char *k= key;
const char *s= salt;
int n;
/* Fill pwdata[] with the key and salt. */
while ((*p++ = *k++) != 0) if (p == pwdata+LEN-1) goto fail;
while ((*p++ = *s++) != 0) if (p == pwdata+LEN-0) goto fail;
if (pipe(pfd) < 0) goto fail;
/* Prefill the pipe. */
(void) write(pfd[1], pwdata, p - pwdata);
switch ((pid= fork())) {
case -1:
close(pfd[0]);
close(pfd[1]);
goto fail;
case 0:
/* Connect both input and output to the pipe. */
if (pfd[0] != 0) {
dup2(pfd[0], 0);
close(pfd[0]);
}
if (pfd[1] != 1) {
dup2(pfd[1], 1);
close(pfd[1]);
}
execl(PWDAUTH, PWDAUTH, (char *) nil);
tell("crypt(): ", PWDAUTH, ": ", strerror(errno), "\r\n",
(char *) nil);
/* No pwdauth? Fail! */
(void) read(0, pwdata, LEN);
_exit(1);
}
close(pfd[1]);
status= -1;
while (waitpid(pid, &status, 0) == -1 && errno == EINTR) {}
if (status != 0) {
close(pfd[0]);
goto fail;
}
/* Read and return the result. Check if it contains exactly one
* string.
*/
n= read(pfd[0], pwdata, LEN);
close(pfd[0]);
if (n < 0) goto fail;
p = pwdata + n;
n = 0;
while (p > pwdata) if (*--p == 0) n++;
if (n != 1) goto fail;
return pwdata;
fail:
pwdata[0] = salt[0] ^ 1; /* make result != salt */
pwdata[1] = 0;
return pwdata;
}
/*
* $PchId: crypt.c,v 1.5 1996/04/11 07:46:11 philip Exp $
*/

View file

@ -0,0 +1,33 @@
/* cuserid(3)
*
* Author: Terrence W. Holm Sept. 1987
*/
#include <lib.h>
#include <pwd.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#ifndef L_cuserid
#define L_cuserid 9
#endif
char *cuserid(user_name)
char *user_name;
{
PRIVATE char userid[L_cuserid];
struct passwd *pw_entry;
if (user_name == (char *)NULL) user_name = userid;
pw_entry = getpwuid(geteuid());
if (pw_entry == (struct passwd *)NULL) {
*user_name = '\0';
return((char *)NULL);
}
strcpy(user_name, pw_entry->pw_name);
return(user_name);
}

View file

@ -0,0 +1,50 @@
/*
ttyslot.c
Return the index in the utmp file for the current user's terminal. The
current user's terminal is the first file descriptor in the range 0..2
for which ttyname() returns a name. The index is the line number in the
/etc/ttytab file. 0 will be returned in case of an error.
Created: Oct 11, 1992 by Philip Homburg
*/
#include <sys/types.h>
#include <ttyent.h>
#include <string.h>
#include <unistd.h>
int fttyslot(fd)
int fd;
{
char *tname;
int lineno;
struct ttyent *ttyp;
tname= ttyname(fd);
if (tname == NULL) return 0;
/* Assume that tty devices are in /dev */
if (strncmp(tname, "/dev/", 5) != 0)
return 0; /* Malformed tty name. */
tname += 5;
/* Scan /etc/ttytab. */
lineno= 1;
while ((ttyp= getttyent()) != NULL)
{
if (strcmp(tname, ttyp->ty_name) == 0)
{
endttyent();
return lineno;
}
lineno++;
}
/* No match */
endttyent();
return 0;
}
/*
* $PchHeader: /mount/hd2/minix/lib/misc/RCS/ttyslot.c,v 1.3 1994/12/22 13:49:12 philip Exp $
*/

View file

@ -0,0 +1,156 @@
/* getpwent(), getpwuid(), getpwnam() - password file routines
*
* Author: Kees J. Bot
* 31 Jan 1994
*/
#include <sys/types.h>
#include <compat/pwd.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#define arraysize(a) (sizeof(a) / sizeof((a)[0]))
#define arraylimit(a) ((a) + arraysize(a))
static char PASSWD[]= "/etc/passwd"; /* The password file. */
static const char *pwfile; /* Current password file. */
static char buf[1024]; /* Read buffer. */
static char pwline[256]; /* One line from the password file. */
static struct passwd entry; /* Entry to fill and return. */
static int pwfd= -1; /* Filedescriptor to the file. */
static char *bufptr; /* Place in buf. */
static ssize_t buflen= 0; /* Remaining characters in buf. */
static char *lineptr; /* Place in the line. */
void endpwent(void)
/* Close the password file. */
{
if (pwfd >= 0) {
(void) close(pwfd);
pwfd= -1;
buflen= 0;
}
}
int setpwent(void)
/* Open the password file. */
{
if (pwfd >= 0) endpwent();
if (pwfile == NULL) pwfile= PASSWD;
if ((pwfd= open(pwfile, O_RDONLY)) < 0) return -1;
(void) fcntl(pwfd, F_SETFD, fcntl(pwfd, F_GETFD) | FD_CLOEXEC);
return 0;
}
void setpwfile(const char *file)
/* Prepare for reading an alternate password file. */
{
endpwent();
pwfile= file;
}
static int getline(void)
/* Get one line from the password file, return 0 if bad or EOF. */
{
lineptr= pwline;
do {
if (buflen == 0) {
if ((buflen= read(pwfd, buf, sizeof(buf))) <= 0)
return 0;
bufptr= buf;
}
if (lineptr == arraylimit(pwline)) return 0;
buflen--;
} while ((*lineptr++ = *bufptr++) != '\n');
lineptr= pwline;
return 1;
}
static char *scan_colon(void)
/* Scan for a field separator in a line, return the start of the field. */
{
char *field= lineptr;
char *last;
for (;;) {
last= lineptr;
if (*lineptr == 0) return NULL;
if (*lineptr == '\n') break;
if (*lineptr++ == ':') break;
}
*last= 0;
return field;
}
struct passwd *getpwent(void)
/* Read one entry from the password file. */
{
char *p;
/* Open the file if not yet open. */
if (pwfd < 0 && setpwent() < 0) return NULL;
/* Until a good line is read. */
for (;;) {
if (!getline()) return NULL; /* EOF or corrupt. */
if ((entry.pw_name= scan_colon()) == NULL) continue;
if ((entry.pw_passwd= scan_colon()) == NULL) continue;
if ((p= scan_colon()) == NULL) continue;
entry.pw_uid= strtol(p, NULL, 0);
if ((p= scan_colon()) == NULL) continue;
entry.pw_gid= strtol(p, NULL, 0);
if ((entry.pw_gecos= scan_colon()) == NULL) continue;
if ((entry.pw_dir= scan_colon()) == NULL) continue;
if ((entry.pw_shell= scan_colon()) == NULL) continue;
if (*lineptr == 0) return &entry;
}
}
struct passwd *getpwuid(uid_t uid)
/* Return the password file entry belonging to the user-id. */
{
struct passwd *pw;
endpwent();
while ((pw= getpwent()) != NULL && pw->pw_uid != uid) {}
endpwent();
return pw;
}
struct passwd *getpwnam(const char *name)
/* Return the password file entry belonging to the user name. */
{
struct passwd *pw;
endpwent();
while ((pw= getpwent()) != NULL && strcmp(pw->pw_name, name) != 0) {}
endpwent();
return pw;
}
#ifndef L_cuserid
#define L_cuserid 9
#endif
char *getlogin()
{
static char userid[L_cuserid];
struct passwd *pw_entry;
pw_entry = getpwuid(getuid());
if (pw_entry == (struct passwd *)NULL) return((char *)NULL);
strcpy(userid, pw_entry->pw_name);
return(userid);
}

View file

@ -0,0 +1,8 @@
.PATH: ${MINIXSRCDIR}/lib/nbsd_libcompat_minix/include
INCSDIR= /usr/netbsd/include
INCS+= configfile.h termcap.h
INCS+= compat/a.out.h compat/regexp.h compat/syslog.h \
compat/pwd.h

View file

@ -0,0 +1,118 @@
/* The <a.out> header file describes the format of executable files. */
#ifndef _AOUT_H
#define _AOUT_H
struct exec { /* a.out header */
unsigned char a_magic[2]; /* magic number */
unsigned char a_flags; /* flags, see below */
unsigned char a_cpu; /* cpu id */
unsigned char a_hdrlen; /* length of header */
unsigned char a_unused; /* reserved for future use */
unsigned short a_version; /* version stamp (not used at present) */
long a_text; /* size of text segement in bytes */
long a_data; /* size of data segment in bytes */
long a_bss; /* size of bss segment in bytes */
long a_entry; /* entry point */
long a_total; /* total memory allocated */
long a_syms; /* size of symbol table */
/* SHORT FORM ENDS HERE */
long a_trsize; /* text relocation size */
long a_drsize; /* data relocation size */
long a_tbase; /* text relocation base */
long a_dbase; /* data relocation base */
};
#define A_MAGIC0 (unsigned char) 0x01
#define A_MAGIC1 (unsigned char) 0x03
#define BADMAG(X) ((X).a_magic[0] != A_MAGIC0 ||(X).a_magic[1] != A_MAGIC1)
/* CPU Id of TARGET machine (byte order coded in low order two bits) */
#define A_NONE 0x00 /* unknown */
#define A_I8086 0x04 /* intel i8086/8088 */
#define A_M68K 0x0B /* motorola m68000 */
#define A_NS16K 0x0C /* national semiconductor 16032 */
#define A_I80386 0x10 /* intel i80386 */
#define A_SPARC 0x17 /* Sun SPARC */
#define A_BLR(cputype) ((cputype&0x01)!=0) /* TRUE if bytes left-to-right */
#define A_WLR(cputype) ((cputype&0x02)!=0) /* TRUE if words left-to-right */
/* Flags. */
#define A_UZP 0x01 /* unmapped zero page (pages) */
#define A_PAL 0x02 /* page aligned executable */
#define A_NSYM 0x04 /* new style symbol table */
#define A_IMG 0x08 /* image instead of executable (e.g. root FS) */
#define A_EXEC 0x10 /* executable */
#define A_SEP 0x20 /* separate I/D */
#define A_PURE 0x40 /* pure text */ /* not used */
#define A_TOVLY 0x80 /* text overlay */ /* not used */
/* Offsets of various things. */
#define A_MINHDR 32
#define A_TEXTPOS(X) ((long)(X).a_hdrlen)
#define A_DATAPOS(X) (A_TEXTPOS(X) + (X).a_text)
#define A_HASRELS(X) ((X).a_hdrlen > (unsigned char) A_MINHDR)
#define A_HASEXT(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 8))
#define A_HASLNS(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 16))
#define A_HASTOFF(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 24))
#define A_TRELPOS(X) (A_DATAPOS(X) + (X).a_data)
#define A_DRELPOS(X) (A_TRELPOS(X) + (X).a_trsize)
#define A_SYMPOS(X) (A_TRELPOS(X) + (A_HASRELS(X) ? \
((X).a_trsize + (X).a_drsize) : 0))
struct reloc {
long r_vaddr; /* virtual address of reference */
unsigned short r_symndx; /* internal segnum or extern symbol num */
unsigned short r_type; /* relocation type */
};
/* r_type values: */
#define R_ABBS 0
#define R_RELLBYTE 2
#define R_PCRBYTE 3
#define R_RELWORD 4
#define R_PCRWORD 5
#define R_RELLONG 6
#define R_PCRLONG 7
#define R_REL3BYTE 8
#define R_KBRANCHE 9
/* r_symndx for internal segments */
#define S_ABS ((unsigned short)-1)
#define S_TEXT ((unsigned short)-2)
#define S_DATA ((unsigned short)-3)
#define S_BSS ((unsigned short)-4)
struct nlist { /* symbol table entry */
char n_name[8]; /* symbol name */
long n_value; /* value */
unsigned char n_sclass; /* storage class */
unsigned char n_numaux; /* number of auxiliary entries (not used) */
unsigned short n_type; /* language base and derived type (not used) */
};
/* Low bits of storage class (section). */
#define N_SECT 07 /* section mask */
#define N_UNDF 00 /* undefined */
#define N_ABS 01 /* absolute */
#define N_TEXT 02 /* text */
#define N_DATA 03 /* data */
#define N_BSS 04 /* bss */
#define N_COMM 05 /* (common) */
/* High bits of storage class. */
#define N_CLASS 0370 /* storage class mask */
#define C_NULL
#define C_EXT 0020 /* external symbol */
#define C_STAT 0030 /* static */
/* Function prototypes. */
#ifndef _MINIX_ANSI_H
#include <minix/ansi.h>
#endif
_PROTOTYPE( int nlist, (char *_file, struct nlist *_nl) );
#endif /* _AOUT_H */

View file

@ -0,0 +1,34 @@
/* The <pwd.h> header defines the items in the password file. */
#ifndef _PWD_H
#define _PWD_H
#ifndef _TYPES_H
#include <minix/types.h>
#endif
struct passwd {
char *pw_name; /* login name */
uid_t pw_uid; /* uid corresponding to the name */
gid_t pw_gid; /* gid corresponding to the name */
char *pw_dir; /* user's home directory */
char *pw_shell; /* name of the user's shell */
/* The following members are not defined by POSIX. */
char *pw_passwd; /* password information */
char *pw_gecos; /* just in case you have a GE 645 around */
};
/* Function Prototypes. */
_PROTOTYPE( struct passwd *getpwnam, (const char *_name) );
_PROTOTYPE( struct passwd *getpwuid, (uid_t _uid) );
#ifdef _MINIX
_PROTOTYPE( void endpwent, (void) );
_PROTOTYPE( struct passwd *getpwent, (void) );
_PROTOTYPE( int setpwent, (void) );
_PROTOTYPE( void setpwfile, (const char *_file) );
_PROTOTYPE( const char *user_from_uid, (uid_t, int) );
#endif
#endif /* _PWD_H */

View file

@ -0,0 +1,37 @@
/* The <regexp.h> header is used by the (V8-compatible) regexp(3) routines. */
/* NOTE: Obsoleted by the POSIX regex(3) library. */
#ifndef _REGEXP_H
#define _REGEXP_H
#include <sys/cdefs.h>
#define CHARBITS 0377
#define NSUBEXP 10
typedef struct regexp {
const char *startp[NSUBEXP];
const char *endp[NSUBEXP];
char regstart; /* Internal use only. */
char reganch; /* Internal use only. */
char *regmust; /* Internal use only. */
int regmlen; /* Internal use only. */
char program[1]; /* Unwarranted chumminess with compiler. */
} regexp;
/* Keep these functions away from the POSIX versions. */
#define regcomp _v8_regcomp
#define regexec _v8_regexec
#define regsub _v8_regsub
#define regerror _v8_regerror
/* Function Prototypes. */
regexp *regcomp(const char *_exp);
int regexec(regexp *_prog, const char *_string, int _bolflag);
void regsub(regexp *_prog, char *_source, char *_dest);
void regerror(const char *_message) ;
#endif /* _REGEXP_H */
/*
* $PchId: regexp.h,v 1.4 1996/04/10 21:43:17 philip Exp $
*/

View file

@ -0,0 +1,8 @@
#ifndef _COMPAT_SYSLOG_H
#define _COMPAT_SYSLOG_H
#include <syslog.h>
#define FacNames facilitynames
#define PriNames prioritynames
#endif

View file

@ -0,0 +1,44 @@
/* configfile.h - Generic configuration file format.
* Author: Kees J. Bot
* 5 Jun 1999
*/
#ifndef _CONFIGFILE_H
#define _CONFIGFILE_H
/* Data can only be modified inside the library. */
#ifndef _c
#define _c const
#endif
typedef _c struct config { /* Contents of a generic configuration file. */
_c struct config *next; /* Next configuration file thing. */
_c struct config *list; /* For a { sublist }. */
const char *file; /* File and line where this is found. */
unsigned line;
int flags; /* Special flags. */
char word[1]; /* Payload. */
} config_t;
#define CFG_CLONG 0x0001 /* strtol(word, &end, 0) is valid. */
#define CFG_OLONG 0x0002 /* strtol(word, &end, 010). */
#define CFG_DLONG 0x0004 /* strtol(word, &end, 10). */
#define CFG_XLONG 0x0008 /* strtol(word, &end, 0x10). */
#define CFG_CULONG 0x0010 /* strtoul(word, &end, 0). */
#define CFG_OULONG 0x0020 /* strtoul(word, &end, 010). */
#define CFG_DULONG 0x0040 /* strtoul(word, &end, 10). */
#define CFG_XULONG 0x0080 /* strtoul(word, &end, 0x10). */
#define CFG_STRING 0x0100 /* The word is enclosed in quotes. */
#define CFG_SUBLIST 0x0200 /* This is a sublist, so no word. */
#define CFG_ESCAPED 0x0400 /* Escapes are still marked with \. */
config_t *config_read(const char *_file, int flags, config_t *_cfg);
void config_delete(config_t *_cfg);
int config_renewed(config_t *_cfg);
size_t config_length(config_t *_cfg);
#define config_issub(cfg) (!!((cfg)->flags & CFG_SUBLIST))
#define config_isatom(cfg) (!config_issub(cfg))
#define config_isstring(cfg) (!!((cfg)->flags & CFG_STRING))
#undef _c
#endif /* _CONFIGFILE_H */

View file

@ -0,0 +1,13 @@
#ifndef _TERMCAP_H
#define _TERMCAP_H
#include <minix/ansi.h>
_PROTOTYPE( int tgetent, (char *_bp, char *_name) );
_PROTOTYPE( int tgetflag, (char *_id) );
_PROTOTYPE( int tgetnum, (char *_id) );
_PROTOTYPE( char *tgetstr, (char *_id, char **_area) );
_PROTOTYPE( char *tgoto, (char *_cm, int _destcol, int _destline) );
_PROTOTYPE( int tputs, (char *_cp, int _affcnt, void (*_outc)(int)) );
#endif /* _TERMCAP_H */

View file

@ -0,0 +1,205 @@
/* This package consists of 4 routines for handling the /etc/mtab file.
* The /etc/mtab file contains information about the root and mounted file
* systems as a series of lines, each one with exactly four fields separated
* by one space as follows:
*
* special mounted_on version rw_flag
*
* where
* special is the name of the block special file
* mounted_on is the directory on which it is mounted
* version is either 1 or 2 for MINIX V1 and V2 file systems
* rw_flag is rw or ro for read/write or read only
*
* An example /etc/mtab:
*
* /dev/ram / 2 rw
* /dev/hd1 /usr 2 rw
* /dev/fd0 /user 1 ro
*
*
* The four routines for handling /etc/mtab are as follows. They use two
* (hidden) internal buffers, mtab_in for input and mtab_out for output.
*
* load_mtab(&prog_name) - read /etc/mtab into mtab_in
* get_mtab_entry(&s1, &s2, &s3, &s4) - arrays that are filled in
* put_mtab_entry(&s1, &s2, &s3, &s4) - append a line to mtab_out
* rewrite_mtab(&prog_name) - write mtab_out to /etc/mtab
*
* If load_mtab and rewrite_mtab work, they return 0. If they fail, they
* print their own error messages on stderr and return -1. When get_mtab_entry
* runs out of entries to return, it sets the first pointer to NULL and returns
* -1 instead of 0. Also, rewrite_mtab returns -1 if it fails.
*/
#include <sys/types.h>
#include <minix/minlib.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#define BUF_SIZE 512 /* size of the /etc/mtab buffer */
char *etc_mtab = "/etc/mtab"; /* name of the /etc/mtab file */
static char mtab_in[BUF_SIZE+1]; /* holds /etc/mtab when it is read in */
static char mtab_out[BUF_SIZE+1]; /* buf to build /etc/mtab for output later */
static char *iptr = mtab_in; /* pointer to next line to feed out. */
static char *optr = mtab_out; /* pointer to place where next line goes */
_PROTOTYPE(int load_mtab, (char *prog_name ));
_PROTOTYPE(int rewrite_mtab, (char *prog_name ));
_PROTOTYPE(int get_mtab_entry, (char *special, char *mounted_on,
char *version, char *rw_flag));
_PROTOTYPE(int put_mtab_entry, (char *special, char *mounted_on,
char *version, char *rw_flag));
_PROTOTYPE(void err, (char *prog_name, char *str ));
int load_mtab(prog_name)
char *prog_name;
{
/* Read in /etc/mtab and store it in /etc/mtab. */
int fd, n;
char *ptr;
/* Open the file. */
fd = open(etc_mtab, O_RDONLY);
if (fd < 0) {
err(prog_name, ": cannot open ");
return(-1);
}
/* File opened. Read it in. */
n = read(fd, mtab_in, BUF_SIZE);
if (n <= 0) {
/* Read failed. */
err(prog_name, ": cannot read ");
return(-1);
}
if (n == BUF_SIZE) {
/* Some nut has mounted 50 file systems or something like that. */
std_err(prog_name);
std_err(": file too large: ");
std_err(etc_mtab);
return(-1);
}
close(fd);
/* Replace all the whitespace by '\0'. */
ptr = mtab_in;
while (*ptr != '\0') {
if (isspace(*ptr)) *ptr = '\0';
ptr++;
}
return(0);
}
int rewrite_mtab(prog_name)
char *prog_name;
{
/* Write mtab_out to /etc/mtab. */
int fd, n;
/* Do a creat to truncate the file. */
fd = creat(etc_mtab, 0777);
if (fd < 0) {
err(prog_name, ": cannot overwrite ");
return(-1);
}
/* File created. Write it. */
n = write(fd, mtab_out, (unsigned int)(optr - mtab_out));
if (n <= 0) {
/* Write failed. */
err(prog_name, " could not write ");
return(-1);
}
close(fd);
return(0);
}
int get_mtab_entry(special, mounted_on, version, rw_flag)
char *special;
char *mounted_on;
char *version;
char *rw_flag;
{
/* Return the next entry from mtab_in. */
if (iptr >= &mtab_in[BUF_SIZE]) {
special[0] = '\0';
return(-1);
}
strcpy(special, iptr);
while (isprint(*iptr)) iptr++;
while (*iptr == '\0'&& iptr < &mtab_in[BUF_SIZE]) iptr++;
strcpy(mounted_on, iptr);
while (isprint(*iptr)) iptr++;
while (*iptr == '\0'&& iptr < &mtab_in[BUF_SIZE]) iptr++;
strcpy(version, iptr);
while (isprint(*iptr)) iptr++;
while (*iptr == '\0'&& iptr < &mtab_in[BUF_SIZE]) iptr++;
strcpy(rw_flag, iptr);
while (isprint(*iptr)) iptr++;
while (*iptr == '\0'&& iptr < &mtab_in[BUF_SIZE]) iptr++;
return(0);
}
int put_mtab_entry(special, mounted_on, version, rw_flag)
char *special;
char *mounted_on;
char *version;
char *rw_flag;
{
/* Append an entry to the mtab_out buffer. */
int n1, n2, n3, n4;
n1 = strlen(special);
n2 = strlen(mounted_on);
n3 = strlen(version);
n4 = strlen(rw_flag);
if (optr + n1 + n2 + n3 + n4 + 5 >= &mtab_out[BUF_SIZE]) return(-1);
strcpy(optr, special);
optr += n1;
*optr++ = ' ';
strcpy(optr, mounted_on);
optr += n2;
*optr++ = ' ';
strcpy(optr, version);
optr += n3;
*optr++ = ' ';
strcpy(optr, rw_flag);
optr += n4;
*optr++ = '\n';
return(0);
}
void
err(prog_name, str)
char *prog_name, *str;
{
std_err(prog_name);
std_err(str);
std_err(etc_mtab);
perror(" ");
}

View file

@ -0,0 +1,71 @@
/*
* "nlist.c", Peter Valkenburg, january 1989.
*/
#include <lib.h>
#include <string.h>
#include <a.out.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#define fail(fp) (fclose(fp), -1) /* ret. exp. when nlist fails */
_PROTOTYPE( int nlist, (char *file, struct nlist nl[]));
/*
* Nlist fills fields n_sclass and n_value of array nl with values found in
* non-stripped executable file. Entries that are not found have their
* n_value/n_sclass fields set to 0. Nl ends with a 0 or nul string n_name.
* The return value is -1 on failure, else the number of entries not found.
*/
int nlist(file, nl)
char *file;
struct nlist nl[];
{
int nents, nsrch, nfound, i;
struct nlist nlent;
FILE *fp;
struct exec hd;
/* open executable with namelist */
if ((fp = fopen(file, "r")) == NULL)
return -1;
/* get header and seek to start of namelist */
if (fread((char *) &hd, sizeof(struct exec), 1, fp) != 1 ||
BADMAG(hd) || fseek(fp, A_SYMPOS(hd), SEEK_SET) != 0)
return fail(fp);
/* determine number of entries searched for & reset fields */
nsrch = 0;
while (nl[nsrch].n_name != NULL && *(nl[nsrch].n_name) != '\0') {
nl[nsrch].n_sclass = 0;
nl[nsrch].n_value = 0;
nl[nsrch].n_type = 0; /* for compatability */
nsrch++;
}
/* loop through namelist & fill in user array */
nfound = 0;
for (nents = (hd.a_syms & 0xFFFF) / sizeof(struct nlist);
nents > 0; nents--) {
if (nsrch == nfound)
break; /* no need to look further */
if (fread((char *) &nlent, sizeof(struct nlist), 1, fp) != 1)
return fail(fp);
for (i = 0; i < nsrch; i++)
if (nl[i].n_sclass == 0 &&
strncmp(nl[i].n_name, nlent.n_name,
sizeof(nlent.n_name)) == 0) {
nl[i] = nlent;
nfound++;
break;
}
}
(void) fclose(fp);
return nsrch - nfound;
}

View file

@ -0,0 +1,11 @@
#include <lib.h>
#include <sys/types.h>
#include <unistd.h>
void std_err(const char *s)
{
register const char *p = s;
while (*p != 0) p++;
write(2, s, (int) (p - s));
}

View file

@ -0,0 +1,326 @@
/*
* termcap.c V1.1 20/7/87 agc Joypace Ltd
*
* Copyright Joypace Ltd, London, UK, 1987. All rights reserved.
* This file may be freely distributed provided that this notice
* remains attached.
*
* A public domain implementation of the termcap(3) routines.
*
*
*
* Klamer Schutte V1.2 Nov. 1988
*
* - Can match multiple terminal names [tgetent]
* - Removal of **area assignments [tgetstr]
*
* Terrence W. Holm V1.3 May, Sep, Oct. 1988
*
* - Correct when TERM != name and TERMCAP is defined [tgetent]
* - Correct the comparison for the terminal name [tgetent]
* - Correct the value of ^x escapes [tgetstr]
* - Added %r to reverse row/column [tgoto]
* - Fixed end of definition test [tgetnum/flag/str]
*
* Terrence W. Holm V1.4 Jan. 1989
*
* - Incorporated Klamer's V1.2 fixes into V1.3
* - Added %d, (old %d is now %2) [tgoto]
* - Allow '#' comments in definition file [tgetent]
*/
#include <sys/cdefs.h>
#include <lib.h>
#include <termcap.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
char *capab = (char *)NULL; /* the capability itself */
#if 0
/* The following are not yet used. */
extern short ospeed; /* output speed */
extern char PC; /* padding character */
extern char *BC; /* back cursor movement */
extern char *UP; /* up cursor movement */
#endif
/*
* tgetent - get the termcap entry for terminal name, and put it
* in bp (which must be an array of 1024 chars). Returns 1 if
* termcap entry found, 0 if not found, and -1 if file not found.
*/
int tgetent(bp, name)
char *bp;
char *name;
{
FILE *fp;
char *file;
char *term;
short len = strlen(name);
capab = bp;
/* If TERMCAP begins with a '/' then use TERMCAP as the path */
/* Name of the termcap definitions file. If TERMCAP is a */
/* Definition and TERM equals "name" then use TERMCAP as the */
/* Definition. Otherwise use "/etc/termcap" as the path name. */
if ((file = getenv("TERMCAP")) == (char *)NULL)
file = "/etc/termcap";
else if (*file != '/')
if ((term = getenv("TERM")) != (char *)NULL && strcmp(term, name) == 0) {
*bp = '\0';
strncat(bp, file, 1023);
return(1);
} else
file = "/etc/termcap";
if ((fp = fopen(file, "r")) == (FILE *) NULL) {
capab = (char *)NULL; /* no valid termcap */
return(-1);
}
for (;;) {
/* Read in each definition */
int def_len = 0;
char *cp = bp;
do {
if (fgets(&bp[def_len], (unsigned int)(1024 - def_len), fp) == (char *)NULL) {
fclose(fp);
capab = (char *)NULL; /* no valid termcap */
return(0);
}
def_len = strlen(bp) - 2;
} while (bp[def_len] == '\\');
while (isspace(*cp)) cp++;
/* Comment lines start with a '#' */
if (*cp == '#') continue;
/* See if any of the terminal names in this definition */
/* Match "name". */
do {
if (strncmp(name, cp, len) == 0 &&
(cp[len] == '|' || cp[len] == ':')) {
fclose(fp);
return(1);
}
while ((*cp) && (*cp != '|') && (*cp != ':')) cp++;
} while (*cp++ == '|');
}
}
/*
* tgetnum - get the numeric terminal capability corresponding
* to id. Returns the value, -1 if invalid.
*/
int tgetnum(id)
char *id;
{
register char *cp = capab;
if (cp == (char *)NULL || id == (char *)NULL) return(-1);
for (;;) {
while (*cp++ != ':')
if (cp[-1] == '\0') return(-1);
while (isspace(*cp)) cp++;
if (strncmp(cp, id, 2) == 0 && cp[2] == '#') return(atoi(cp + 3));
}
}
/*
* tgetflag - get the boolean flag corresponding to id. Returns -1
* if invalid, 0 if the flag is not in termcap entry, or 1 if it is
* present.
*/
int tgetflag(id)
char *id;
{
register char *cp = capab;
if (cp == (char *)NULL || id == (char *)NULL) return(-1);
for (;;) {
while (*cp++ != ':')
if (cp[-1] == '\0') return(0);
while (isspace(*cp)) cp++;
if (strncmp(cp, id, 2) == 0) return(1);
}
}
/*
* tgetstr - get the string capability corresponding to id and place
* it in area (advancing area at same time). Expand escape sequences
* etc. Returns the string, or NULL if it can't do it.
*/
char *tgetstr(id, area)
char *id;
char **area;
{
register char *cp = capab;
register char *wsp = *area; /* workspace pointer */
if (cp == (char *)NULL || id == (char *)NULL) return((char *)NULL);
for (;;) {
while (*cp++ != ':')
if (cp[-1] == '\0') return((char *)NULL);
while (isspace(*cp)) cp++;
if (strncmp(cp, id, 2) == 0 && cp[2] == '=') {
for (cp += 3; *cp && *cp != ':'; wsp++, cp++) switch (*cp) {
case '^':
*wsp = *++cp - '@';
break;
case '\\':
switch (*++cp) {
case 'E':
*wsp = '\033';
break;
case 'n':
*wsp = '\n';
break;
case 'r':
*wsp = '\r';
break;
case 't':
*wsp = '\t';
break;
case 'b':
*wsp = '\b';
break;
case 'f':
*wsp = '\f';
break;
case '0':
case '1':
case '2':
case '3':
{
int i;
int t = 0;
for (i = 0; i < 3 &&
isdigit(*cp); ++i, ++cp)
t = t * 8 + *cp - '0';
*wsp = t;
cp--;
break;
}
default:
*wsp = *cp;
}
break;
default: *wsp = *cp;
}
*wsp++ = '\0';
{
char *ret = *area;
*area = wsp;
return(ret);
}
}
} /* end for(;;) */
}
/*
* tgoto - given the cursor motion string cm, make up the string
* for the cursor to go to (destcol, destline), and return the string.
* Returns "OOPS" if something's gone wrong, or the string otherwise.
*/
char *tgoto(cm, destcol, destline)
char *cm;
int destcol;
int destline;
{
PRIVATE char ret[24];
char *rp = ret;
int incr = 0;
int argno = 0;
int numval;
for (; *cm; cm++) {
if (*cm == '%') {
switch (*++cm) {
case 'i': incr = 1; break;
case 'r': argno = 1; break;
case '+':
numval = (argno == 0 ? destline : destcol);
*rp++ = numval + incr + *++cm;
argno = 1 - argno;
break;
case '2':
numval = (argno == 0 ? destline : destcol);
numval = (numval + incr) % 100;
*rp++ = '0' + (numval / 10);
*rp++ = '0' + (numval % 10);
argno = 1 - argno;
break;
case 'd':
numval = (argno == 0 ? destline : destcol);
numval = (numval + incr) % 1000;
if (numval > 99) *rp++ = '0' + (numval / 100);
if (numval > 9) *rp++ = '0' + (numval / 10) % 10;
*rp++ = '0' + (numval % 10);
argno = 1 - argno;
break;
case '%': *rp++ = '%'; break;
default: return("OOPS");
}
} else
*rp++ = *cm;
}
*rp = '\0';
return(ret);
}
/*
* tputs - put the string cp out onto the terminal, using the function
* outc. This should do padding for the terminal, but I can't find a
* terminal that needs padding at the moment...
*/
int tputs(cp, affcnt, outc)
register char *cp;
int affcnt;
_PROTOTYPE( void (*outc), (int ch));
{
if (cp == (char *)NULL) return(1);
/* Do any padding interpretation - left null for MINIX just now */
while (*cp) (*outc) (*cp++);
return(1);
}

View file

@ -0,0 +1,15 @@
/* regerror() - Default regexp error report Author: Kees J. Bot
* 12 Jun 1999
*
* A better version of this routine should be supplied by the user in
* the program using regexps.
*/
#include <stdio.h>
#define const /* avoid "const poisoning" */
#include <compat/regexp.h>
#undef const
void regerror(char *message)
{
fprintf(stderr, "regexp error: %s\n", message);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,90 @@
/* regsub
*
* Copyright (c) 1986 by University of Toronto.
* Written by Henry Spencer. Not derived from licensed software.
*
* Permission is granted to anyone to use this software for any
* purpose on any computer system, and to redistribute it freely,
* subject to the following restrictions:
*
* 1. The author is not responsible for the consequences of use of
* this software, no matter how awful, even if they arise
* from defects in it.
*
* 2. The origin of this software must not be misrepresented, either
* by explicit claim or by omission.
*
* 3. Altered versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*/
#include <string.h>
#include <stdio.h>
#define const /* avoid "const poisoning" */
#include <compat/regexp.h>
#undef const
/* The first byte of the regexp internal "program" is actually this magic
* number; the start node begins in the second byte.
*/
#define MAGIC 0234
#define CHARBITS 0377
#ifndef CHARBITS
#define UCHARAT(p) ((int)*(unsigned char *)(p))
#else
#define UCHARAT(p) ((int)*(p)&CHARBITS)
#endif
/*
- regsub - perform substitutions after a regexp match
*/
void regsub(prog, source, dest)
regexp *prog;
char *source;
char *dest;
{
register char *src;
register char *dst;
register char c;
register int no;
register int len;
if (prog == (regexp *)NULL || source == (char *)NULL || dest == (char *)NULL) {
regerror("NULL parm to regsub");
return;
}
if (UCHARAT(prog->program) != MAGIC) {
regerror("damaged regexp fed to regsub");
return;
}
src = source;
dst = dest;
while ((c = *src++) != '\0') {
if (c == '&')
no = 0;
else if (c == '\\' && '0' <= *src && *src <= '9')
no = *src++ - '0';
else
no = -1;
if (no < 0) { /* Ordinary character. */
if (c == '\\' && (*src == '\\' || *src == '&')) c = *src++;
*dst++ = c;
} else
if (prog->startp[no] != (char *)NULL && prog->endp[no] != (char *)NULL) {
len = (int) (prog->endp[no] - prog->startp[no]);
strncpy(dst, prog->startp[no], len);
dst += len;
if (len != 0 && *(dst - 1) == '\0') { /* strncpy hit NUL. */
regerror("damaged match string");
return;
}
}
}
*dst++ = '\0';
}
/*
* $PchId: regsub.c,v 1.3 1995/11/27 20:18:16 philip Exp $
*/