Imported Upstream version 2.4.4p3
[debian/amanda] / client-src / sendbackup-dump.c
1 /*
2  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3  * Copyright (c) 1991-1998 University of Maryland at College Park
4  * All Rights Reserved.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of U.M. not be used in advertising or
11  * publicity pertaining to distribution of the software without specific,
12  * written prior permission.  U.M. makes no representations about the
13  * suitability of this software for any purpose.  It is provided "as is"
14  * without express or implied warranty.
15  *
16  * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Authors: the Amanda Development Team.  Its members are listed in a
24  * file named AUTHORS, in the root directory of this distribution.
25  */
26 /* 
27  * $Id: sendbackup-dump.c,v 1.65.2.5.4.2.2.9 2003/02/05 02:11:26 martinea Exp $
28  *
29  * send backup data using BSD dump
30  */
31
32 #include "sendbackup.h"
33 #include "clock.h"
34 #include "getfsent.h"
35 #include "version.h"
36
37 #ifdef KRB4_SECURITY
38 #include "sendbackup-krb4.h"
39 #else                                   /* I'd tell you what this does */
40 #define NAUGHTY_BITS                    /* but then I'd have to kill you */
41 #endif
42
43 #define LEAF_AND_DIRS "sed -e \'\ns/^leaf[ \t]*[0-9]*[ \t]*\\.//\nt\n/^dir[ \t]/ {\ns/^dir[ \t]*[0-9]*[ \t]*\\.//\ns%$%/%\nt\n}\nd\n\'"
44
45 static regex_t re_table[] = {
46   /* the various encodings of dump size */
47   /* this should also match BSDI pre-3.0's buggy dump program, that
48      produced doubled DUMP: DUMP: messages */
49   AM_SIZE_RE("DUMP: [0-9][0-9]* tape blocks", 1024),
50   AM_SIZE_RE("dump: Actual: [0-9][0-9]* tape blocks", 1024),
51   AM_SIZE_RE("backup: There are [0-9][0-9]* tape blocks on [0-9][0-9]* tapes",
52              1024),
53   AM_SIZE_RE("backup: [0-9][0-9]* tape blocks on [0-9][0-9]* tape\\(s\\)",
54              1024),
55   AM_SIZE_RE("backup: [0-9][0-9]* 1k blocks on [0-9][0-9]* volume\\(s\\)",
56              1024),
57   AM_SIZE_RE("DUMP: [0-9][0-9]* blocks \\([0-9][0-9]*KB\\) on [0-9][0-9]* volume",
58              512),
59
60   AM_SIZE_RE("DUMP: [0-9][0-9]* blocks \\([0-9][0-9]*\\.[0-9][0-9]*MB\\) on [0-9][0-9]* volume",
61              512),
62   AM_SIZE_RE("DUMP: [0-9][0-9]* blocks", 512),
63   AM_SIZE_RE("DUMP: [0-9][0-9]* bytes were dumped", 1),
64   /* OSF's vdump */
65   AM_SIZE_RE("vdump: Dumped  [0-9][0-9]* of [0-9][0-9]* bytes", 1),
66   /* DU 4.0a dump */
67   AM_SIZE_RE("dump: Actual: [0-9][0-9]* blocks output to pipe", 1024),
68   /* DU 4.0 vdump */
69   AM_SIZE_RE("dump: Dumped  [0-9][0-9]* of [0-9][0-9]* bytes", 1),
70   /* HPUX dump */
71   AM_SIZE_RE("DUMP: [0-9][0-9]* KB actual output", 1024),
72   /* HPUX 10.20 and above vxdump */
73   AM_SIZE_RE("vxdump: [0-9][0-9]* tape blocks", 1024),
74   /* UnixWare vxdump */
75   AM_SIZE_RE("vxdump: [0-9][0-9]* blocks", 1024),
76   /* SINIX vxdump */
77   AM_SIZE_RE("   VXDUMP: [0-9][0-9]* blocks", 512),
78   /* SINIX ufsdump */
79   AM_SIZE_RE("   UFSDUMP: [0-9][0-9]* blocks", 512),
80   /* Irix 6.2 xfs dump */
81   AM_SIZE_RE("xfsdump: media file size [0-9][0-9]* bytes", 1),
82   /* NetApp dump */
83   AM_SIZE_RE("DUMP: [0-9][0-9]* KB", 1024),
84
85   /* strange dump lines */
86   AM_STRANGE_RE("should not happen"),
87   AM_STRANGE_RE("Cannot open"),
88   AM_STRANGE_RE("[Ee]rror"),
89   AM_STRANGE_RE("[Ff]ail"),
90   /* XXX add more ERROR entries here by scanning dump sources? */
91
92   /* any blank or non-strange DUMP: lines are marked as normal */
93   AM_NORMAL_RE("^ *DUMP:"),
94   AM_NORMAL_RE("^dump:"),                               /* OSF/1 */
95   AM_NORMAL_RE("^vdump:"),                              /* OSF/1 */
96   AM_NORMAL_RE("^ *vxdump:"),                           /* HPUX10 */
97   AM_NORMAL_RE("^ *vxfs *vxdump:"),                     /* Solaris */
98   AM_NORMAL_RE("^xfsdump:"),                            /* IRIX xfs */
99   AM_NORMAL_RE("^ *VXDUMP:"),                           /* Sinix */
100   AM_NORMAL_RE("^ *UFSDUMP:"),                          /* Sinix */
101
102 #ifdef VDUMP    /* this is for OSF/1 3.2's vdump for advfs */
103   AM_NORMAL_RE("^The -s option is ignored"),            /* OSF/1 */
104   AM_NORMAL_RE("^path"),                                /* OSF/1 */
105   AM_NORMAL_RE("^dev/fset"),                            /* OSF/1 */
106   AM_NORMAL_RE("^type"),                                /* OSF/1 */
107   AM_NORMAL_RE("^advfs id"),                            /* OSF/1 */
108   AM_NORMAL_RE("^[A-Z][a-z][a-z] [A-Z][a-z][a-z] .[0-9] [0-9]"), /* OSF/1 */
109 #endif
110
111   AM_NORMAL_RE("^backup:"),                             /* AIX */
112   AM_NORMAL_RE("^        Use the umount command to unmount the filesystem"),
113
114   AM_NORMAL_RE("^[ \t]*$"),
115
116   /* catch-all; DMP_STRANGE is returned for all other lines */
117   AM_STRANGE_RE(NULL)
118 };
119
120 static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, indexf)
121     char *host;
122     char *disk, *amdevice;
123     int level, dataf, mesgf, indexf;
124     char *dumpdate;
125 {
126     int dumpin, dumpout;
127     char *dumpkeys = NULL;
128     char *device = NULL;
129     char *fstype = NULL;
130     char *cmd = NULL;
131     char *indexcmd = NULL;
132     char level_str[NUM_STR_SIZE];
133
134     ap_snprintf(level_str, sizeof(level_str), "%d", level);
135
136     fprintf(stderr, "%s: start [%s:%s level %d]\n",
137             get_pname(), host, disk, level);
138
139     NAUGHTY_BITS;
140
141     if(options->compress == COMPR_FAST || options->compress == COMPR_BEST) {
142         char *compopt = skip_argument;
143
144 #if defined(COMPRESS_BEST_OPT) && defined(COMPRESS_FAST_OPT)
145         if(options->compress == COMPR_BEST) {
146             compopt = COMPRESS_BEST_OPT;
147         } else {
148             compopt = COMPRESS_FAST_OPT;
149         }
150 #endif
151         comppid = pipespawn(COMPRESS_PATH, STDIN_PIPE,
152                             &dumpout, &dataf, &mesgf,
153                             COMPRESS_PATH, compopt, NULL);
154         dbprintf(("%s: pid %ld: %s",
155                   debug_prefix_time("-dump"), (long)comppid, COMPRESS_PATH));
156         if(compopt != skip_argument) {
157             dbprintf((" %s", compopt));
158         }
159         dbprintf(("\n"));
160     } else {
161         dumpout = dataf;
162         comppid = -1;
163     }
164
165     /* invoke dump */
166     device = amname_to_devname(amdevice);
167     fstype = amname_to_fstype(amdevice);
168
169     dbprintf(("%s: dumping device '%s' with '%s'\n",
170               debug_prefix_time(NULL), device, fstype));
171
172 #if defined(USE_RUNDUMP) || !defined(DUMP)
173     cmd = vstralloc(libexecdir, "/", "rundump", versionsuffix(), NULL);
174 #else
175     cmd = stralloc(DUMP);
176 #endif
177
178 #ifndef AIX_BACKUP                                      /* { */
179     /* normal dump */
180 #ifdef XFSDUMP                                          /* { */
181 #ifdef DUMP                                             /* { */
182     if (strcmp(amname_to_fstype(amdevice), "xfs") == 0)
183 #else                                                   /* } { */
184     if (1)
185 #endif                                                  /* } */
186     {
187         char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump",
188                                             versionsuffix(), NULL);
189         program->backup_name  = XFSDUMP;
190         program->restore_name = XFSRESTORE;
191
192         indexcmd = vstralloc(XFSRESTORE,
193                              " -t",
194                              " -v", " silent",
195                              " -",
196                              " 2>/dev/null",
197                              " | sed",
198                              " -e", " \'s/^/\\//\'",
199                              NULL);
200         write_tapeheader();
201
202         start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
203
204         dumpkeys = stralloc(level_str);
205         dumppid = pipespawn(progname, STDIN_PIPE,
206                             &dumpin, &dumpout, &mesgf,
207                             "xfsdump",
208                             options->no_record ? "-J" : skip_argument,
209                             "-F",
210                             "-l", dumpkeys,
211                             "-",
212                             device,
213                             NULL);
214     }
215     else
216 #endif                                                  /* } */
217 #ifdef VXDUMP                                           /* { */
218 #ifdef DUMP
219     if (strcmp(amname_to_fstype(amdevice), "vxfs") == 0)
220 #else
221     if (1)
222 #endif
223     {
224 #ifdef USE_RUNDUMP
225         char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump",
226                                             versionsuffix(), NULL);
227 #else
228         char *progname = cmd = newvstralloc(cmd, VXDUMP, NULL);
229 #endif
230         program->backup_name  = VXDUMP;
231         program->restore_name = VXRESTORE;
232
233         dumpkeys = vstralloc(level_str,
234                              options->no_record ? "" : "u",
235                              "s",
236                              "f",
237                              NULL);
238
239         indexcmd = vstralloc(VXRESTORE,
240                              " -tvf", " -",
241                              " 2>/dev/null",
242                              " | ",
243                              LEAF_AND_DIRS,
244                              NULL);
245         write_tapeheader();
246
247         start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
248
249         dumppid = pipespawn(progname, STDIN_PIPE,
250                             &dumpin, &dumpout, &mesgf, 
251                             "vxdump",
252                             dumpkeys,
253                             "1048576",
254                             "-",
255                             device,
256                             NULL);
257     }
258     else
259 #endif                                                  /* } */
260
261 #ifdef VDUMP                                            /* { */
262 #ifdef DUMP
263     if (strcmp(amname_to_fstype(amdevice), "advfs") == 0)
264 #else
265     if (1)
266 #endif
267     {
268         char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump",
269                                             versionsuffix(), NULL);
270         device = newstralloc(device, amname_to_dirname(amdevice));
271         program->backup_name  = VDUMP;
272         program->restore_name = VRESTORE;
273
274         dumpkeys = vstralloc(level_str,
275                              options->no_record ? "" : "u",
276                              "b",
277                              "f",
278                              NULL);
279
280         indexcmd = vstralloc(VRESTORE,
281                              " -tvf", " -",
282                              " 2>/dev/null",
283                              " | ",
284                              "sed -e \'\n/^\\./ {\ns/^\\.//\ns/, [0-9]*$//\ns/^\\.//\ns/ @-> .*$//\nt\n}\nd\n\'",
285                              NULL);
286         write_tapeheader();
287
288         start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
289
290         dumppid = pipespawn(cmd, STDIN_PIPE,
291                             &dumpin, &dumpout, &mesgf, 
292                             "vdump",
293                             dumpkeys,
294                             "60",
295                             "-",
296                             device,
297                             NULL);
298     }
299     else
300 #endif                                                  /* } */
301
302     {
303 #ifndef RESTORE
304 #define RESTORE "restore"
305 #endif
306
307         dumpkeys = vstralloc(level_str,
308                              options->no_record ? "" : "u",
309                              "s",
310 #ifdef HAVE_HONOR_NODUMP
311                              "h",
312 #endif
313                              "f",
314                              NULL);
315
316         indexcmd = vstralloc(RESTORE,
317                              " -tvf", " -",
318                              " 2>&1",
319                              /* not to /dev/null because of DU's dump */
320                              " | ",
321                              LEAF_AND_DIRS,
322                              NULL);
323         write_tapeheader();
324
325         start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
326
327         dumppid = pipespawn(cmd, STDIN_PIPE,
328                             &dumpin, &dumpout, &mesgf, 
329                             "dump",
330                             dumpkeys,
331                             "1048576",
332 #ifdef HAVE_HONOR_NODUMP
333                             "0",
334 #endif
335                             "-",
336                             device,
337                             NULL);
338     }
339 #else                                                   /* } { */
340     /* AIX backup program */
341     dumpkeys = vstralloc("-",
342                          level_str,
343                          options->no_record ? "" : "u",
344                          "f",
345                          NULL);
346
347     indexcmd = vstralloc(RESTORE,
348                          " -B",
349                          " -tvf", " -",
350                          " 2>/dev/null",
351                          " | ",
352                          LEAF_AND_DIRS,
353                          NULL);
354     write_tapeheader();
355
356     start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
357
358     dumppid = pipespawn(cmd, STDIN_PIPE,
359                         &dumpin, &dumpout, &mesgf, 
360                         "backup",
361                         dumpkeys,
362                         "-",
363                         device,
364                         NULL);
365 #endif                                                  /* } */
366
367     amfree(dumpkeys);
368     amfree(device);
369     amfree(cmd);
370     amfree(indexcmd);
371
372     /* close the write ends of the pipes */
373
374     aclose(dumpin);
375     aclose(dumpout);
376     aclose(dataf);
377     aclose(mesgf);
378     if (options->createindex)
379         aclose(indexf);
380 }
381
382 static void end_backup(status)
383 int status;
384 {
385     /* don't need to do anything for dump */
386 }
387
388 backup_program_t dump_program = {
389   "DUMP",
390 #ifdef DUMP
391   DUMP
392 #else
393   "dump"
394 #endif
395   ,
396   RESTORE
397   ,
398   re_table, start_backup, end_backup
399 };