// changes a given file attributes void chattr_cmd(int term, char **args, int argc) { int flags = 0, substract = 0; char *path = NULL; // changeable attributes are: hidden and readonly // -|+{h,r} if(argc != 2 || len(args[1]) == 1 || (args[1][0] != '+' && args[1][0] != '-')) { term_color_print(term, invalid_params, 12); term_color_print(term, "Usage: chattr filename +|-{h,r}.\n", 7); return; } path = build_path(args[0], term); if(path == NULL) { term_color_print(term, "Invalid path.\n", 7); return; } if(args[1][0] == '-') { substract = 1; } if(first_index_of(args[1], 'h', 0) != -1) { flags |= IOLIB_ATT_HIDDEN; } if(first_index_of(args[1], 'r', 0) != -1) { flags |= IOLIB_ATT_READONLY; } if(chattr(path, flags, substract)) { term_color_print(term, mapioerr(ioerror()), 12); term_color_print(term, "\n", 11); } free(path); }
/* implement chattr */ int main(int argc, char *argv[]) { int opt; int fd; int attr; char *file, *mode, *p; Boolean info = TRUE; /* error messages */ int action; if (argc < 2 || strcmp(argv[1], "--help") == 0) { eprintf("Usage: %s [-f] mode file", argv[0]); fprintf(stderr, "\t mode: +-=[aAcCdDeijsStTu]"); exit(EXIT_FAILURE); } while ((opt = getopt(argc, argv, "f")) != -1) { switch (opt) { case 'f': info = FALSE; break; default: /* '?' */ usageErr("%s [-a] file\n", argv[0]); } } if (optind+2 > argc) { eprintf("Error: optind: %d argc: %d\n", optind, argc); exit(EXIT_FAILURE); } mode = argv[optind]; file = argv[optind+1]; /* Build bit mask based on attribute string in argv[1] */ switch (*mode) { case '+': action = SET; break; case '-': action = UNSET; break; case '=': action = EQUALS; break; default: eprintf("unknow action: %s\n", mode); exit(EXIT_FAILURE); } attr = 0; for (p = ++mode; *p != '\0'; p++) { switch (*p) { case 'a': attr |= FS_APPEND_FL; break; case 'A': attr |= FS_NOATIME_FL; break; case 'c': attr |= FS_COMPR_FL; break; case 'd': attr |= FS_NODUMP_FL; break; case 'D': attr |= FS_DIRSYNC_FL; break; case 'i': attr |= FS_IMMUTABLE_FL; break; case 'j': attr |= FS_JOURNAL_DATA_FL; break; case 's': attr |= FS_SECRM_FL; break; case 'S': attr |= FS_SYNC_FL; break; case 't': attr |= FS_NOTAIL_FL; break; case 'T': attr |= FS_TOPDIR_FL; break; case 'u': attr |= FS_UNRM_FL; break; default: eprintf("unknown option: %c\n", *p); exit(EXIT_FAILURE); } } fd = open(file, O_RDONLY); if (fd == -1) errExit("open failed: %s\n", file); chattr(fd, attr, action, info); if (close(fd) == -1) errExit("close"); exit(EXIT_SUCCESS); }