1 /* 2 * fsetflags.c - Set a file flags on an ext2 file system 3 * 4 * Copyright (C) 1993, 1994 Remy Card <card (at) masi.ibp.fr> 5 * Laboratoire MASI, Institut Blaise Pascal 6 * Universite Pierre et Marie Curie (Paris VI) 7 * 8 * This file can be redistributed under the terms of the GNU Library General 9 * Public License 10 */ 11 12 /* 13 * History: 14 * 93/10/30 - Creation 15 */ 16 17 #define _LARGEFILE_SOURCE 18 #define _LARGEFILE64_SOURCE 19 20 #if HAVE_ERRNO_H 21 #include <errno.h> 22 #endif 23 #if HAVE_UNISTD_H 24 #include <unistd.h> 25 #endif 26 #include <sys/types.h> 27 #include <sys/stat.h> 28 #if HAVE_EXT2_IOCTLS 29 #include <fcntl.h> 30 #include <sys/ioctl.h> 31 #endif 32 33 #include "e2p.h" 34 35 /* 36 * Deal with lame glibc's that define this function without actually 37 * implementing it. Can you say "attractive nuisance", boys and girls? 38 * I knew you could! 39 */ 40 #ifdef __linux__ 41 #undef HAVE_CHFLAGS 42 #endif 43 44 #ifdef O_LARGEFILE 45 #define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE) 46 #else 47 #define OPEN_FLAGS (O_RDONLY|O_NONBLOCK) 48 #endif 49 50 int fsetflags (const char * name, unsigned long flags) 51 { 52 struct stat buf; 53 #if HAVE_CHFLAGS && !(APPLE_DARWIN && HAVE_EXT2_IOCTLS) 54 unsigned long bsd_flags = 0; 55 56 #ifdef UF_IMMUTABLE 57 if (flags & EXT2_IMMUTABLE_FL) 58 bsd_flags |= UF_IMMUTABLE; 59 #endif 60 #ifdef UF_APPEND 61 if (flags & EXT2_APPEND_FL) 62 bsd_flags |= UF_APPEND; 63 #endif 64 #ifdef UF_NODUMP 65 if (flags & EXT2_NODUMP_FL) 66 bsd_flags |= UF_NODUMP; 67 #endif 68 69 return chflags (name, bsd_flags); 70 #else 71 #if HAVE_EXT2_IOCTLS 72 int fd, r, f, save_errno = 0; 73 74 if (!stat(name, &buf) && 75 !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) { 76 goto notsupp; 77 } 78 #if !APPLE_DARWIN 79 fd = open (name, OPEN_FLAGS); 80 if (fd == -1) 81 return -1; 82 f = (int) flags; 83 r = ioctl (fd, EXT2_IOC_SETFLAGS, &f); 84 if (r == -1) 85 save_errno = errno; 86 close (fd); 87 if (save_errno) 88 errno = save_errno; 89 #else 90 f = (int) flags; 91 return syscall(SYS_fsctl, name, EXT2_IOC_SETFLAGS, &f, 0); 92 #endif 93 return r; 94 #endif /* HAVE_EXT2_IOCTLS */ 95 #endif 96 notsupp: 97 errno = EOPNOTSUPP; 98 return -1; 99 } 100