blob: 08dd114dc0b86822bebc69ae3d3499385ed569d1 [file] [log] [blame]
Theodore Ts'o3839e651997-04-26 13:21:57 +00001/*
2 * fsetflags.c - Set a file flags on an ext2 file system
3 *
4 * Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
5 * Laboratoire MASI, Institut Blaise Pascal
6 * Universite Pierre et Marie Curie (Paris VI)
7 *
Theodore Ts'o543547a2010-05-17 21:31:56 -04008 * %Begin-Header%
9 * This file may be redistributed under the terms of the GNU Library
10 * General Public License, version 2.
11 * %End-Header%
Theodore Ts'o3839e651997-04-26 13:21:57 +000012 */
13
14/*
15 * History:
16 * 93/10/30 - Creation
17 */
18
Theodore Ts'o66d8c3f2000-12-02 06:11:44 +000019#define _LARGEFILE_SOURCE
20#define _LARGEFILE64_SOURCE
21
Theodore Ts'o50e1e101997-04-26 13:58:21 +000022#if HAVE_ERRNO_H
Theodore Ts'o3839e651997-04-26 13:21:57 +000023#include <errno.h>
Theodore Ts'o50e1e101997-04-26 13:58:21 +000024#endif
25#if HAVE_UNISTD_H
Theodore Ts'o3839e651997-04-26 13:21:57 +000026#include <unistd.h>
Theodore Ts'o50e1e101997-04-26 13:58:21 +000027#endif
Theodore Ts'o023d1112002-08-17 14:44:56 -040028#include <sys/types.h>
29#include <sys/stat.h>
30#if HAVE_EXT2_IOCTLS
Theodore Ts'o50e1e101997-04-26 13:58:21 +000031#include <fcntl.h>
Theodore Ts'o3839e651997-04-26 13:21:57 +000032#include <sys/ioctl.h>
Theodore Ts'o50e1e101997-04-26 13:58:21 +000033#endif
Theodore Ts'o3839e651997-04-26 13:21:57 +000034
Theodore Ts'o3839e651997-04-26 13:21:57 +000035#include "e2p.h"
36
Theodore Ts'oefc6f622008-08-27 23:07:54 -040037/*
38 * Deal with lame glibc's that define this function without actually
Theodore Ts'o919994a2004-06-25 00:52:08 -040039 * implementing it. Can you say "attractive nuisance", boys and girls?
40 * I knew you could!
41 */
42#ifdef __linux__
43#undef HAVE_CHFLAGS
44#endif
45
Theodore Ts'o66d8c3f2000-12-02 06:11:44 +000046#ifdef O_LARGEFILE
47#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE)
48#else
49#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK)
50#endif
51
Theodore Ts'o3839e651997-04-26 13:21:57 +000052int fsetflags (const char * name, unsigned long flags)
53{
Theodore Ts'o3c203cb2004-01-31 21:16:35 -050054#if HAVE_CHFLAGS && !(APPLE_DARWIN && HAVE_EXT2_IOCTLS)
Theodore Ts'occe382b1998-03-09 13:07:09 +000055 unsigned long bsd_flags = 0;
Theodore Ts'o50e1e101997-04-26 13:58:21 +000056
57#ifdef UF_IMMUTABLE
Theodore Ts'occe382b1998-03-09 13:07:09 +000058 if (flags & EXT2_IMMUTABLE_FL)
59 bsd_flags |= UF_IMMUTABLE;
Theodore Ts'o50e1e101997-04-26 13:58:21 +000060#endif
61#ifdef UF_APPEND
Theodore Ts'occe382b1998-03-09 13:07:09 +000062 if (flags & EXT2_APPEND_FL)
63 bsd_flags |= UF_APPEND;
Theodore Ts'o50e1e101997-04-26 13:58:21 +000064#endif
65#ifdef UF_NODUMP
Theodore Ts'occe382b1998-03-09 13:07:09 +000066 if (flags & EXT2_NODUMP_FL)
67 bsd_flags |= UF_NODUMP;
Theodore Ts'o50e1e101997-04-26 13:58:21 +000068#endif
69
Theodore Ts'occe382b1998-03-09 13:07:09 +000070 return chflags (name, bsd_flags);
JP Abgralle0ed7402014-03-19 19:08:39 -070071#else /* !HAVE_CHFLAGS || (APPLE_DARWIN && HAVE_EXT2_IOCTLS) */
Theodore Ts'o50e1e101997-04-26 13:58:21 +000072#if HAVE_EXT2_IOCTLS
Theodore Ts'oa8a813e2002-07-14 16:13:55 -040073 int fd, r, f, save_errno = 0;
JP Abgralle0ed7402014-03-19 19:08:39 -070074 struct stat buf;
Theodore Ts'o3839e651997-04-26 13:21:57 +000075
Theodore Ts'o1a4ce9d2007-10-22 01:36:13 -040076 if (!lstat(name, &buf) &&
Theodore Ts'o023d1112002-08-17 14:44:56 -040077 !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
Theodore Ts'o023d1112002-08-17 14:44:56 -040078 goto notsupp;
79 }
Theodore Ts'o3c203cb2004-01-31 21:16:35 -050080#if !APPLE_DARWIN
Theodore Ts'o66d8c3f2000-12-02 06:11:44 +000081 fd = open (name, OPEN_FLAGS);
Theodore Ts'o3839e651997-04-26 13:21:57 +000082 if (fd == -1)
83 return -1;
Theodore Ts'occe382b1998-03-09 13:07:09 +000084 f = (int) flags;
85 r = ioctl (fd, EXT2_IOC_SETFLAGS, &f);
Theodore Ts'oa8a813e2002-07-14 16:13:55 -040086 if (r == -1)
87 save_errno = errno;
Theodore Ts'o3839e651997-04-26 13:21:57 +000088 close (fd);
Theodore Ts'oa8a813e2002-07-14 16:13:55 -040089 if (save_errno)
90 errno = save_errno;
JP Abgralle0ed7402014-03-19 19:08:39 -070091#else /* APPLE_DARWIN */
92 f = (int) flags;
93 return syscall(SYS_fsctl, name, EXT2_IOC_SETFLAGS, &f, 0);
94#endif /* !APPLE_DARWIN */
Theodore Ts'o3839e651997-04-26 13:21:57 +000095 return r;
JP Abgralle0ed7402014-03-19 19:08:39 -070096
97notsupp:
Theodore Ts'o023d1112002-08-17 14:44:56 -040098#endif /* HAVE_EXT2_IOCTLS */
99#endif
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000100 errno = EOPNOTSUPP;
101 return -1;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000102}