(linenum→info "unix/slp.c:2238")

glibc/2.7/hurd/xattr.c

    1: /* Support for *xattr interfaces on GNU/Hurd.
    2:    Copyright (C) 2006 Free Software Foundation, Inc.
    3:    This file is part of the GNU C Library.
    4: 
    5:    The GNU C Library is free software; you can redistribute it and/or
    6:    modify it under the terms of the GNU Lesser General Public
    7:    License as published by the Free Software Foundation; either
    8:    version 2.1 of the License, or (at your option) any later version.
    9: 
   10:    The GNU C Library is distributed in the hope that it will be useful,
   11:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13:    Lesser General Public License for more details.
   14: 
   15:    You should have received a copy of the GNU Lesser General Public
   16:    License along with the GNU C Library; if not, write to the Free
   17:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   18:    02111-1307 USA.  */
   19: 
   20: #include <hurd.h>
   21: #include <hurd/xattr.h>
   22: #include <string.h>
   23: #include <sys/mman.h>
   24: 
   25: /* Right now we support only a fixed set of xattr names for Hurd features.
   26:    There are no RPC interfaces for free-form xattr names and values.
   27: 
   28:    Name                 Value encoding
   29:    ----                 ----- --------
   30:    gnu.author           empty if st_author==st_uid
   31:                         uid_t giving st_author value
   32:    gnu.translator       empty if no passive translator
   33:                         translator and arguments: "/hurd/foo\0arg1\0arg2\0"
   34: */
   35: 
   36: error_t
   37: _hurd_xattr_get (io_t port, const char *name, void *value, size_t *size)
   38: {
   39:   if (strncmp (name, "gnu.", 4))
   40:     return EOPNOTSUPP;
   41:   name += 4;
   42: 
   43:   if (!strcmp (name, "author"))
   44:     {
   45:       struct stat64 st;
   46:       error_t err = __io_stat (port, &st);
   47:       if (err)
   48:         return err;
   49:       if (st.st_author == st.st_uid)
   50:         *size = 0;
   51:       else if (value)
   52:         {
   53:           if (*size < sizeof st.st_author)
   54:             return ERANGE;
   55:           memcpy (value, &st.st_author, sizeof st.st_author);
   56:         }
   57:       *size = sizeof st.st_author;
   58:       return 0;
   59:     }
   60: 
   61:   if (!strcmp (name, "translator"))
   62:     {
   63:       char *buf = value;
   64:       size_t bufsz = value ? *size : 0;
   65:       error_t err = __file_get_translator (port, &buf, &bufsz);
   66:       if (err)
   67:         return err;
   68:       if (value != NULL && *size < bufsz)
   69:         {
   70:           if (buf != value)
   71:             munmap (buf, bufsz);
   72:           return -ERANGE;
   73:         }
   74:       if (buf != value && bufsz > 0)
   75:         {
   76:           if (value != NULL)
   77:             memcpy (value, buf, bufsz);
   78:           munmap (buf, bufsz);
   79:         }
   80:       *size = bufsz;
   81:       return 0;
   82:     }
   83: 
   84:   return EOPNOTSUPP;
   85: }
   86: 
   87: error_t
   88: _hurd_xattr_set (io_t port, const char *name, const void *value, size_t size,
   89:                  int flags)
   90: {
   91:   if (strncmp (name, "gnu.", 4))
   92:     return EOPNOTSUPP;
   93:   name += 4;
   94: 
   95:   if (!strcmp (name, "author"))
   96:     switch (size)
   97:       {
   98:       default:
   99:         return EINVAL;
  100:       case 0:                   /* "Clear" author by setting to st_uid. */
  101:         {
  102:           struct stat64 st;
  103:           error_t err = __io_stat (port, &st);
  104:           if (err)
  105:             return err;
  106:           if (st.st_author == st.st_uid)
  107:             {
  108:               /* Nothing to do.  */
  109:               if (flags & XATTR_REPLACE)
  110:                 return ENODATA;
  111:               return 0;
  112:             }
  113:           if (flags & XATTR_CREATE)
  114:             return EEXIST;
  115:           return __file_chauthor (port, st.st_uid);
  116:         }
  117:       case sizeof (uid_t):      /* Set the author.  */
  118:         {
  119:           uid_t id;
  120:           memcpy (&id, value, sizeof id);
  121:           if (flags & (XATTR_CREATE|XATTR_REPLACE))
  122:             {
  123:               struct stat64 st;
  124:               error_t err = __io_stat (port, &st);
  125:               if (err)
  126:                 return err;
  127:               if (st.st_author == st.st_uid)
  128:                 {
  129:                   if (flags & XATTR_REPLACE)
  130:                     return ENODATA;
  131:                 }
  132:               else if (flags & XATTR_CREATE)
  133:                 return EEXIST;
  134:               if (st.st_author == id)
  135:                 /* Nothing to do.  */
  136:                 return 0;
  137:             }
  138:           return __file_chauthor (port, id);
  139:         }
  140:       }
  141: 
  142:   if (!strcmp (name, "translator"))
  143:     {
  144:       if (flags & XATTR_REPLACE)
  145:         {
  146:           /* Must make sure it's already there.  */
  147:           char *buf = NULL;
  148:           size_t bufsz = 0;
  149:           error_t err = __file_get_translator (port, &buf, &bufsz);
  150:           if (err)
  151:             return err;
  152:           if (bufsz > 0)
  153:             {
  154:               munmap (buf, bufsz);
  155:               return ENODATA;
  156:             }
  157:         }
  158:       return __file_set_translator (port,
  159:                                     FS_TRANS_SET | ((flags & XATTR_CREATE)
  160:                                                     ? FS_TRANS_EXCL : 0), 0, 0,
  161:                                     value, size,
  162:                                     MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND);
  163:     }
  164: 
  165:   return EOPNOTSUPP;
  166: }
  167: 
  168: error_t
  169: _hurd_xattr_remove (io_t port, const char *name)
  170: {
  171:   return _hurd_xattr_set (port, name, NULL, 0, XATTR_REPLACE);
  172: }
  173: 
  174: error_t
  175: _hurd_xattr_list (io_t port, void *buffer, size_t *size)
  176: {
  177:   size_t total = 0;
  178:   char *bufp = buffer;
  179:   inline void add (const char *name, size_t len)
  180:     {
  181:       total += len;
  182:       if (bufp != NULL && total <= *size)
  183:         bufp = __mempcpy (bufp, name, len);
  184:     }
  185: #define add(s) add (s, sizeof s)
  186: 
  187:   struct stat64 st;
  188:   error_t err = __io_stat (port, &st);
  189:   if (err)
  190:     return err;
  191: 
  192:   if (st.st_author != st.st_uid)
  193:     add ("gnu.author");
  194:   if (st.st_mode & S_IPTRANS)
  195:     add ("gnu.translator");
  196: 
  197:   if (buffer != NULL && total > *size)
  198:     return ERANGE;
  199:   *size = total;
  200:   return 0;
  201: }
Syntax (Markdown)