3f21b1198283718f983c2e86a7ba8dcde8ed3ff9
[debian/amanda] / tape-src / amdd.c
1 #ifdef NO_AMANDA
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <sys/stat.h>
9
10 #include "output-rait.h"
11
12 #define tape_open       rait_open
13 #define tapefd_read     rait_read
14 #define tapefd_write    rait_write
15 #define tapefd_setinfo_length(outfd, length)
16 #define tapefd_close    rait_close
17
18 #else
19 #include "amanda.h"
20 #include "tapeio.h"
21 #endif
22
23 extern int optind;
24
25 static int debug_amdd = 0;
26 static char *pgm = NULL;
27
28 static void
29 usage()
30 {
31     fprintf(stderr, "usage: %s ", pgm);
32     fprintf(stderr, " [-d]");
33     fprintf(stderr, " [-l length]");
34     fprintf(stderr, " [if=input]");
35     fprintf(stderr, " [of=output]");
36     fprintf(stderr, " [bs=blocksize]");
37     fprintf(stderr, " [count=count]");
38     fprintf(stderr, " [skip=count]");
39     fprintf(stderr, "\n");
40     exit(1);
41 }
42
43 int
44 main(int argc, char **argv) {
45     int infd = 0;                               /* stdin */
46     int outfd = 1;                              /* stdout */
47     int blocksize = 512;
48     int skip=0;
49     int len;
50     int pread, fread, pwrite, fwrite;
51     int res = 0;
52     char *buf;
53     int count = 0;
54     int have_count = 0;
55     int save_errno;
56     int ch;
57     char *eq;
58     int length = 0;
59     int have_length = 0;
60     ssize_t (*read_func)(int, void *, size_t);
61     ssize_t (*write_func)(int, const void *, size_t);
62
63     if((pgm = strrchr(argv[0], '/')) != NULL) {
64         pgm++;
65     } else {
66         pgm = argv[0];
67     }
68     while(-1 != (ch = getopt(argc, argv, "hdl:"))) {
69         switch(ch) {
70         case 'd':
71             debug_amdd = 1;
72             fprintf(stderr, "debug mode!\n");
73             break;
74         case 'l':
75             have_length = 1;
76             length = atoi(optarg);
77             len = strlen(optarg);
78             if(len > 0) {
79                 switch(optarg[len-1] ) {
80                 case 'k':                               break;
81                 case 'b': length /= 2;                  break;
82                 case 'M': length *= 1024;               break;
83                 default:  length /= 1024;               break;
84                 }
85             } else {
86                 length /= 1024;
87             }
88             break;
89         case 'h':
90         default:
91             usage();
92             /* NOTREACHED */
93         }
94     }
95
96     read_func = read;
97     write_func = write;
98     for( ; optind < argc; optind++) {
99         if(0 == (eq = strchr(argv[optind], '='))) {
100             usage();
101             /* NOTREACHED */
102         }
103         len = eq - argv[optind];
104         if(0 == strncmp("if", argv[optind], len)) {
105             if((infd = tape_open(eq + 1, O_RDONLY)) < 0) {
106                 save_errno = errno;
107                 fprintf(stderr, "%s: %s: ", pgm, eq + 1);
108                 errno = save_errno;
109                 perror("open");
110                 return 1;
111             }
112             read_func = tapefd_read;
113             if(debug_amdd) {
114                 fprintf(stderr, "input opened \"%s\", got fd %d\n",
115                                 eq + 1, infd);
116             }
117         } else if(0 == strncmp("of", argv[optind], len)) {
118             if((outfd = tape_open(eq + 1, O_RDWR|O_CREAT|O_TRUNC, 0644)) < 0) {
119                 save_errno = errno;
120                 fprintf(stderr, "%s: %s: ", pgm, eq + 1);
121                 errno = save_errno;
122                 perror("open");
123                 return 1;
124             }
125             write_func = tapefd_write;
126             if(debug_amdd) {
127                 fprintf(stderr, "output opened \"%s\", got fd %d\n",
128                                 eq + 1, outfd);
129             }
130             if(have_length) {
131                 if(debug_amdd) {
132                     fprintf(stderr, "length set to %d\n", length);
133                 }
134                 tapefd_setinfo_length(outfd, length);
135             }
136         } else if(0 == strncmp("bs", argv[optind], len)) {
137             blocksize = atoi(eq + 1);
138             len = strlen(argv[optind]);
139             if(len > 0) {
140                 switch(argv[optind][len-1] ) {
141                 case 'k': blocksize *= 1024;            break;
142                 case 'b': blocksize *= 512;             break;
143                 case 'M': blocksize *= 1024 * 1024;     break;
144                 }
145             }
146             if(debug_amdd) {
147                 fprintf(stderr, "blocksize set to %d\n", blocksize);
148             }
149         } else if(0 == strncmp("count", argv[optind], len)) {
150             count = atoi(eq + 1);
151             have_count = 1;
152             if(debug_amdd) {
153                 fprintf(stderr, "count set to %d\n", count);
154             }
155         } else if(0 == strncmp("skip", argv[optind], len)) {
156             skip = atoi(eq + 1);
157             if(debug_amdd) {
158                 fprintf(stderr, "skip set to %d\n", skip);
159             }
160         } else {
161             fprintf(stderr, "%s: bad argument: \"%s\"\n", pgm, argv[optind]);
162             return 1;
163         }
164     }
165
166     if(0 == (buf = malloc(blocksize))) {
167         save_errno = errno;
168         fprintf(stderr, "%s: ", pgm);
169         errno = save_errno;
170         perror("malloc error");
171         return 1;
172     }
173
174     eq = "read error";
175     pread = fread = pwrite = fwrite = 0;
176     while(0 < (len = (*read_func)(infd, buf, blocksize))) {
177         if(skip-- > 0) {
178             continue;
179         }
180         if(len == blocksize) {
181             fread++;
182         } else if(len > 0) {
183             pread++;
184         }
185         len = (*write_func)(outfd, buf, len);
186         if(len < 0) {
187             eq = "write error";
188             break;
189         } else if(len == blocksize) {
190             fwrite++;
191         } else if(len > 0) {
192             pwrite++;
193         }
194         if(have_count) {
195             if(--count <= 0) {
196                 len = 0;
197                 break;
198             }
199         }
200     }
201     if(len < 0) {
202         save_errno = errno;
203         fprintf(stderr, "%s: ", pgm);
204         errno = save_errno;
205         perror(eq);
206         res = 1;
207     }
208     fprintf(stderr, "%d+%d in\n%d+%d out\n", fread, pread, fwrite, pwrite);
209     if(read_func == tapefd_read) {
210         if(0 != tapefd_close(infd)) {
211             save_errno = errno;
212             fprintf(stderr, "%s: ", pgm);
213             errno = save_errno;
214             perror("input close");
215             res = 1;
216         }
217     }
218     if(write_func == tapefd_write) {
219         if(0 != tapefd_close(outfd)) {
220             save_errno = errno;
221             fprintf(stderr, "%s: ", pgm);
222             errno = save_errno;
223             perror("output close");
224             res = 1;
225         }
226     }
227     return res;
228 }