home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
panix
/
k95source.tar.gz
/
k95source.tar
/
cku2tm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-11-27
|
9KB
|
266 lines
/*
* Steven Schultz - sms@moe.2bsd.com
*
* @(#)ctimed.c 1.0 (2.11BSD) 1996/6/25
*
* ctimed - the daemon that supports the ctime() and getpw*() stubs
* in 'libcstubs.a'.
*/
#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <pwd.h>
#include <utmp.h>
/*
* These should probably be placed in an include file. If you add anything
* here then you will also have to modify /usr/src/usr.lib/libstubs/stubs.c
* (if for no other reason than to add the stub code).
*/
#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
extern struct tm *offtime();
jmp_buf env;
char *cp;
char junk[256 + sizeof (struct passwd) + 4];
long off;
time_t l;
void timeout(), checkppid();
struct tm tmtmp, *tp;
main()
{
register int i;
register struct passwd *pw;
struct itimerval it;
u_char c, xxx;
int len, tosslen;
uid_t uid;
signal(SIGPIPE, SIG_DFL);
for (i = getdtablesize(); --i > 2; )
close(i);
/*
* Need a timer running while we disassociate from the control terminal
* in case of a modem line which has lost carrier.
*/
timerclear(&it.it_interval);
it.it_value.tv_sec = 5;
it.it_value.tv_usec = 0;
signal(SIGALRM, timeout);
setitimer(ITIMER_REAL, &it, (struct itimerval *) NULL);
if (setjmp(env) == 0)
{
i = open("/dev/tty", 0);
if (i >= 0)
{
ioctl(i, TIOCNOTTY, NULL);
close(i);
}
}
/*
* Now start a timer with one minute refresh. In the signal service
* routine, check the parent process id to see if this process has
* been orphaned and if so exit. This is primarily aimed at removing
* the 'ctimed' process left behind by 'sendmail's multi-fork startup
* but may prove useful in preventing accumulation of 'ctimed' processes
* in other circumstances as well. Normally this process is short
* lived.
*/
it.it_interval.tv_sec = 60;
it.it_interval.tv_usec = 0;
it.it_value.tv_sec = 60;
it.it_value.tv_usec = 0;
signal(SIGALRM, checkppid);
setitimer(ITIMER_REAL, &it, (struct itimerval *) NULL);
while (read(fileno(stdin), &c, 1) == 1)
{
switch (c)
{
case CTIME:
l = 0L;
getb(fileno(stdin), &l, sizeof l);
cp = ctime(&l);
write(fileno(stdout), cp, 26);
break;
case ASCTIME:
getb(fileno(stdin), &tmtmp, sizeof tmtmp);
cp = asctime(&tmtmp);
write(fileno(stdout), cp, 26);
break;
case TZSET:
(void) tzset();
break;
case LOCALTIME:
l = 0L;
getb(fileno(stdin), &l, sizeof l);
tp = localtime(&l);
write(fileno(stdout), tp, sizeof (*tp));
strcpy(junk, tp->tm_zone);
junk[24] = '\0';
write(fileno(stdout), junk, 24);
break;
case GMTIME:
l = 0L;
getb(fileno(stdin), &l, sizeof l);
tp = gmtime(&l);
write(fileno(stdout), tp, sizeof (*tp));
strcpy(junk, tp->tm_zone);
junk[24] = '\0';
write(fileno(stdout), junk, 24);
break;
case OFFTIME:
getb(fileno(stdin), &l, sizeof l);
getb(fileno(stdin), &off, sizeof off);
#ifdef __bsdi__
l += off;
tp = localtime(&l);
#else
tp = offtime(&l, off);
#endif
write(fileno(stdout), tp, sizeof (*tp));
break;
case GETPWENT:
pw = getpwent();
do_pw(pw);
break;
case GETPWNAM:
getb(fileno(stdin), &len, sizeof (int));
if (len > UT_NAMESIZE)
{
tosslen = len - UT_NAMESIZE;
len = UT_NAMESIZE;
}
else
tosslen = 0;
getb(fileno(stdin), junk, len);
for (;tosslen; tosslen--)
getb(fileno(stdin), &xxx, 1);
junk[len] = '\0';
pw = getpwnam(junk);
do_pw(pw);
break;
case GETPWUID:
getb(fileno(stdin), &uid, sizeof (uid_t));
pw = getpwuid(uid);
do_pw(pw);
break;
case SETPASSENT:
getb(fileno(stdin), &len, sizeof (int));
if (setpassent(len))
len = 1;
else
len = 0;
write(fileno(stdout), &len, sizeof (int));
break;
case ENDPWENT:
endpwent();
break;
default:
abort("switch");
}
}
}
getb(f, p, n)
int f;
register char *p;
register int n;
{
register int i;
while (n)
{
i = read(f, p, n);
if (i <= 0)
return;
p += i;
n -= i;
}
}
void
timeout()
{
longjmp(env, 1);
}
void
checkppid()
{
if (getppid() == 1)
exit(0);
}
do_pw(pw)
struct passwd *pw;
{
int len;
if (!pw)
{
len = 0;
write(fileno(stdout), &len, sizeof (int));
return;
}
len = packpwtobuf(pw, junk);
write(fileno(stdout), &len, sizeof (int));
write(fileno(stdout), pw, sizeof (*pw));
write(fileno(stdout), junk, len);
return;
}
packpwtobuf(pw, buf)
register struct passwd *pw;
char *buf;
{
register char *cp = buf;
register char *dp;
dp = pw->pw_name;
pw->pw_name = (char*) 0;
while (*cp++ = *dp++)
;
dp = pw->pw_passwd;
pw->pw_passwd = (char*) (cp - buf);
while (*cp++ = *dp++)
;
dp = pw->pw_class;
pw->pw_class = (char*) (cp - buf);
while (*cp++ = *dp++)
;
dp = pw->pw_gecos;
pw->pw_gecos = (char*) (cp - buf);
while (*cp++ = *dp++)
;
dp = pw->pw_dir;
pw->pw_dir = (char*) (cp - buf);
while (*cp++ = *dp++)
;
dp = pw->pw_shell;
pw->pw_shell = (char*) (cp - buf);
while (*cp++ = *dp++)
;
return(cp - buf);
}