Imported Upstream version 3.1.0
[debian/amanda] / ndmp-src / ndma_data_pfe.c
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
43 int
44 ndmda_pipe_fork_exec (struct ndm_session *sess, char *cmd, int is_backup)
45 {
46         struct ndm_data_agent * da = &sess->data_acb;
47         struct ndmchan *        ch;
48         int                     errpipe[2];
49         int                     datpipe[2];
50         int                     wrppipe[2];
51         int                     nullfd;
52         int                     rc = -1;
53
54         ndmalogf (sess, 0, 2, "Starting %s", cmd);
55
56         nullfd = open ("/dev/null", 2);
57         if (nullfd < 0) {
58                 return rc;
59         }
60
61         rc = pipe (errpipe);
62         if (rc < 0) {
63                 close (nullfd);
64                 return rc;
65         }
66
67         rc = pipe (datpipe);
68         if (rc < 0) {
69                 close (nullfd);
70                 close (errpipe[0]);
71                 close (errpipe[1]);
72                 return rc;
73         }
74
75         rc = pipe (wrppipe);
76         if (rc < 0) {
77                 close (nullfd);
78                 close (errpipe[0]);
79                 close (errpipe[1]);
80                 close (datpipe[0]);
81                 close (datpipe[1]);
82                 return rc;
83         }
84
85         rc = fork();
86         if (rc < 0) {
87                 close (nullfd);
88                 close (errpipe[0]);
89                 close (errpipe[1]);
90                 close (datpipe[0]);
91                 close (datpipe[1]);
92                 close (wrppipe[0]);
93                 close (wrppipe[1]);
94                 return rc;
95         }
96
97         if (rc == 0) {
98                 /* child */
99                 dup2 (errpipe[1], 2);
100                 dup2 (wrppipe[1], 3);
101                 close (errpipe[0]);
102                 close (wrppipe[0]);
103
104                 if (is_backup) {
105                         dup2 (nullfd, 0);
106                         dup2 (datpipe[1], 1);
107                         close (datpipe[0]);
108                 } else {
109                         dup2 (datpipe[0], 0);
110                         dup2 (nullfd, 1);
111                         close (datpipe[1]);
112                 }
113
114                 /*
115                  * 0 -- formatter stdin
116                  * 1 -- formatter stdout
117                  * 2 -- formatter stderr
118                  * 3 -- formatter wrap chan (wraplib.c)
119                  */
120                 for (rc = 4; rc < 100; rc++) {
121                         close(rc);
122                 }
123
124                 execl ("/bin/sh", "sh", "-c", cmd, NULL);
125
126                 fprintf (stderr, "EXEC FAILED %s\n", cmd);
127                 exit(127);
128         }
129
130         /* parent */
131         close (nullfd);
132
133         ch = &da->formatter_error;
134         ndmchan_initialize (ch, "dfp-error");
135         ndmchan_setbuf (ch, da->fmt_error_buf, sizeof da->fmt_error_buf);
136         close (errpipe[1]);
137         ndmos_condition_pipe_fd (sess, errpipe[0]);
138         ndmchan_start_read (ch, errpipe[0]);
139
140         ch = &da->formatter_wrap;
141         ndmchan_initialize (ch, "dfp-wrap");
142         ndmchan_setbuf (ch, da->fmt_wrap_buf, sizeof da->fmt_wrap_buf);
143         close (wrppipe[1]);
144         ndmos_condition_pipe_fd (sess, wrppipe[0]);
145         ndmchan_start_read (ch, wrppipe[0]);
146
147         ch = &da->formatter_image;
148         ndmchan_initialize (ch, "dfp-image");
149         ndmchan_setbuf (ch, da->fmt_image_buf, sizeof da->fmt_image_buf);
150
151         if (is_backup) {
152                 ndmalogf (sess, 0, 2, "backup...");
153                 close (datpipe[1]);
154                 ndmos_condition_pipe_fd (sess, datpipe[0]);
155                 ndmchan_start_read (ch, datpipe[0]);
156         } else {
157                 ndmalogf (sess, 0, 2, "recover...");
158                 close (datpipe[0]);
159                 ndmos_condition_pipe_fd (sess, datpipe[1]);
160                 ndmchan_start_write (ch, datpipe[1]);
161         }
162
163         da->formatter_pid = rc;
164
165         return rc;      /* PID */
166 }
167
168 int
169 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)
181                         return -1;      /* overflow */
182                 if (c == '\\' || strchr (special, c))
183                         *p++ = '\\';
184                 *p++ = c;
185         }
186         *p = 0;
187
188         return 0;
189 }
190
191 int
192 ndmda_add_to_cmd (char *cmd, char *word)
193 {
194         return ndmda_add_to_cmd_with_escapes (cmd, word, " \t`'\"*?[]$");
195 }
196
197 int
198 ndmda_add_to_cmd_allow_file_wildcards (char *cmd, char *word)
199 {
200         return ndmda_add_to_cmd_with_escapes (cmd, word, " \t`'\"$");
201 }
202
203 #endif /* !NDMOS_OPTION_NO_DATA_AGENT */