Imported Upstream version 2.4.5p1
[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.2.1 2005/09/20 18:13:08 jrjackson 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("^Dumping .* to stdout"),                /* Solaris vxdump */
99   AM_NORMAL_RE("^xfsdump:"),                            /* IRIX xfs */
100   AM_NORMAL_RE("^ *VXDUMP:"),                           /* Sinix */
101   AM_NORMAL_RE("^ *UFSDUMP:"),                          /* Sinix */
102
103 #ifdef VDUMP    /* this is for OSF/1 3.2's vdump for advfs */
104   AM_NORMAL_RE("^The -s option is ignored"),            /* OSF/1 */
105   AM_NORMAL_RE("^path"),                                /* OSF/1 */
106   AM_NORMAL_RE("^dev/fset"),                            /* OSF/1 */
107   AM_NORMAL_RE("^type"),                                /* OSF/1 */
108   AM_NORMAL_RE("^advfs id"),                            /* OSF/1 */
109   AM_NORMAL_RE("^[A-Z][a-z][a-z] [A-Z][a-z][a-z] .[0-9] [0-9]"), /* OSF/1 */
110 #endif
111
112   AM_NORMAL_RE("^backup:"),                             /* AIX */
113   AM_NORMAL_RE("^        Use the umount command to unmount the filesystem"),
114
115   AM_NORMAL_RE("^[ \t]*$"),
116
117   /* catch-all; DMP_STRANGE is returned for all other lines */
118   AM_STRANGE_RE(NULL)
119 };
120
121 static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, indexf)
122     char *host;
123     char *disk, *amdevice;
124     int level, dataf, mesgf, indexf;
125     char *dumpdate;
126 {
127     int dumpin, dumpout;
128     char *dumpkeys = NULL;
129     char *device = NULL;
130     char *fstype = NULL;
131     char *cmd = NULL;
132     char *indexcmd = NULL;
133     char level_str[NUM_STR_SIZE];
134
135     ap_snprintf(level_str, sizeof(level_str), "%d", level);
136
137     fprintf(stderr, "%s: start [%s:%s level %d]\n",
138             get_pname(), host, disk, level);
139
140     NAUGHTY_BITS;
141
142     if(options->compress == COMPR_FAST || options->compress == COMPR_BEST) {
143         char *compopt = skip_argument;
144
145 #if defined(COMPRESS_BEST_OPT) && defined(COMPRESS_FAST_OPT)
146         if(options->compress == COMPR_BEST) {
147             compopt = COMPRESS_BEST_OPT;
148         } else {
149             compopt = COMPRESS_FAST_OPT;
150         }
151 #endif
152         comppid = pipespawn(COMPRESS_PATH, STDIN_PIPE,
153                             &dumpout, &dataf, &mesgf,
154                             COMPRESS_PATH, compopt, NULL);
155         dbprintf(("%s: pid %ld: %s",
156                   debug_prefix_time("-dump"), (long)comppid, COMPRESS_PATH));
157         if(compopt != skip_argument) {
158             dbprintf((" %s", compopt));
159         }
160         dbprintf(("\n"));
161     } else {
162         dumpout = dataf;
163         comppid = -1;
164     }
165
166     /* invoke dump */
167     device = amname_to_devname(amdevice);
168     fstype = amname_to_fstype(amdevice);
169
170     dbprintf(("%s: dumping device '%s' with '%s'\n",
171               debug_prefix_time(NULL), device, fstype));
172
173 #if defined(USE_RUNDUMP) || !defined(DUMP)
174     cmd = vstralloc(libexecdir, "/", "rundump", versionsuffix(), NULL);
175 #else
176     cmd = stralloc(DUMP);
177 #endif
178
179 #ifndef AIX_BACKUP                                      /* { */
180     /* normal dump */
181 #ifdef XFSDUMP                                          /* { */
182 #ifdef DUMP                                             /* { */
183     if (strcmp(amname_to_fstype(amdevice), "xfs") == 0)
184 #else                                                   /* } { */
185     if (1)
186 #endif                                                  /* } */
187     {
188         char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump",
189                                             versionsuffix(), NULL);
190         program->backup_name  = XFSDUMP;
191         program->restore_name = XFSRESTORE;
192
193         indexcmd = vstralloc(XFSRESTORE,
194                              " -t",
195                              " -v", " silent",
196                              " -",
197                              " 2>/dev/null",
198                              " | sed",
199                              " -e", " \'s/^/\\//\'",
200                              NULL);
201         write_tapeheader();
202
203         start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
204
205         dumpkeys = stralloc(level_str);
206         dumppid = pipespawn(progname, STDIN_PIPE,
207                             &dumpin, &dumpout, &mesgf,
208                             "xfsdump",
209                             options->no_record ? "-J" : skip_argument,
210                             "-F",
211                             "-l", dumpkeys,
212                             "-",
213                             device,
214                             NULL);
215     }
216     else
217 #endif                                                  /* } */
218 #ifdef VXDUMP                                           /* { */
219 #ifdef DUMP
220     if (strcmp(amname_to_fstype(amdevice), "vxfs") == 0)
221 #else
222     if (1)
223 #endif
224     {
225 #ifdef USE_RUNDUMP
226         char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump",
227                                             versionsuffix(), NULL);
228 #else
229         char *progname = cmd = newvstralloc(cmd, VXDUMP, NULL);
230 #endif
231         program->backup_name  = VXDUMP;
232         program->restore_name = VXRESTORE;
233
234         dumpkeys = vstralloc(level_str,
235                              options->no_record ? "" : "u",
236                              "s",
237                              "f",
238                              NULL);
239
240         indexcmd = vstralloc(VXRESTORE,
241                              " -tvf", " -",
242                              " 2>/dev/null",
243                              " | ",
244                              LEAF_AND_DIRS,
245                              NULL);
246         write_tapeheader();
247
248         start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
249
250         dumppid = pipespawn(progname, STDIN_PIPE,
251                             &dumpin, &dumpout, &mesgf, 
252                             "vxdump",
253                             dumpkeys,
254                             "1048576",
255                             "-",
256                             device,
257                             NULL);
258     }
259     else
260 #endif                                                  /* } */
261
262 #ifdef VDUMP                                            /* { */
263 #ifdef DUMP
264     if (strcmp(amname_to_fstype(amdevice), "advfs") == 0)
265 #else
266     if (1)
267 #endif
268     {
269         char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump",
270                                             versionsuffix(), NULL);
271         device = newstralloc(device, amname_to_dirname(amdevice));
272         program->backup_name  = VDUMP;
273         program->restore_name = VRESTORE;
274
275         dumpkeys = vstralloc(level_str,
276                              options->no_record ? "" : "u",
277                              "b",
278                              "f",
279                              NULL);
280
281         indexcmd = vstralloc(VRESTORE,
282                              " -tvf", " -",
283                              " 2>/dev/null",
284                              " | ",
285                              "sed -e \'\n/^\\./ {\ns/^\\.//\ns/, [0-9]*$//\ns/^\\.//\ns/ @-> .*$//\nt\n}\nd\n\'",
286                              NULL);
287         write_tapeheader();
288
289         start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
290
291         dumppid = pipespawn(cmd, STDIN_PIPE,
292                             &dumpin, &dumpout, &mesgf, 
293                             "vdump",
294                             dumpkeys,
295                             "60",
296                             "-",
297                             device,
298                             NULL);
299     }
300     else
301 #endif                                                  /* } */
302
303     {
304 #ifndef RESTORE
305 #define RESTORE "restore"
306 #endif
307
308         dumpkeys = vstralloc(level_str,
309                              options->no_record ? "" : "u",
310                              "s",
311 #ifdef HAVE_HONOR_NODUMP
312                              "h",
313 #endif
314                              "f",
315                              NULL);
316
317         indexcmd = vstralloc(RESTORE,
318                              " -tvf", " -",
319                              " 2>&1",
320                              /* not to /dev/null because of DU's dump */
321                              " | ",
322                              LEAF_AND_DIRS,
323                              NULL);
324         write_tapeheader();
325
326         start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
327
328         dumppid = pipespawn(cmd, STDIN_PIPE,
329                             &dumpin, &dumpout, &mesgf, 
330                             "dump",
331                             dumpkeys,
332                             "1048576",
333 #ifdef HAVE_HONOR_NODUMP
334                             "0",
335 #endif
336                             "-",
337                             device,
338                             NULL);
339     }
340 #else                                                   /* } { */
341     /* AIX backup program */
342     dumpkeys = vstralloc("-",
343                          level_str,
344                          options->no_record ? "" : "u",
345                          "f",
346                          NULL);
347
348     indexcmd = vstralloc(RESTORE,
349                          " -B",
350                          " -tvf", " -",
351                          " 2>/dev/null",
352                          " | ",
353                          LEAF_AND_DIRS,
354                          NULL);
355     write_tapeheader();
356
357     start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
358
359     dumppid = pipespawn(cmd, STDIN_PIPE,
360                         &dumpin, &dumpout, &mesgf, 
361                         "backup",
362                         dumpkeys,
363                         "-",
364                         device,
365                         NULL);
366 #endif                                                  /* } */
367
368     amfree(dumpkeys);
369     amfree(device);
370     amfree(cmd);
371     amfree(indexcmd);
372
373     /* close the write ends of the pipes */
374
375     aclose(dumpin);
376     aclose(dumpout);
377     aclose(dataf);
378     aclose(mesgf);
379     if (options->createindex)
380         aclose(indexf);
381 }
382
383 static void end_backup(status)
384 int status;
385 {
386     /* don't need to do anything for dump */
387 }
388
389 backup_program_t dump_program = {
390   "DUMP",
391 #ifdef DUMP
392   DUMP
393 #else
394   "dump"
395 #endif
396   ,
397   RESTORE
398   ,
399   re_table, start_backup, end_backup
400 };