source: trunk/minix/commands/i386/mtools-3.9.7/mlabel.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 5.1 KB
RevLine 
[9]1/*
2 * mlabel.c
3 * Make an MSDOS volume label
4 */
5
6#include "sysincludes.h"
7#include "msdos.h"
8#include "mainloop.h"
9#include "vfat.h"
10#include "mtools.h"
11#include "nameclash.h"
12
13char *label_name(char *filename, int verbose,
14 int *mangled, char *ans)
15{
16 int len;
17 int i;
18 int have_lower, have_upper;
19
20 strcpy(ans," ");
21 len = strlen(filename);
22 if(len > 11){
23 *mangled = 1;
24 len = 11;
25 } else
26 *mangled = 0;
27 strncpy(ans, filename, len);
28 have_lower = have_upper = 0;
29 for(i=0; i<11; i++){
30 if(islower((unsigned char)ans[i]))
31 have_lower = 1;
32 if(isupper(ans[i]))
33 have_upper = 1;
34 ans[i] = toupper((unsigned char)ans[i]);
35
36 if(strchr("^+=/[]:,?*\\<>|\".", ans[i])){
37 *mangled = 1;
38 ans[i] = '~';
39 }
40 }
41 if (have_lower && have_upper)
42 *mangled = 1;
43 return ans;
44}
45
46int labelit(char *dosname,
47 char *longname,
48 void *arg0,
49 direntry_t *entry)
50{
51 time_t now;
52
53 /* find out current time */
54 getTimeNow(&now);
55 mk_entry(dosname, 0x8, 0, 0, now, &entry->dir);
56 return 0;
57}
58
59static void usage(void)
60{
61 fprintf(stderr, "Mtools version %s, dated %s\n",
62 mversion, mdate);
63 fprintf(stderr, "Usage: %s [-vscn] [-N serial] drive:[label]\n"
64 "\t-v Verbose\n"
65 "\t-s Show label\n"
66 "\t-c Clear label\n"
67 "\t-n New random serial number\n"
68 "\t-N New given serial number\n", progname);
69 exit(1);
70}
71
72
73void mlabel(int argc, char **argv, int type)
74{
75
76 char *drive, *newLabel;
77 int verbose, clear, interactive, show, open_mode;
78 direntry_t entry;
79 int result=0;
80 char longname[VBUFSIZE];
81 char shortname[13];
82 ClashHandling_t ch;
83 struct MainParam_t mp;
84 Stream_t *RootDir;
85 int c;
86 int mangled;
87 enum { SER_NONE, SER_RANDOM, SER_SET } set_serial = SER_NONE;
88 long serial = 0;
89 int need_write_boot = 0;
90 int have_boot = 0;
91 char *eptr = "";
92 struct bootsector boot;
93 Stream_t *Fs=0;
94 int r;
95 struct label_blk_t *labelBlock;
96
97 init_clash_handling(&ch);
98 ch.name_converter = label_name;
99 ch.ignore_entry = -2;
100
101 verbose = 0;
102 clear = 0;
103 show = 0;
104
105 while ((c = getopt(argc, argv, "vcsnN:")) != EOF) {
106 switch (c) {
107 case 'v':
108 verbose = 1;
109 break;
110 case 'c':
111 clear = 1;
112 break;
113 case 's':
114 show = 1;
115 break;
116 case 'n':
117 set_serial = SER_RANDOM;
118 srandom((long)time (0));
119 serial=random();
120 break;
121 case 'N':
122 set_serial = SER_SET;
123 serial = strtol(optarg, &eptr, 16);
124 if(*eptr) {
125 fprintf(stderr,
126 "%s not a valid serial number\n",
127 optarg);
128 exit(1);
129 }
130 break;
131 default:
132 usage();
133 }
134 }
135
136 if (argc - optind != 1 || skip_drive(argv[optind]) == argv[optind])
137 usage();
138
139 init_mp(&mp);
140 newLabel = skip_drive(argv[optind]);
141 interactive = !show && !clear &&!newLabel[0] &&
142 (set_serial == SER_NONE);
143 open_mode = O_RDWR;
144 drive = get_drive(argv[optind], NULL);
145 RootDir = open_root_dir(drive, open_mode);
146 if(strlen(newLabel) > VBUFSIZE) {
147 fprintf(stderr, "Label too long\n");
148 FREE(&RootDir);
149 exit(1);
150 }
151
152 if(!RootDir && open_mode == O_RDWR && !clear && !newLabel[0] &&
153 ( errno == EACCES || errno == EPERM) ) {
154 show = 1;
155 interactive = 0;
156 RootDir = open_root_dir(drive, O_RDONLY);
157 }
158 if(!RootDir) {
159 fprintf(stderr, "%s: Cannot initialize drive\n", argv[0]);
160 exit(1);
161 }
162
163 initializeDirentry(&entry, RootDir);
164 r=vfat_lookup(&entry, 0, 0, ACCEPT_LABEL | MATCH_ANY,
165 shortname, longname);
166 if (r == -2) {
167 FREE(&RootDir);
168 exit(1);
169 }
170
171 if(show || interactive){
172 if(isNotFound(&entry))
173 printf(" Volume has no label\n");
174 else if (*longname)
175 printf(" Volume label is %s (abbr=%s)\n",
176 longname, shortname);
177 else
178 printf(" Volume label is %s\n", shortname);
179
180 }
181
182 /* ask for new label */
183 if(interactive){
184 newLabel = longname;
185 fprintf(stderr,"Enter the new volume label : ");
186 fgets(newLabel, VBUFSIZE, stdin);
187 if(newLabel[0])
188 newLabel[strlen(newLabel)-1] = '\0';
189 }
190
191 if((!show || newLabel[0]) && !isNotFound(&entry)){
192 /* if we have a label, wipe it out before putting new one */
193 if(interactive && newLabel[0] == '\0')
194 if(ask_confirmation("Delete volume label (y/n): ",0,0)){
195 FREE(&RootDir);
196 exit(0);
197 }
198 entry.dir.name[0] = DELMARK;
199 entry.dir.attr = 0; /* for old mlabel */
200 dir_write(&entry);
201 }
202
203 if (newLabel[0] != '\0') {
204 ch.ignore_entry = 1;
205 result = mwrite_one(RootDir,newLabel,0,labelit,NULL,&ch) ?
206 0 : 1;
207 }
208
209 have_boot = 0;
210 if( (!show || newLabel[0]) || set_serial != SER_NONE) {
211 Fs = GetFs(RootDir);
212 have_boot = (force_read(Fs,(char *)&boot,0,sizeof(boot)) ==
213 sizeof(boot));
214 }
215
216 if(_WORD(boot.fatlen)) {
217 labelBlock = &boot.ext.old.labelBlock;
218 } else {
219 labelBlock = &boot.ext.fat32.labelBlock;
220 }
221
222 if(!show || newLabel[0]){
223
224 if(!newLabel[0])
225 strncpy(shortname, "NO NAME ",11);
226 else
227 label_name(newLabel, verbose, &mangled, shortname);
228
229 if(have_boot && boot.descr >= 0xf0 &&
230 labelBlock->dos4 == 0x29) {
231 strncpy(labelBlock->label, shortname, 11);
232 need_write_boot = 1;
233
234 }
235 }
236
237 if((set_serial != SER_NONE) & have_boot) {
238 if(have_boot && boot.descr >= 0xf0 &&
239 labelBlock->dos4 == 0x29) {
240 set_dword(labelBlock->serial, serial);
241 need_write_boot = 1;
242 }
243 }
244
245 if(need_write_boot) {
246 force_write(Fs, (char *)&boot, 0, sizeof(boot));
247 }
248
249 FREE(&RootDir);
250 exit(result);
251}
Note: See TracBrowser for help on using the repository browser.