1 /*
2  * Copyright (c) 1998,1999,2000
3  *      Traakan, Inc., Los Altos, CA
4  *      All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice unmodified, this list of conditions, and the following
11  *    disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 /*
30  * Project:  NDMJOB
31  * Ident:    $Id: $
32  *
33  * Description:
34  *
35  */
36 
37 
38 #include "ndmagents.h"
39 
40 #ifndef NDMOS_OPTION_NO_DATA_AGENT
41 
42 
ndmda_pipe_fork_exec(struct ndm_session * sess,char * cmd,int is_backup)43 int ndmda_pipe_fork_exec(struct ndm_session* sess, char* cmd, int is_backup)
44 {
45   struct ndm_data_agent* da = sess->data_acb;
46   struct ndmchan* ch;
47   int errpipe[2];
48   int datpipe[2];
49   int wrppipe[2];
50   int nullfd;
51   int rc = -1;
52 
53   ndmalogf(sess, 0, 2, "Starting %s", cmd);
54 
55   nullfd = open("/dev/null", 2);
56   if (nullfd < 0) { return rc; }
57 
58   rc = pipe(errpipe);
59   if (rc < 0) {
60     close(nullfd);
61     return rc;
62   }
63 
64   rc = pipe(datpipe);
65   if (rc < 0) {
66     close(nullfd);
67     close(errpipe[0]);
68     close(errpipe[1]);
69     return rc;
70   }
71 
72   rc = pipe(wrppipe);
73   if (rc < 0) {
74     close(nullfd);
75     close(errpipe[0]);
76     close(errpipe[1]);
77     close(datpipe[0]);
78     close(datpipe[1]);
79     return rc;
80   }
81 
82   rc = fork();
83   if (rc < 0) {
84     close(nullfd);
85     close(errpipe[0]);
86     close(errpipe[1]);
87     close(datpipe[0]);
88     close(datpipe[1]);
89     close(wrppipe[0]);
90     close(wrppipe[1]);
91     return rc;
92   }
93 
94   if (rc == 0) {
95     /* child */
96     dup2(errpipe[1], 2);
97     dup2(wrppipe[1], 3);
98     close(errpipe[0]);
99     close(wrppipe[0]);
100 
101     if (is_backup) {
102       dup2(nullfd, 0);
103       dup2(datpipe[1], 1);
104       close(datpipe[0]);
105     } else {
106       dup2(datpipe[0], 0);
107       dup2(nullfd, 1);
108       close(datpipe[1]);
109     }
110 
111     /*
112      * 0 -- formatter stdin
113      * 1 -- formatter stdout
114      * 2 -- formatter stderr
115      * 3 -- formatter wrap chan (wraplib.c)
116      */
117     for (rc = 4; rc < 100; rc++) { close(rc); }
118 
119     execl("/bin/sh", "sh", "-c", cmd, NULL);
120 
121     fprintf(stderr, "EXEC FAILED %s\n", cmd);
122     exit(127);
123   }
124 
125   /* parent */
126   close(nullfd);
127 
128   ch = &da->formatter_error;
129   ndmchan_initialize(ch, "dfp-error");
130   da->fmt_error_buf = NDMOS_API_MALLOC(NDMDA_N_FMT_ERROR_BUF);
131   if (!da->fmt_error_buf) return -1;
132   ndmchan_setbuf(ch, da->fmt_error_buf, NDMDA_N_FMT_ERROR_BUF);
133   close(errpipe[1]);
134   ndmos_condition_pipe_fd(sess, errpipe[0]);
135   ndmchan_start_read(ch, errpipe[0]);
136 
137   ch = &da->formatter_wrap;
138   ndmchan_initialize(ch, "dfp-wrap");
139   da->fmt_wrap_buf = NDMOS_API_MALLOC(NDMDA_N_FMT_WRAP_BUF);
140   if (!da->fmt_wrap_buf) return -1;
141   ndmchan_setbuf(ch, da->fmt_wrap_buf, NDMDA_N_FMT_WRAP_BUF);
142   close(wrppipe[1]);
143   ndmos_condition_pipe_fd(sess, wrppipe[0]);
144   ndmchan_start_read(ch, wrppipe[0]);
145 
146   ch = &da->formatter_image;
147   ndmchan_initialize(ch, "dfp-image");
148   da->fmt_image_buf = NDMOS_API_MALLOC(NDMDA_N_FMT_IMAGE_BUF);
149   if (!da->fmt_image_buf) return -1;
150   ndmchan_setbuf(ch, da->fmt_image_buf, NDMDA_N_FMT_IMAGE_BUF);
151 
152   if (is_backup) {
153     ndmalogf(sess, 0, 2, "backup...");
154     close(datpipe[1]);
155     ndmos_condition_pipe_fd(sess, datpipe[0]);
156     ndmchan_start_read(ch, datpipe[0]);
157   } else {
158     ndmalogf(sess, 0, 2, "recover...");
159     close(datpipe[0]);
160     ndmos_condition_pipe_fd(sess, datpipe[1]);
161     ndmchan_start_write(ch, datpipe[1]);
162   }
163 
164   da->formatter_pid = rc;
165 
166   return rc; /* PID */
167 }
168 
ndmda_add_to_cmd_with_escapes(char * cmd,char * word,char * special)169 int ndmda_add_to_cmd_with_escapes(char* cmd, char* word, char* special)
170 {
171   char* cmd_lim = &cmd[NDMDA_MAX_CMD - 3];
172   char* p;
173   int c;
174 
175   p = cmd;
176   while (*p) p++;
177   if (p != cmd) *p++ = ' ';
178 
179   while ((c = *word++) != 0) {
180     if (p >= cmd_lim) return -1; /* overflow */
181     if (c == '\\' || strchr(special, c)) *p++ = '\\';
182     *p++ = c;
183   }
184   *p = 0;
185 
186   return 0;
187 }
188 
ndmda_add_to_cmd(char * cmd,char * word)189 int ndmda_add_to_cmd(char* cmd, char* word)
190 {
191   return ndmda_add_to_cmd_with_escapes(cmd, word, " \t`'\"*?[]$");
192 }
193 
ndmda_add_to_cmd_allow_file_wildcards(char * cmd,char * word)194 int ndmda_add_to_cmd_allow_file_wildcards(char* cmd, char* word)
195 {
196   return ndmda_add_to_cmd_with_escapes(cmd, word, " \t`'\"$");
197 }
198 
199 #endif /* !NDMOS_OPTION_NO_DATA_AGENT */
200