1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
/*
* mattrib.c
* Change MSDOS file attribute flags
*/
#include "sysincludes.h"
#include "msdos.h"
#include "mtools.h"
#include "mainloop.h"
typedef struct Arg_t {
char add;
unsigned char remove;
struct MainParam_t mp;
} Arg_t;
static int attrib_file(Stream_t *Dir, MainParam_t *mp, int entry)
{
Arg_t *arg=(Arg_t *) mp->arg;
mp->dir.attr = (mp->dir.attr & arg->remove) | arg->add;
dir_write(Dir,entry,& mp->dir);
return GOT_ONE;
}
static int view_attrib(Stream_t *Dir, MainParam_t *mp, int entry)
{
printf(" ");
if(mp->dir.attr & 0x20)
putchar('A');
else
putchar(' ');
fputs(" ",stdout);
if(mp->dir.attr & 0x4)
putchar('S');
else
putchar(' ');
if(mp->dir.attr & 0x2)
putchar('H');
else
putchar(' ');
if(mp->dir.attr & 0x1)
putchar('R');
else
putchar(' ');
printf(" %c:%s", mp->drivename, mp->pathname);
if(strlen(mp->pathname) != 1 )
putchar('/');
puts(mp->outname);
return GOT_ONE;
}
static void usage(void) NORETURN;
static void usage(void)
{
fprintf(stderr, "Mtools version %s, dated %s\n",
mversion, mdate);
fprintf(stderr,
"Usage: %s [-p] [-a|+a] [-h|+h] [-r|+r] [-s|+s] msdosfile [msdosfiles...]\n",
progname);
exit(1);
}
static int letterToCode(int letter)
{
switch (toupper(letter)) {
case 'A':
return 0x20;
case 'H':
return 0x2;
case 'R':
return 0x1;
case 'S':
return 0x4;
default:
usage();
}
}
void mattrib(int argc, char **argv, int type)
{
Arg_t arg;
int view;
int c;
char filename[VBUFSIZE];
char pathname[MAX_PATH];
char *ptr;
arg.add = 0;
arg.remove = 0xff;
view = 0;
while ((c = getopt(argc, argv, "ahrsAHRS")) != EOF) {
switch (c) {
default:
arg.remove &= ~letterToCode(c);
break;
case '?':
usage();
}
}
for(;optind < argc;optind++) {
switch(argv[optind][0]) {
case '+':
for(ptr = argv[optind] + 1; *ptr; ptr++)
arg.add |= letterToCode(*ptr);
continue;
case '-':
for(ptr = argv[optind] + 1; *ptr; ptr++)
arg.remove &= ~letterToCode(*ptr);
continue;
}
break;
}
if(arg.remove == 0xff && !arg.add)
view = 1;
if (optind >= argc)
usage();
init_mp(&arg.mp);
if(view){
arg.mp.callback = view_attrib;
arg.mp.openflags = O_RDONLY;
} else {
arg.mp.callback = attrib_file;
arg.mp.openflags = O_RDWR;
}
arg.mp.outname = filename;
arg.mp.arg = (void *) &arg;
arg.mp.lookupflags = ACCEPT_PLAIN | ACCEPT_DIR;
arg.mp.pathname = pathname;
exit(main_loop(&arg.mp, argv + optind, argc - optind));
}
|