ca5e1c9e418dd0c34c79666fa489cd3d8ab65fdf
[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     if((pgm = strrchr(argv[0], '/')) != NULL) {
160         pgm++;
161     } else {
162         pgm = argv[0];
163     }
164     tapename = getenv("TAPE");
165     while(-1 != (ch = getopt(argc, argv, "df:t:"))) {
166         switch(ch) {
167         case 'd':
168             debug_ammt = 1;
169             fprintf(stderr, "debug mode!\n");
170             break;
171         case 'f':
172         case 't':
173             tapename = stralloc(optarg);
174             break;
175         default:
176             usage();
177             /* NOTREACHED */
178         }
179     }
180     if(optind >= argc) {
181         usage();
182         /* NOTREACHED */
183     }
184
185     /*
186      * Compute the minimum abbreviation for each command.
187      */
188     for(i = 0; cmd[i].name; i++) {
189         cmd[i].min_chars = 1;
190         while (1) {
191             for(j = 0; cmd[j].name; j++) {
192                 if(i == j) {
193                     continue;
194                 }
195                 if(0 == strncmp(cmd[i].name, cmd[j].name, cmd[i].min_chars)) {
196                     break;
197                 }
198             }
199             if(0 == cmd[j].name) {
200                 break;
201             }
202             cmd[i].min_chars++;
203         }
204         if(debug_ammt) {
205             fprintf(stderr, "syntax: %-20s -> %*.*s\n",
206                             cmd[i].name,
207                             cmd[i].min_chars,
208                             cmd[i].min_chars,
209                             cmd[i].name);
210         }
211     }
212
213     /*
214      * Process the command.
215      */
216     s = "unknown";
217     j = strlen(argv[optind]);
218     for(i = 0; cmd[i].name; i++) {
219         if(0 == strncmp(cmd[i].name, argv[optind], j)) {
220             if(j >= cmd[i].min_chars) {
221                 break;
222             }
223             s = "ambiguous";
224         }
225     }
226     if(0 == cmd[i].name) {
227         fprintf(stderr, "%s: %s command: %s\n", pgm, s, argv[optind]);
228         exit(1);
229     }
230     optind++;
231     if(0 == tapename) {
232         fprintf(stderr, "%s: -f device or -t device is required\n", pgm);
233         exit(1);
234     }
235     if(debug_ammt) {
236         fprintf(stderr, "tapename is \"%s\"\n", tapename);
237     }
238
239     count = 1;
240     if(optind < argc && cmd[i].count) {
241         count = atoi(argv[optind]);
242     }
243
244     if(debug_ammt) {
245         fprintf(stderr, "calling tape_open(\"%s\",%d)\n", tapename, cmd[i].flags);
246     }
247     if((fd = tape_open(tapename, cmd[i].flags)) < 0) {
248         goto report_error;
249     }
250
251     if(debug_ammt) {
252         fprintf(stderr, "processing %s(%d)\n", cmd[i].name, count);
253     }
254     if(0 != (*cmd[i].func)(fd, count)) {
255         goto report_error;
256     }
257
258     (void)tapefd_close(fd);
259
260     exit(0);
261
262 report_error:
263
264     save_errno = errno;
265     fprintf(stderr, "%s %s", tapename, cmd[i].name);
266     if(cmd[i].count) {
267         fprintf(stderr, " %d", count);
268     }
269     errno = save_errno;
270     perror(" failed");
271     exit(1);
272 }