|
|
1.1 root 1: /*
2: * cronpipe.c
3: * Special version of popen, that allows to crond keep track about
4: * children.
5: */
6: #include <stdio.h>
7: #include <signal.h>
8: #include <time.h>
9: #include <sys/types.h>
10: #include "cron.h"
11:
12: #define R 0 /* Pipe read descriptor index */
13: #define W 1 /* Pipe write descriptor index */
14:
15: extern child_id *add_entry(); /* Add an new entry to a link list */
16:
17: extern char acRealUser[MAX_UNAME];
18: extern time_t clock;
19: extern child_id *current; /* Pointer to the current child id */
20: extern int flag320;
21: extern int mailFlag;
22: extern int set_uid_flag;
23:
24: static int poppid[_NFILE];
25:
26: FILE *
27: cronpipe(command, type)
28: char *command, *type;
29: {
30: register mode;
31: register fd;
32: int pd[2];
33:
34: if (pipe(pd) < 0)
35: return (NULL);
36: if (*type == 'w') {
37: mode = W;
38: fd = pd[W];
39: } else {
40: mode = R;
41: fd = pd[R];
42: }
43: if ((poppid[fd] = fork()) < 0) {
44: close(pd[R]);
45: close(pd[W]);
46: return (NULL);
47: }
48: if (poppid[fd] == 0) { /* Child */
49: /* Set uid to user which crontab is going to be executed.
50: * In case of COHERENT3.2.0 set uid to daemon (set_uid_flag
51: * is TRUE).
52: */
53: Dprint("Set user ID to '%s'\n", acRealUser);
54: if (set_uid_flag == FALSE) {
55: /* If file name is not user name ignore it */
56: if ((set_uid_flag = set_uid(acRealUser)) != TRUE) {
57: fprintf(stderr,
58: "crond: cannot find/set user '%s'\n",
59: acRealUser);
60: return(NULL);
61: }
62: }
63: if (mode == W) {
64: close(pd[W]);
65: close(fileno(stdin));
66: dup(pd[R]);
67: close(pd[R]);
68: } else {
69: close(pd[R]);
70: close(fileno(stdout));
71: dup(pd[W]);
72: close(pd[W]);
73: }
74: Dprint("cronpipe: before execl %s\n", command);
75: execl("/bin/sh", "sh", "-c", command, NULL);
76: exit(1);
77: }
78: /* Parent */
79: /* We will keep track about keeds only in SV mode */
80: if (flag320 == FALSE) {
81: Dprint("cronpipe before fork: Name %s\n", acRealUser);
82: Dprint(" Pid %d\n", poppid[fd]);
83: Dprint(" Name %s\n", acRealUser);
84: Dprint(" Time %s\n", ctime(&clock));
85: Dprint(" Command %s\n", command);
86: current = add_entry(poppid[fd], acRealUser, clock, command);
87: }
88: if (mode == W) {
89: close(pd[R]);
90: return (fdopen(pd[W], "w"));
91: } else {
92: close(pd[W]);
93: return (fdopen(pd[R], "r"));
94: }
95: }
96:
97: pclose(stream)
98: FILE *stream;
99: {
100: register fd;
101: register pid, wpid;
102: int status;
103: int (*hupfun)(), (*intfun)(), (*quitfun)();
104:
105: fd = fileno(stream);
106: pid = poppid[fd];
107: poppid[fd] = 0;
108: if (pid==0 || fclose(stream)==EOF)
109: return (-1);
110: hupfun = signal(SIGHUP, SIG_IGN);
111: intfun = signal(SIGINT, SIG_IGN);
112: quitfun = signal(SIGQUIT, SIG_IGN);
113: while ((wpid = wait(&status))!=pid && wpid>=0)
114: ;
115: if (wpid < 0)
116: status = -1;
117: signal(SIGHUP, hupfun);
118: signal(SIGINT, intfun);
119: signal(SIGQUIT, quitfun);
120: return (status);
121: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.