1 /*
2    Bacula(R) - The Network Backup Solution
3 
4    Copyright (C) 2000-2020 Kern Sibbald
5 
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8 
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13 
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16 
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  * Program for determining file system type
21  *
22  *   Written by Preben 'Peppe' Guldberg, December MMIV
23  */
24 
25 #include "bacula.h"
26 #include "findlib/find.h"
27 
usage()28 static void usage()
29 {
30    fprintf(stderr, _(
31 "\n"
32 "Usage: fstype [-v] path ...\n"
33 "\n"
34 "       Print the file system type for each file/directory argument given.\n"
35 "       The following options are supported:\n"
36 "\n"
37 "       -l     print all file system types in mtab.\n"
38 "       -m     print full entries in mtab.\n"
39 "       -v     print both path and file system type of each argument.\n"
40 "       -?     print this message.\n"
41 "\n"));
42 
43    exit(1);
44 }
45 
46 struct mtab_item {
47    rblink link;
48    uint64_t dev;
49    char fstype[1];
50 };
51 
52 /* Compare two device types */
compare_mtab_items(void * item1,void * item2)53 static int compare_mtab_items(void *item1, void *item2)
54 {
55    mtab_item *mtab1, *mtab2;
56    mtab1 = (mtab_item *)item1;
57    mtab2 = (mtab_item *)item2;
58    if (mtab1->dev < mtab2->dev) return -1;
59    if (mtab1->dev > mtab2->dev) return 1;
60    return 0;
61 }
62 
print_mtab_item(void * user_ctx,struct stat * st,const char * fstype,const char * mountpoint,const char * mntopts,const char * fsname)63 void print_mtab_item(void *user_ctx, struct stat *st, const char *fstype,
64                       const char *mountpoint, const char *mntopts,
65                       const char *fsname)
66 {
67    fprintf(stderr, "dev=%p fstype=%s mountpoint=%s mntopts=%s\n",
68       ((void *)st->st_dev), fstype, mountpoint, mntopts);
69 }
70 
add_mtab_item(void * user_ctx,struct stat * st,const char * fstype,const char * mountpoint,const char * mntopts,const char * fsname)71 static void add_mtab_item(void *user_ctx, struct stat *st, const char *fstype,
72                const char *mountpoint, const char *mntopts,
73                const char *fsname)
74 {
75    rblist *mtab_list = (rblist *)user_ctx;
76    mtab_item *item, *ritem;
77    int len = strlen(fstype) + 1;
78 
79    item = (mtab_item *)malloc(sizeof(mtab_item) + len);
80    item->dev = (uint64_t)st->st_dev;
81    bstrncpy(item->fstype, fstype, len);
82    //fprintf(stderr, "Add dev=%lx fstype=%s\n", item->dev, item->fstype);
83    ritem = (mtab_item *)mtab_list->insert((void *)item, compare_mtab_items);
84    if (ritem != item) {
85       fprintf(stderr, "Problem!! Returned item not equal added item\n");
86    }
87    //fprintf(stderr, "dev=%p fstype=%s mountpoint=%s mntopts=%s\n",
88    //   ((void *)st->st_dev), fstype, mountpoint, mntopts);
89 }
90 
91 
main(int argc,char * const * argv)92 int main (int argc, char *const *argv)
93 {
94    char fs[1000];
95    bool verbose = false;
96    bool list = false;
97    bool mtab = false;
98    int status = 0;
99    int ch, i;
100 
101    setlocale(LC_ALL, "");
102    bindtextdomain("bacula", LOCALEDIR);
103    textdomain("bacula");
104 
105    while ((ch = getopt(argc, argv, "lmv?")) != -1) {
106       switch (ch) {
107          case 'l':
108             list = true;
109             break;
110          case 'm':
111             mtab = true; /* list mtab */
112             break;
113          case 'v':
114             verbose = true;
115             break;
116          case '?':
117          default:
118             usage();
119 
120       }
121    }
122    argc -= optind;
123    argv += optind;
124 
125 
126    OSDependentInit();
127 
128    if (mtab) {
129       read_mtab(print_mtab_item, NULL);
130       status = 1;
131       goto get_out;
132    }
133    if (list) {
134       rblist *mtab_list;
135       mtab_item *item;
136       mtab_list = New(rblist());
137       read_mtab(add_mtab_item, mtab_list);
138       fprintf(stderr, "Size of mtab=%d\n", mtab_list->size());
139       foreach_rblist(item, mtab_list) {
140          fprintf(stderr, "Found dev=%lx fstype=%s\n", item->dev, item->fstype);
141       }
142       delete mtab_list;
143       goto get_out;
144    }
145 
146    if (argc < 1) {
147       usage();
148    }
149    for (i = 0; i < argc; --argc, ++argv) {
150       FF_PKT ff_pkt;
151       memset((void *)&ff_pkt, 0, sizeof(ff_pkt));
152       ff_pkt.fname = ff_pkt.link = *argv;
153       if (lstat(ff_pkt.fname, &ff_pkt.statp) != 0) {
154          fprintf(stderr, "lstat of %s failed.\n", ff_pkt.fname);
155          status = 1;
156          break;
157       }
158       if (fstype(&ff_pkt, fs, sizeof(fs))) {
159          if (verbose) {
160             printf("%s: %s\n", *argv, fs);
161          } else {
162             puts(fs);
163          }
164       } else {
165          fprintf(stderr, _("%s: unknown file system type\n"), *argv);
166          status = 1;
167       }
168    }
169 
170 get_out:
171    exit(status);
172 }
173