Imported Upstream version 2.6.0p2
[debian/amanda] / tape-src / ammt.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 extern char *getenv();
13
14 #define tape_open       rait_open
15 #define tapefd_read     rait_read
16 #define tapefd_write    rait_write
17 #define tapefd_fsf      rait_tapefd_fsf
18 #define tapefd_rewind   rait_tapefd_rewind
19 #define tapefd_status   rait_tapefd_status
20 #define tapefd_unload   rait_tapefd_unload
21 #define tapefd_weof     rait_tapefd_weof
22 #define tapefd_setinfo_length(outfd, length)
23 #define tapefd_close    rait_close
24
25 #else
26 #include "amanda.h"
27 #include "tapeio.h"
28 #endif
29
30 extern int optind;
31
32 static int do_asf(int fd, off_t count);
33 static int do_bsf(int fd, off_t count);
34 static int do_status(int fd, off_t count);
35 static void usage(void);
36
37 struct cmd {
38     char *name;
39     size_t min_chars;
40     int count;
41     int (*func)(int, off_t);
42     int flags;
43 } cmd[] = {
44     { "eof",            0,      1,      tapefd_weof,    O_RDWR },
45     { "weof",           0,      1,      tapefd_weof,    O_RDWR },
46     { "fsf",            0,      1,      tapefd_fsf,     O_RDONLY },
47     { "asf",            0,      0,      do_asf,         O_RDONLY },
48     { "bsf",            0,      1,      do_bsf,         O_RDONLY },
49     { "rewind",         0,      0,      (int (*)(int, off_t))tapefd_rewind,
50                                                         O_RDONLY },
51     { "offline",        0,      0,      (int (*)(int, off_t))tapefd_unload,
52                                                         O_RDONLY },
53     { "rewoffl",        0,      0,      (int (*)(int, off_t))tapefd_unload,
54                                                         O_RDONLY },
55     { "status",         0,      0,      do_status,      O_RDONLY },
56     { NULL,             0,      0,      NULL,           0 }
57 };
58
59 static char *pgm;
60 static int debug_ammt = 0;
61
62 static char *tapename;
63
64 static int
65 do_asf(
66     int         fd,
67     off_t       count)
68 {
69     int r;
70
71     if(debug_ammt) {
72         g_fprintf(stderr, _("calling tapefd_rewind()\n"));
73     }
74     if(0 != (r = tapefd_rewind(fd))) {
75         return r;
76     }
77     if(debug_ammt) {
78         g_fprintf(stderr, _("calling tapefd_fsf(%lld)\n"), (long long)count);
79     }
80     return tapefd_fsf(fd, count);
81 }
82
83 static int
84 do_bsf(
85     int         fd,
86     off_t       count)
87 {
88     if(debug_ammt) {
89         g_fprintf(stderr, _("calling tapefd_fsf(%lld)\n"), (long long)-count);
90     }
91     return tapefd_fsf(fd, -count);
92 }
93
94 static int
95 do_status(
96     int         fd,
97     off_t       count)
98 {
99     int ret;
100     struct am_mt_status stat;
101
102     (void)count;        /* Quiet unused parameter warning */
103
104     if(debug_ammt) {
105         g_fprintf(stderr, _("calling tapefd_status()\n"));
106     }
107     if((ret = tapefd_status(fd, &stat)) != 0) {
108         return ret;
109     }
110     g_printf(_("%s status:"), tapename);
111     if(stat.online_valid) {
112         if(stat.online) {
113             fputs(_(" ONLINE"), stdout);
114         } else {
115             fputs(_(" OFFLINE"), stdout);
116         }
117     }
118     if(stat.bot_valid && stat.bot) {
119         fputs(_(" BOT"), stdout);
120     }
121     if(stat.eot_valid && stat.eot) {
122         fputs(_(" EOT"), stdout);
123     }
124     if(stat.protected_valid && stat.protected) {
125         fputs(_(" PROTECTED"), stdout);
126     }
127     if(stat.device_status_valid) {
128         g_printf(_(" ds == 0x%0*lx"),
129                stat.device_status_size * 2,
130                (unsigned long)stat.device_status);
131     }
132     if(stat.error_status_valid) {
133         g_printf(_(" er == 0x%0*lx"),
134                stat.error_status_size * 2,
135                (unsigned long)stat.error_status);
136     }
137     if(stat.fileno_valid) {
138         g_printf(_(" fileno == %ld"), stat.fileno);
139     }
140     if(stat.blkno_valid) {
141         g_printf(_(" blkno == %ld"), stat.blkno);
142     }
143
144     putchar('\n');
145     return 0;
146 }
147
148 static void
149 usage(void)
150 {
151     g_fprintf(stderr, _("usage: %s [-d] [-f|-t device] command [count]\n"), pgm);
152     exit(1);
153 }
154
155 int
156 main(
157     int         argc,
158     char **     argv)
159 {
160     int ch;
161     off_t count;
162     size_t i;
163     size_t j;
164     int fd;
165     int save_errno;
166     char *s;
167
168     /*
169      * Configure program for internationalization:
170      *   1) Only set the message locale for now.
171      *   2) Set textdomain for all amanda related programs to "amanda"
172      *      We don't want to be forced to support dozens of message catalogs.
173      */  
174     setlocale(LC_MESSAGES, "C");
175     textdomain("amanda"); 
176
177     fprintf(stderr, _("ammt is deprecated\n"));
178
179     /* Don't die when child closes pipe */
180     signal(SIGPIPE, SIG_IGN);
181
182     if((pgm = strrchr(argv[0], '/')) != NULL) {
183         pgm++;
184     } else {
185         pgm = argv[0];
186     }
187     tapename = getenv("TAPE");
188     while(-1 != (ch = getopt(argc, argv, "df:t:"))) {
189         switch(ch) {
190         case 'd':
191             debug_ammt = 1;
192             g_fprintf(stderr, _("debug mode!\n"));
193             break;
194         case 'f':
195         case 't':
196             tapename = stralloc(optarg);
197             break;
198         default:
199             usage();
200             /*NOTREACHED*/
201         }
202     }
203     if(optind >= argc) {
204         usage();
205         /*NOTREACHED*/
206     }
207
208     /*
209      * Compute the minimum abbreviation for each command.
210      */
211     for(i = 0; cmd[i].name; i++) {
212         cmd[i].min_chars = (size_t)1;
213         while (1) {
214             for(j = 0; cmd[j].name; j++) {
215                 if(i == j) {
216                     continue;
217                 }
218                 if(0 == strncmp(cmd[i].name, cmd[j].name,
219                                 cmd[i].min_chars)) {
220                     break;
221                 }
222             }
223             if(0 == cmd[j].name) {
224                 break;
225             }
226             cmd[i].min_chars++;
227         }
228         if(debug_ammt) {
229             g_fprintf(stderr, _("syntax: %-20s -> %*.*s\n"),
230                             cmd[i].name,
231                             (int)cmd[i].min_chars,
232                             (int)cmd[i].min_chars,
233                             cmd[i].name);
234         }
235     }
236
237     /*
238      * Process the command.
239      */
240     s = _("unknown");
241     j = strlen(argv[optind]);
242     for(i = 0; cmd[i].name; i++) {
243         if(0 == strncmp(cmd[i].name, argv[optind], j)) {
244             if(j >= cmd[i].min_chars) {
245                 break;
246             }
247             s = _("ambiguous");
248         }
249     }
250     if(0 == cmd[i].name) {
251         g_fprintf(stderr, _("%s: %s command: %s\n"), pgm, s, argv[optind]);
252         exit(1);
253     }
254     optind++;
255     if(0 == tapename) {
256         g_fprintf(stderr, _("%s: -f device or -t device is required\n"), pgm);
257         exit(1);
258     }
259     if(debug_ammt) {
260         g_fprintf(stderr, _("tapename is \"%s\"\n"), tapename);
261     }
262
263     count = (off_t)1;
264     if(optind < argc && cmd[i].count) {
265         count = OFF_T_ATOI(argv[optind]);
266     }
267
268     if(debug_ammt) {
269         g_fprintf(stderr, _("calling tape_open(\"%s\",%d)\n"), tapename, cmd[i].flags);
270     }
271     if((fd = tape_open(tapename, cmd[i].flags, 0)) < 0) {
272         goto report_error;
273     }
274
275     if(debug_ammt) {
276         g_fprintf(stderr, _("processing %s(%lld)\n"),
277                 cmd[i].name, (long long)count);
278     }
279     if(0 != (*cmd[i].func)(fd, count)) {
280         goto report_error;
281     }
282
283     (void)tapefd_close(fd);
284
285     exit(0);
286
287 report_error:
288
289     save_errno = errno;
290     g_fprintf(stderr, _("%s %s"), tapename, cmd[i].name);
291     if(cmd[i].count) {
292         g_fprintf(stderr, " %lld", (long long)count);
293     }
294     errno = save_errno;
295     perror(_(" failed"));
296     return (1); /* exit */
297 }