56502e2c4cd353f19cbc59eab2b45089c5bdb5ce
[platform/upstream/dosfstools.git] / src / fatlabel.c
1 /* fatlabel.c - User interface
2
3    Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch>
4    Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
5    Copyright (C) 2007 Red Hat, Inc.
6    Copyright (C) 2008-2013 Daniel Baumann <mail@daniel-baumann.ch>
7
8    This program is free software: you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation, either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21    On Debian systems, the complete text of the GNU General Public License
22    can be found in /usr/share/common-licenses/GPL-3 file.
23 */
24
25 #include "version.h"
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <getopt.h>
33 #include <ctype.h>
34
35 #include "common.h"
36 #include "fsck.fat.h"
37 #include "io.h"
38 #include "boot.h"
39 #include "fat.h"
40 #include "file.h"
41 #include "check.h"
42
43 int interactive = 0, rw = 0, list = 0, test = 0, verbose = 0, write_immed = 0;
44 int atari_format = 0;
45 unsigned n_files = 0;
46 void *mem_queue = NULL;
47
48 static void usage(int error)
49 {
50     FILE *f = error ? stderr : stdout;
51     int status = error ? 1 : 0;
52
53     fprintf(f, "usage: fatlabel device [label]\n");
54     exit(status);
55 }
56
57 /*
58  * ++roman: On m68k, check if this is an Atari; if yes, turn on Atari variant
59  * of MS-DOS filesystem by default.
60  */
61 static void check_atari(void)
62 {
63 #ifdef __mc68000__
64     FILE *f;
65     char line[128], *p;
66
67     if (!(f = fopen("/proc/hardware", "r"))) {
68         perror("/proc/hardware");
69         return;
70     }
71
72     while (fgets(line, sizeof(line), f)) {
73         if (strncmp(line, "Model:", 6) == 0) {
74             p = line + 6;
75             p += strspn(p, " \t");
76             if (strncmp(p, "Atari ", 6) == 0)
77                 atari_format = 1;
78             break;
79         }
80     }
81     fclose(f);
82 #endif
83 }
84
85 int main(int argc, char *argv[])
86 {
87     DOS_FS fs = {0};
88     rw = 0;
89
90     int i;
91
92     char *device = NULL;
93     char label[12] = {0};
94
95     loff_t offset;
96     DIR_ENT de;
97
98     check_atari();
99
100     if (argc < 2 || argc > 3)
101         usage(1);
102
103     if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
104         usage(0);
105     else if (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")) {
106         printf("fatlabel " VERSION ", " VERSION_DATE ", FAT32, LFN\n");
107         exit(0);
108     }
109
110     device = argv[1];
111     if (argc == 3) {
112         strncpy(label, argv[2], 11);
113         if (strlen(argv[2]) > 11) {
114             fprintf(stderr,
115                     "fatlabel: labels can be no longer than 11 characters\n");
116             exit(1);
117         }
118         for (i = 0; label[i] && i < 11; i++)
119           /* don't know if here should be more strict !uppercase(label[i])*/
120           if (islower(label[i])) {
121             fprintf(stderr,
122                     "fatlabel: labels cannot contain lower case characters\n");
123             exit(1);
124           }
125         rw = 1;
126     }
127
128     fs_open(device, rw);
129     read_boot(&fs);
130     if (fs.fat_bits == 32)
131         read_fat(&fs);
132     if (!rw) {
133         offset = find_volume_de(&fs, &de);
134         if (offset == 0)
135           fprintf(stdout, "%s\n", fs.label);
136         else
137           fprintf(stdout, "%.8s%.3s\n", de.name, de.ext);
138         exit(0);
139     }
140
141     write_label(&fs, label);
142     fs_close(rw);
143     return 0;
144 }