source: trunk/third/kermit/cku2tm.c @ 10780

Revision 10780, 5.2 KB checked in by brlewis, 27 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r10779, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Steven Schultz - sms@moe.2bsd.com
3 *
4 *      @(#)ctimed.c    1.0 (2.11BSD) 1996/6/25
5 *
6 * ctimed - the daemon that supports the ctime() and getpw*() stubs
7 *          in 'libcstubs.a'.
8*/
9
10#include        <signal.h>
11#include        <stdio.h>
12#include        <setjmp.h>
13#include        <sys/ioctl.h>
14#include        <sys/types.h>
15#include        <sys/time.h>
16#include        <pwd.h>
17#include        <utmp.h>
18
19/*
20 * These should probably be placed in an include file.  If you add anything
21 * here then you will also have to modify /usr/src/usr.lib/libstubs/stubs.c
22 * (if for no other reason than to add the stub code).
23*/
24
25#define CTIME   1
26#define ASCTIME 2
27#define TZSET   3
28#define LOCALTIME 4
29#define GMTIME  5
30#define OFFTIME 6
31
32#define GETPWENT        7
33#define GETPWNAM        8
34#define GETPWUID        9
35#define SETPASSENT      10
36#define ENDPWENT        11
37
38extern  struct  tm      *offtime();
39
40        jmp_buf env;
41        char    *cp;
42        char    junk[256 + sizeof (struct passwd) + 4];
43        long    off;
44        time_t  l;
45        void    timeout(), checkppid();
46        struct  tm      tmtmp, *tp;
47
48main()
49        {
50        register int i;
51        register struct passwd *pw;
52        struct  itimerval it;
53        u_char  c, xxx;
54        int     len, tosslen;
55        uid_t   uid;
56
57        signal(SIGPIPE, SIG_DFL);
58        for     (i = getdtablesize(); --i > 2; )
59                close(i);
60/*
61 * Need a timer running while we disassociate from the control terminal
62 * in case of a modem line which has lost carrier.
63*/
64        timerclear(&it.it_interval);
65        it.it_value.tv_sec = 5;
66        it.it_value.tv_usec = 0;
67        signal(SIGALRM, timeout);
68        setitimer(ITIMER_REAL, &it, (struct itimerval *) NULL);
69        if      (setjmp(env) == 0)
70                {
71                i = open("/dev/tty", 0);
72                if      (i >= 0)
73                        {
74                        ioctl(i, TIOCNOTTY, NULL);
75                        close(i);
76                        }
77                }
78/*
79 * Now start a timer with one minute refresh.  In the signal service
80 * routine, check the parent process id to see if this process has
81 * been orphaned and if so exit.  This is primarily aimed at removing
82 * the 'ctimed' process left behind by 'sendmail's multi-fork startup
83 * but may prove useful in preventing accumulation of 'ctimed' processes
84 * in other circumstances as well.  Normally this process is short
85 * lived.
86*/
87        it.it_interval.tv_sec = 60;
88        it.it_interval.tv_usec = 0;
89        it.it_value.tv_sec = 60;
90        it.it_value.tv_usec = 0;
91        signal(SIGALRM, checkppid);
92        setitimer(ITIMER_REAL, &it, (struct itimerval *) NULL);
93
94        while   (read(fileno(stdin), &c, 1) == 1)
95                {
96                switch  (c)
97                        {
98                        case    CTIME:
99                                l = 0L;
100                                getb(fileno(stdin), &l, sizeof l);
101                                cp = ctime(&l);
102                                write(fileno(stdout), cp, 26);
103                                break;
104                        case    ASCTIME:
105                                getb(fileno(stdin), &tmtmp, sizeof tmtmp);
106                                cp = asctime(&tmtmp);
107                                write(fileno(stdout), cp, 26);
108                                break;
109                        case    TZSET:
110                                (void) tzset();
111                                break;
112                        case    LOCALTIME:
113                                l = 0L;
114                                getb(fileno(stdin), &l, sizeof l);
115                                tp = localtime(&l);
116                                write(fileno(stdout), tp, sizeof (*tp));
117                                strcpy(junk, tp->tm_zone);
118                                junk[24] = '\0';
119                                write(fileno(stdout), junk, 24);
120                                break;
121                        case    GMTIME:
122                                l = 0L;
123                                getb(fileno(stdin), &l, sizeof l);
124                                tp = gmtime(&l);
125                                write(fileno(stdout), tp, sizeof (*tp));
126                                strcpy(junk, tp->tm_zone);
127                                junk[24] = '\0';
128                                write(fileno(stdout), junk, 24);
129                                break;
130                        case    OFFTIME:
131                                getb(fileno(stdin), &l, sizeof l);
132                                getb(fileno(stdin), &off, sizeof off);
133#ifdef  __bsdi__
134                                l += off;
135                                tp = localtime(&l);
136#else
137                                tp = offtime(&l, off);
138#endif
139                                write(fileno(stdout), tp, sizeof (*tp));
140                                break;
141                        case    GETPWENT:
142                                pw = getpwent();
143                                do_pw(pw);
144                                break;
145                        case    GETPWNAM:
146                                getb(fileno(stdin), &len, sizeof (int));
147                                if      (len > UT_NAMESIZE)
148                                        {
149                                        tosslen = len - UT_NAMESIZE;
150                                        len = UT_NAMESIZE;
151                                        }
152                                else
153                                        tosslen = 0;
154                                getb(fileno(stdin), junk, len);
155                                for     (;tosslen; tosslen--)
156                                        getb(fileno(stdin), &xxx, 1);
157                                junk[len] = '\0';
158                                pw = getpwnam(junk);
159                                do_pw(pw);
160                                break;
161                        case    GETPWUID:
162                                getb(fileno(stdin), &uid, sizeof (uid_t));
163                                pw = getpwuid(uid);
164                                do_pw(pw);
165                                break;
166                        case    SETPASSENT:
167                                getb(fileno(stdin), &len, sizeof (int));
168                                if      (setpassent(len))
169                                        len = 1;
170                                else
171                                        len = 0;
172                                write(fileno(stdout), &len, sizeof (int));
173                                break;
174                        case    ENDPWENT:
175                                endpwent();
176                                break;
177                        default:
178                                abort("switch");
179                        }
180                }
181        }
182
183getb(f, p, n)
184        int     f;
185        register char   *p;
186        register int    n;
187        {
188        register int    i;
189
190        while   (n)
191                {
192                i = read(f, p, n);
193                if      (i <= 0)
194                        return;
195                p += i;
196                n -= i;
197                }
198        }
199
200void
201timeout()
202        {
203
204        longjmp(env, 1);
205        }
206
207void
208checkppid()
209        {
210
211        if      (getppid() == 1)
212                exit(0);
213        }
214
215do_pw(pw)
216        struct passwd *pw;
217        {
218        int     len;
219
220        if      (!pw)
221                {
222                len = 0;
223                write(fileno(stdout), &len, sizeof (int));
224                return;
225                }
226        len = packpwtobuf(pw, junk);
227        write(fileno(stdout), &len, sizeof (int));
228        write(fileno(stdout), pw, sizeof (*pw));
229        write(fileno(stdout), junk, len);
230        return;
231        }
232
233packpwtobuf(pw, buf)
234        register struct passwd *pw;
235        char    *buf;
236        {
237        register char *cp = buf;
238        register char *dp;
239
240        dp = pw->pw_name;
241        pw->pw_name = (char*) 0;
242        while   (*cp++ = *dp++)
243                ;
244        dp = pw->pw_passwd;
245        pw->pw_passwd = (char*) (cp - buf);
246        while   (*cp++ = *dp++)
247                ;
248        dp = pw->pw_class;
249        pw->pw_class = (char*) (cp - buf);
250        while   (*cp++ = *dp++)
251                ;
252        dp = pw->pw_gecos;
253        pw->pw_gecos = (char*) (cp - buf);
254        while   (*cp++ = *dp++)
255                ;
256        dp = pw->pw_dir;
257        pw->pw_dir = (char*) (cp - buf);
258        while   (*cp++ = *dp++)
259                ;
260        dp = pw->pw_shell;
261        pw->pw_shell = (char*) (cp - buf);
262        while   (*cp++ = *dp++)
263                ;
264        return(cp - buf);
265        }
Note: See TracBrowser for help on using the repository browser.