692b525eef8a0871b74e65890a9bdfe7536c7f63
[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();
33 static int do_bsf();
34 static int do_status();
35
36 struct cmd {
37     char *name;
38     int min_chars;
39     int count;
40     int (*func)();
41     int flags;
42 } cmd[] = {
43     { "eof",            0,      1,      tapefd_weof, O_RDWR },
44     { "weof",           0,      1,      tapefd_weof, O_RDWR },
45     { "fsf",            0,      1,      tapefd_fsf, O_RDONLY },
46     { "asf",            0,      0,      do_asf, O_RDONLY },
47     { "bsf",            0,      1,      do_bsf, O_RDONLY },
48     { "rewind",         0,      0,      tapefd_rewind, O_RDONLY },
49     { "offline",        0,      0,      tapefd_unload, O_RDONLY },
50     { "rewoffl",        0,      0,      tapefd_unload, O_RDONLY },
51     { "status",         0,      0,      do_status, O_RDONLY },
52     { NULL,             0,      0,      NULL }
53 };
54
55 static char *pgm;
56 static int debug_ammt = 0;
57
58 static char *tapename;
59
60 static int
61 do_asf(fd, count)
62     int fd;
63     int count;
64 {
65     int r;
66
67     if(debug_ammt) {
68         fprintf(stderr, "calling tapefd_rewind()\n");
69     }
70     if(0 != (r = tapefd_rewind(fd))) {
71         return r;
72     }
73     if(debug_ammt) {
74         fprintf(stderr, "calling tapefd_fsf(%d)\n", count);
75     }
76     return tapefd_fsf(fd, count);
77 }
78
79 static int
80 do_bsf(fd, count)
81     int fd;
82     int count;
83 {
84     if(debug_ammt) {
85         fprintf(stderr, "calling tapefd_fsf(%d)\n", -count);
86     }
87     return tapefd_fsf(fd, -count);
88 }
89
90 static int
91 do_status(fd, count)
92     int fd;
93     int count;
94 {
95     int ret;
96     struct am_mt_status stat;
97
98     if(debug_ammt) {
99         fprintf(stderr, "calling tapefd_status()\n");
100     }
101     if((ret = tapefd_status(fd, &stat)) != 0) {
102         return ret;
103     }
104     printf("%s status:", tapename);
105     if(stat.online_valid) {
106         if(stat.online) {
107             fputs(" ONLINE", stdout);
108         } else {
109             fputs(" OFFLINE", stdout);
110         }
111     }
112     if(stat.bot_valid && stat.bot) {
113         fputs(" BOT", stdout);
114     }
115     if(stat.eot_valid && stat.eot) {
116         fputs(" EOT", stdout);
117     }
118     if(stat.protected_valid && stat.protected) {
119         fputs(" PROTECTED", stdout);
120     }
121     if(stat.device_status_valid) {
122         printf(" ds == 0x%0*lx",
123                stat.device_status_size * 2,
124                (unsigned long)stat.device_status);
125     }
126     if(stat.error_status_valid) {
127         printf(" er == 0x%0*lx",
128                stat.error_status_size * 2,
129                (unsigned long)stat.error_status);
130     }
131     if(stat.fileno_valid) {
132         printf(" fileno == %ld", stat.fileno);
133     }
134     if(stat.blkno_valid) {
135         printf(" blkno == %ld", stat.blkno);
136     }
137
138     putchar('\n');
139     return 0;
140 }
141
142 static void
143 usage()
144 {
145     fprintf(stderr, "usage: %s [-d] [-f|-t device] command [count]\n", pgm);
146     exit(1);
147 }
148
149 int
150 main(int argc, char **argv) {
151     int ch;
152     int count;
153     int i;
154     int j;
155     int fd;
156     int save_errno;
157     char *s;
158
159     /* Don't die when child closes pipe */
160     signal(SIGPIPE, SIG_IGN);
161
162     if((pgm = strrchr(argv[0], '/')) != NULL) {
163         pgm++;
164     } else {
165         pgm = argv[0];
166     }
167     tapename = getenv("TAPE");
168     while(-1 != (ch = getopt(argc, argv, "df:t:"))) {
169         switch(ch) {
170         case 'd':
171             debug_ammt = 1;
172             fprintf(stderr, "debug mode!\n");
173             break;
174         case 'f':
175         case 't':
176             tapename = stralloc(optarg);
177             break;
178         default:
179             usage();
180             /* NOTREACHED */
181         }
182     }
183     if(optind >= argc) {
184         usage();
185         /* NOTREACHED */
186     }
187
188     /*
189      * Compute the minimum abbreviation for each command.
190      */
191     for(i = 0; cmd[i].name; i++) {
192         cmd[i].min_chars = 1;
193         while (1) {
194             for(j = 0; cmd[j].name; j++) {
195                 if(i == j) {
196                     continue;
197                 }
198                 if(0 == strncmp(cmd[i].name, cmd[j].name, cmd[i].min_chars)) {
199                     break;
200                 }
201             }
202             if(0 == cmd[j].name) {
203                 break;
204             }
205             cmd[i].min_chars++;
206         }
207         if(debug_ammt) {
208             fprintf(stderr, "syntax: %-20s -> %*.*s\n",
209                             cmd[i].name,
210                             cmd[i].min_chars,
211                             cmd[i].min_chars,
212                             cmd[i].name);
213         }
214     }
215
216     /*
217      * Process the command.
218      */
219     s = "unknown";
220     j = strlen(argv[optind]);
221     for(i = 0; cmd[i].name; i++) {
222         if(0 == strncmp(cmd[i].name, argv[optind], j)) {
223             if(j >= cmd[i].min_chars) {
224                 break;
225             }
226             s = "ambiguous";
227         }
228     }
229     if(0 == cmd[i].name) {
230         fprintf(stderr, "%s: %s command: %s\n", pgm, s, argv[optind]);
231         exit(1);
232     }
233     optind++;
234     if(0 == tapename) {
235         fprintf(stderr, "%s: -f device or -t device is required\n", pgm);
236         exit(1);
237     }
238     if(debug_ammt) {
239         fprintf(stderr, "tapename is \"%s\"\n", tapename);
240     }
241
242     count = 1;
243     if(optind < argc && cmd[i].count) {
244         count = atoi(argv[optind]);
245     }
246
247     if(debug_ammt) {
248         fprintf(stderr, "calling tape_open(\"%s\",%d)\n", tapename, cmd[i].flags);
249     }
250     if((fd = tape_open(tapename, cmd[i].flags)) < 0) {
251         goto report_error;
252     }
253
254     if(debug_ammt) {
255         fprintf(stderr, "processing %s(%d)\n", cmd[i].name, count);
256     }
257     if(0 != (*cmd[i].func)(fd, count)) {
258         goto report_error;
259     }
260
261     (void)tapefd_close(fd);
262
263     exit(0);
264
265 report_error:
266
267     save_errno = errno;
268     fprintf(stderr, "%s %s", tapename, cmd[i].name);
269     if(cmd[i].count) {
270         fprintf(stderr, " %d", count);
271     }
272     errno = save_errno;
273     perror(" failed");
274     exit(1);
275 }