home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
k95source.tar.gz
/
k95source.tar
/
ckustr.c
< prev
next >
Wrap
C/C++ Source or Header
|
2002-01-22
|
9KB
|
410 lines
/*
* ckustr.c - string extraction/restoration routines
*/
#include <stdio.h>
#include <sysexits.h>
#include <varargs.h>
#include <paths.h>
/*
STR_FILE must be defined as a quoted string on the cc command line,
for example:
-DSTR_FILE=\\\"/usr/local/lib/cku196.sr\\\"
This is the file where the strings go, and where C-Kermit looks for them
at runtime.
*/
#ifdef STR_FILE
char *StringFile = STR_FILE;
#else
char *StringFile = "/usr/local/lib/cku196.sr";
#endif /* STR_FILE */
/*
* If _PATH_CTIMED is defined (in <paths.h>) then use that definition. 2.11BSD
* has this defined but 2.10BSD and other systems do not.
*/
#ifndef _PATH_CTIMED
#define _PATH_CTIMED STR_CTIMED
#endif
extern int errno;
static int strfile = -1, ourpid = 0;
#define BUFLEN 256
errprep(offset, buf)
unsigned short offset;
char *buf;
{
register int pid = getpid();
if (pid != ourpid) {
ourpid = pid;
if (strfile >= 0) {
close(strfile);
strfile = -1;
}
}
if (strfile < 0) {
char *p, *getenv();
if (p = getenv("KSTR"))
if (strlen(p))
StringFile = p;
strfile = open(StringFile, 0);
if (strfile < 0) {
oops:
fprintf(stderr, "Cannot find %s\r\n", StringFile);
exit(EX_OSFILE);
}
}
if (lseek(strfile, (long) offset, 0) < 0
|| read(strfile, buf, BUFLEN) <= 0)
goto oops;
}
/* extracted string front end for printf() */
/*VARARGS1*/
strprerror(fmt, va_alist)
int fmt;
va_dcl
{
va_list ap;
char buf[BUFLEN];
errprep(fmt, buf);
va_start(ap);
vprintf(buf, ap);
va_end(ap);
}
/* extracted string front end for sprintf() */
/*VARARGS1*/
strsrerror(fmt, obuf, va_alist)
int fmt;
char *obuf;
va_dcl
{
char buf[BUFLEN];
va_list ap;
errprep(fmt, buf);
va_start(ap);
vsprintf(obuf, buf, ap);
va_end(ap);
}
/* extracted string front end for fprintf() */
/*VARARGS1*/
strfrerror(fmt, fd, va_alist)
int fmt;
FILE *fd;
va_dcl
{
va_list ap;
char buf[BUFLEN];
errprep(fmt, buf);
va_start(ap);
vfprintf(fd, buf, ap);
va_end(ap);
}
/* extracted string front end for perror() */
strperror(fmt)
int fmt;
{
char buf[BUFLEN];
register int saverr = errno;
errprep(fmt, buf);
errno = saverr;
perror(buf);
}
perror(str)
char *str;
{
printf("%s: errno %d\n", str, errno);
}
/*
* The following is needed _only_ on systems which do not have the C library
* stubs for the ctime() and getpw*() functions. In 2.11BSD these are
* present in the libstubs.a library and accessed via "-lstubs" at link time.
*
* 2.10BSD's cpp has the BSD2_10 symbol builtin. Other systems without
* libstubs.a will need to define (via a -D option in CFLAGS) 'BSD2_10'.
*/
#ifdef BSD2_10
#include <sys/types.h>
#include <sys/time.h>
#include <pwd.h>
#include <utmp.h>
#define SEND_FD W[1]
#define RECV_FD R[0]
#define CTIME 1
#define ASCTIME 2
#define TZSET 3
#define LOCALTIME 4
#define GMTIME 5
#define OFFTIME 6
#define GETPWENT 7
#define GETPWNAM 8
#define GETPWUID 9
#define SETPASSENT 10
#define ENDPWENT 11
static int R[2], W[2], inited;
static char result[256 + 4];
static struct tm tmtmp;
static struct passwd _pw, *getandfixpw();
char *
ctime(t)
time_t *t;
{
u_char fnc = CTIME;
sewer();
write(SEND_FD, &fnc, sizeof fnc);
write(SEND_FD, t, sizeof (*t));
getb(RECV_FD, result, 26);
return(result);
}
char *
asctime(tp)
struct tm *tp;
{
u_char fnc = ASCTIME;
sewer();
write(SEND_FD, &fnc, sizeof fnc);
write(SEND_FD, tp, sizeof (*tp));
getb(RECV_FD, result, 26);
return(result);
}
void
tzset()
{
u_char fnc = TZSET;
sewer();
write(SEND_FD, &fnc, sizeof fnc);
}
struct tm *
localtime(tp)
time_t *tp;
{
u_char fnc = LOCALTIME;
sewer();
write(SEND_FD, &fnc, sizeof fnc);
write(SEND_FD, tp, sizeof (*tp));
getb(RECV_FD, &tmtmp, sizeof tmtmp);
getb(RECV_FD, result, 24);
tmtmp.tm_zone = result;
return(&tmtmp);
}
struct tm *
gmtime(tp)
time_t *tp;
{
u_char fnc = GMTIME;
sewer();
write(SEND_FD, &fnc, sizeof fnc);
write(SEND_FD, tp, sizeof (*tp));
getb(RECV_FD, &tmtmp, sizeof tmtmp);
getb(RECV_FD, result, 24);
tmtmp.tm_zone = result;
return(&tmtmp);
}
struct tm *
offtime(clock, offset)
time_t *clock;
long offset;
{
u_char fnc = OFFTIME;
sewer();
write(SEND_FD, &fnc, sizeof fnc);
write(SEND_FD, clock, sizeof (*clock));
write(SEND_FD, &offset, sizeof offset);
getb(RECV_FD, &tmtmp, sizeof tmtmp);
tmtmp.tm_zone = "";
return(&tmtmp);
}
struct passwd *
getpwent()
{
u_char fnc = GETPWENT;
sewer();
write(SEND_FD, &fnc, sizeof fnc);
return(getandfixpw());
}
struct passwd *
getpwnam(nam)
char *nam;
{
u_char fnc = GETPWNAM;
char lnam[UT_NAMESIZE + 1];
int len;
len = strlen(nam);
if (len > UT_NAMESIZE)
len = UT_NAMESIZE;
bcopy(nam, lnam, len);
lnam[len] = '\0';
sewer();
write(SEND_FD, &fnc, 1);
write(SEND_FD, &len, sizeof (int));
write(SEND_FD, lnam, len);
return(getandfixpw());
}
struct passwd *
getpwuid(uid)
uid_t uid;
{
u_char fnc = GETPWUID;
sewer();
write(SEND_FD, &fnc, sizeof fnc);
write(SEND_FD, &uid, sizeof (uid_t));
return(getandfixpw());
}
setpwent()
{
return(setpassent(0));
}
setpassent(stayopen)
int stayopen;
{
u_char fnc = SETPASSENT;
int sts;
sewer();
write(SEND_FD, &fnc, sizeof fnc);
write(SEND_FD, &stayopen, sizeof (int));
getb(RECV_FD, &sts, sizeof (int));
return(sts);
}
void
endpwent()
{
u_char fnc = ENDPWENT;
sewer();
write(SEND_FD, &fnc, sizeof fnc);
return;
}
/* setpwfile() is deprecated */
void
setpwfile(file)
char *file;
{
return;
}
struct passwd *
getandfixpw()
{
short sz;
getb(RECV_FD, &sz, sizeof (int));
if (sz == 0)
return(NULL);
getb(RECV_FD, &_pw, sizeof (_pw));
getb(RECV_FD, result, sz);
_pw.pw_name += (int)result;
_pw.pw_passwd += (int)result;
_pw.pw_class += (int)result;
_pw.pw_gecos += (int)result;
_pw.pw_dir += (int)result;
_pw.pw_shell += (int)result;
return(&_pw);
}
getb(f, p, n)
register int f, n;
register char *p;
{
int i;
while (n)
{
i = read(f, p, n);
if (i <= 0)
return;
p += i;
n -= i;
}
}
sewer()
{
register int pid, ourpid = getpid();
if (inited == ourpid)
return;
if (inited)
{
close(SEND_FD);
close(RECV_FD);
}
pipe(W);
pipe(R);
pid = vfork();
if (pid == 0)
{ /* child */
alarm(0); /* cancel alarms */
dup2(W[0], 0); /* parent write side to our stdin */
dup2(R[1], 1); /* parent read side to our stdout */
close(SEND_FD); /* copies made, close the... */
close(RECV_FD); /* originals now */
execl(_PATH_CTIMED, "ctimed", 0);
_exit(EX_OSFILE);
}
if (pid == -1)
abort(); /* nothing else really to do */
close(W[0]); /* close read side of SEND channel */
close(R[1]); /* close write side of RECV channel */
inited = ourpid; /* don't do this again in this proc */
}
XXctime()
{
if (SEND_FD)
close(SEND_FD);
if (RECV_FD)
close(RECV_FD);
SEND_FD = RECV_FD = 0;
inited = 0;
}
#endif /* BSD2_10 */