8a9e391bfa2338ba2cc0b943c17a794d4db75905
[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 usage(void);
29
30 static void
31 usage(void)
32 {
33     g_fprintf(stderr, _("usage: %s "), pgm);
34     g_fprintf(stderr, _(" [-d]"));
35     g_fprintf(stderr, _(" [-l length]"));
36     g_fprintf(stderr, _(" [if=input]"));
37     g_fprintf(stderr, _(" [of=output]"));
38     g_fprintf(stderr, _(" [bs=blocksize]"));
39     g_fprintf(stderr, _(" [count=count]"));
40     g_fprintf(stderr, _(" [skip=count]"));
41     g_fprintf(stderr, _("\n"));
42     exit(1);
43 }
44
45 static ssize_t (*read_func)(int, void *, size_t);
46 static ssize_t (*write_func)(int, const void *, size_t);
47
48 int
49 main(
50     int         argc,
51     char **     argv)
52 {
53     int infd = 0;                               /* stdin */
54     int outfd = 1;                              /* stdout */
55     size_t blocksize = 512;
56     off_t skip = (off_t)0;
57     ssize_t len;
58     int pread, fread, pwrite, fwrite;
59     int res = 0;
60     char *buf;
61     off_t count = (off_t)0;
62     int have_count = 0;
63     int save_errno;
64     int ch;
65     char *eq;
66     off_t length = (off_t)0;
67     int have_length = 0;
68
69     /*
70      * Configure program for internationalization:
71      *   1) Only set the message locale for now.
72      *   2) Set textdomain for all amanda related programs to "amanda"
73      *      We don't want to be forced to support dozens of message catalogs.
74      */  
75     setlocale(LC_MESSAGES, "C");
76     textdomain("amanda"); 
77
78     fprintf(stderr, _("amdd is deprecated\n"));
79
80     if((pgm = strrchr(argv[0], '/')) != NULL) {
81         pgm++;
82     } else {
83         pgm = argv[0];
84     }
85     while(-1 != (ch = getopt(argc, argv, "hdl:"))) {
86         switch(ch) {
87         case 'd':
88             debug_amdd = 1;
89             g_fprintf(stderr, _("debug mode!\n"));
90             break;
91
92 #ifndef __lint
93         case 'l':
94             have_length = 1;
95             length = OFF_T_ATOI(optarg);
96             len = (ssize_t)strlen(optarg);
97             if(len > 0) {
98                 switch(optarg[len-1] ) {
99                 case 'k':                               break;
100                 case 'b': length /= (off_t)2;           break;
101                 case 'M': length *= (off_t)1024;        break;
102                 default:  length /= (off_t)1024;        break;
103                 }
104             } else {
105                 length /= (off_t)1024;
106             }
107             break;
108 #endif
109         case 'h':
110         default:
111             usage();
112             /*NOTREACHED*/
113         }
114     }
115
116     /*@ignore@*/
117     read_func = read;
118     write_func = write;
119     /*@end@*/
120     for( ; optind < argc; optind++) {
121         if(0 == (eq = strchr(argv[optind], '='))) {
122             usage();
123             /*NOTREACHED*/
124         }
125         len = (ssize_t)(eq - argv[optind]);
126         if(0 == strncmp("if", argv[optind], (size_t)len)) {
127             if((infd = tape_open(eq + 1, O_RDONLY, 0)) < 0) {
128                 save_errno = errno;
129                 g_fprintf(stderr, "%s: %s: ", pgm, eq + 1);
130                 errno = save_errno;
131                 perror("open");
132                 return 1;
133             }
134             read_func = tapefd_read;
135             if(debug_amdd) {
136                 g_fprintf(stderr, _("input opened \"%s\", got fd %d\n"),
137                                 eq + 1, infd);
138             }
139         } else if(0 == strncmp("of", argv[optind], (size_t)len)) {
140             if((outfd = tape_open(eq + 1, O_RDWR|O_CREAT|O_TRUNC, 0644)) < 0) {
141                 save_errno = errno;
142                 g_fprintf(stderr, "%s: %s: ", pgm, eq + 1);
143                 errno = save_errno;
144                 perror("open");
145                 return 1;
146             }
147             write_func = tapefd_write;
148             if(debug_amdd) {
149                 g_fprintf(stderr, _("output opened \"%s\", got fd %d\n"),
150                                 eq + 1, outfd);
151             }
152             if(have_length) {
153                 if(debug_amdd) {
154                     g_fprintf(stderr, _("length set to %lld\n"),
155                         (long long)length);
156                 }
157                 tapefd_setinfo_length(outfd, length);
158             }
159         } else if(0 == strncmp("bs", argv[optind], (size_t)len)) {
160             blocksize = SIZE_T_ATOI(eq + 1);
161             len = (ssize_t)strlen(argv[optind]);
162             if(len > 0) {
163                 switch(argv[optind][len-1] ) {
164                 case 'k': blocksize *= 1024;            break;
165                 case 'b': blocksize *= 512;             break;
166                 case 'M': blocksize *= 1024 * 1024;     break;
167                 }
168             }
169             if(debug_amdd) {
170                 g_fprintf(stderr, _("blocksize set to %zu\n"), blocksize);
171             }
172         } else if(0 == strncmp("count", argv[optind], (size_t)len)) {
173             count = OFF_T_ATOI(eq + 1);
174             have_count = 1;
175             if(debug_amdd) {
176                 g_fprintf(stderr, _("count set to %lld\n"), (long long)count);
177             }
178         } else if(0 == strncmp("skip", argv[optind], (size_t)len)) {
179             skip = OFF_T_ATOI(eq + 1);
180             if(debug_amdd) {
181                 g_fprintf(stderr, _("skip set to %lld\n"), (long long)skip);
182             }
183         } else {
184             g_fprintf(stderr, _("%s: bad argument: \"%s\"\n"), pgm, argv[optind]);
185             return 1;
186         }
187     }
188
189     if(0 == (buf = malloc(blocksize))) {
190         save_errno = errno;
191         g_fprintf(stderr, "%s: ", pgm);
192         errno = save_errno;
193         perror(_("malloc error"));
194         return 1;
195     }
196
197     eq = _("read error");
198     pread = fread = pwrite = fwrite = 0;
199     while(0 < (len = (*read_func)(infd, buf, blocksize))) {
200         if((skip -= (off_t)1) > (off_t)0) {
201             continue;
202         }
203         if((size_t)len == blocksize) {
204             fread++;
205         } else if(len > 0) {
206             pread++;
207         }
208         len = (*write_func)(outfd, buf, (size_t)len);
209         if(len < 0) {
210             eq = _("write error");
211             break;
212         } else if((size_t)len == blocksize) {
213             fwrite++;
214         } else if(len > 0) {
215             pwrite++;
216         }
217         if(have_count) {
218             if((count -= (off_t)1) <= (off_t)0) {
219                 len = 0;
220                 break;
221             }
222         }
223     }
224     if(len < 0) {
225         save_errno = errno;
226         g_fprintf(stderr, "%s: ", pgm);
227         errno = save_errno;
228         perror(eq);
229         res = 1;
230     }
231     g_fprintf(stderr, _("%d+%d in\n%d+%d out\n"), fread, pread, fwrite, pwrite);
232     if(read_func == tapefd_read) {
233         if(0 != tapefd_close(infd)) {
234             save_errno = errno;
235             g_fprintf(stderr, "%s: ", pgm);
236             errno = save_errno;
237             perror(_("input close"));
238             res = 1;
239         }
240     }
241     if(write_func == tapefd_write) {
242         if(0 != tapefd_close(outfd)) {
243             save_errno = errno;
244             g_fprintf(stderr, "%s: ", pgm);
245             errno = save_errno;
246             perror(_("output close"));
247             res = 1;
248         }
249     }
250     return res;
251 }