e84fe36fd4791eea231ffb0a9cf98b1b8b7c07ee
[rsync/rsync.git] / batch.c
1 /* -*- c-file-style: "linux" -*-
2
3    Weiss 1/1999
4    Batch utilities for rsync.
5
6 */
7
8 #include "rsync.h"
9 #include <time.h>
10
11 extern char *batch_name;
12 extern int delete_mode;
13 extern int delete_excluded;
14
15 static void write_arg(int fd, char *arg)
16 {
17         char *x, *s;
18
19         if (*arg == '-' && (x = strchr(arg, '=')) != NULL) {
20                 write(fd, arg, x - arg + 1);
21                 arg += x - arg + 1;
22         }
23
24         if (strpbrk(arg, " \"'&;|[]()$#!*?^\\") != NULL) {
25                 write(fd, "'", 1);
26                 for (s = arg; (x = strchr(s, '\'')) != NULL; s = x + 1) {
27                         write(fd, s, x - s + 1);
28                         write(fd, "'", 1);
29                 }
30                 write(fd, s, strlen(s));
31                 write(fd, "'", 1);
32                 return;
33         }
34
35         write(fd, arg, strlen(arg));
36 }
37
38 /* This routine tries to write out an equivalent --read-batch command
39  * given the user's --write-batch args.  However, it doesn't really
40  * understand most of the options, so it uses some overly simple
41  * heuristics to munge the command line into something that will
42  * (hopefully) work. */
43 void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
44 {
45         int fd, i;
46         char *p, filename[MAXPATHLEN];
47         int need_excludes = delete_mode && !delete_excluded;
48
49         stringjoin(filename, sizeof filename,
50                    batch_name, ".sh", NULL);
51         fd = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
52                      S_IRUSR | S_IWUSR | S_IEXEC);
53         if (fd < 0) {
54                 rsyserr(FERROR, errno, "Batch file %s open error", filename);
55                 exit_cleanup(1);
56         }
57
58         /* Write argvs info to BATCH.sh file */
59         write_arg(fd, argv[0]);
60         for (i = 1; i < argc - file_arg_cnt; i++) {
61                 p = argv[i];
62                 if (strncmp(p, "--files-from", 12) == 0
63                     || (!need_excludes && (strncmp(p, "--include", 9) == 0
64                                         || strncmp(p, "--exclude", 9) == 0))) {
65                         if (strchr(p, '=') == NULL)
66                                 i++;
67                         continue;
68                 }
69                 write(fd, " ", 1);
70                 if (strncmp(p, "--write-batch", 13) == 0) {
71                         write(fd, "--read-batch", 12);
72                         if (p[13] == '=') {
73                                 write(fd, "=", 1);
74                                 write_arg(fd, p + 14);
75                         }
76                 } else
77                         write_arg(fd, p);
78         }
79         if ((p = find_colon(argv[argc - 1])) != NULL) {
80                 if (*++p == ':')
81                         p++;
82         } else
83                 p = argv[argc - 1];
84         write(fd, " ${1:-", 6);
85         write_arg(fd, p);
86         if (write(fd, "}\n", 2) != 2 || close(fd) < 0) {
87                 rsyserr(FERROR, errno, "Batch file %s write error", filename);
88                 exit_cleanup(1);
89         }
90 }
91
92 void show_flist(int index, struct file_struct **fptr)
93 {
94         /*  for debugging    show_flist(flist->count, flist->files * */
95
96         int i;
97         for (i = 0; i < index; i++) {
98                 rprintf(FINFO, "flist->flags=%#x\n", fptr[i]->flags);
99                 rprintf(FINFO, "flist->modtime=%#lx\n",
100                         (long unsigned) fptr[i]->modtime);
101                 rprintf(FINFO, "flist->length=%.0f\n",
102                         (double) fptr[i]->length);
103                 rprintf(FINFO, "flist->mode=%#o\n", (int) fptr[i]->mode);
104                 rprintf(FINFO, "flist->basename=%s\n", fptr[i]->basename);
105                 if (fptr[i]->dirname)
106                         rprintf(FINFO, "flist->dirname=%s\n",
107                                 fptr[i]->dirname);
108                 if (fptr[i]->basedir)
109                         rprintf(FINFO, "flist->basedir=%s\n",
110                                 fptr[i]->basedir);
111         }
112 }
113
114 void show_argvs(int argc, char *argv[])
115 {
116         /*  for debugging  * */
117
118         int i;
119         rprintf(FINFO, "BATCH.C:show_argvs,argc=%d\n", argc);
120         for (i = 0; i < argc; i++) {
121                 /*    if (argv[i])   */
122                 rprintf(FINFO, "i=%d,argv[i]=%s\n", i, argv[i]);
123
124         }
125 }