The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/darwin/darwin_attr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: darwin_attr.c,v 1.24 2008/04/28 20:23:41 martin Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2003, 2008 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Emmanuel Dreyfus.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __KERNEL_RCSID(0, "$NetBSD: darwin_attr.c,v 1.24 2008/04/28 20:23:41 martin Exp $");
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/types.h>
   38 #include <sys/proc.h>
   39 #include <sys/mount.h>
   40 #include <sys/lwp.h>
   41 #include <sys/file.h>
   42 #include <sys/filedesc.h>
   43 #include <sys/namei.h>
   44 #include <sys/vnode.h>
   45 #include <sys/malloc.h>
   46 #include <sys/stat.h>
   47 #include <sys/syscallargs.h>
   48 #include <sys/vfs_syscalls.h>
   49 #include <sys/kauth.h>
   50 
   51 #include <compat/sys/signal.h>
   52 #include <compat/sys/mount.h>
   53 
   54 #include <compat/common/compat_util.h>
   55 
   56 #include <compat/mach/mach_types.h>
   57 #include <compat/mach/mach_vm.h>
   58 
   59 #include <compat/darwin/darwin_audit.h>
   60 #include <compat/darwin/darwin_attr.h>
   61 #include <compat/darwin/darwin_syscallargs.h>
   62 
   63 #define DARWIN_ATTR_MAXBUFLEN   4096
   64 
   65 static int darwin_attr_append(const char *, size_t, char **, size_t *);
   66 
   67 #define ATTR_APPEND(x, bp, len) \
   68     darwin_attr_append((char *)&(x), sizeof(x), &(bp), &(len))
   69 
   70 
   71 static int
   72 darwin_attr_append(const char *x, size_t size, char **bp, size_t *len)
   73 {
   74         if (*len < size)
   75                 return -1;
   76 
   77         (void)memcpy(*bp, x, size);
   78 
   79         *bp += size;
   80         *len -= size;
   81 
   82         return 0;
   83 }
   84 
   85 int
   86 darwin_sys_getattrlist(struct lwp *l, const struct darwin_sys_getattrlist_args *uap, register_t *retval)
   87 {
   88         /* {
   89                 syscallarg(const char *) path;
   90                 syscallarg(struct darwin_attrlist *) alist;
   91                 syscallarg(void *) attributes;
   92                 syscallarg(size_t) buflen;
   93                 syscallarg(unsigned long) options;
   94         } */
   95         struct darwin_attrlist kalist;
   96         char *tbuf;
   97         char *bp;
   98         size_t len;
   99         size_t shift = 0;
  100         int null = 0;
  101         int error = 0;
  102         int follow = NOFOLLOW;
  103         u_long *whole_len_p = NULL;
  104         darwin_attrreference_t *cmn_name_p = NULL;
  105         darwin_attrreference_t *vol_mountpoint_p = NULL;
  106         darwin_attrreference_t *vol_name_p = NULL;
  107         darwin_attrreference_t *vol_mounteddevice_p = NULL;
  108         struct stat st;
  109         struct statvfs *f;
  110         struct nameidata nd;
  111         struct vnode *vp;
  112         kauth_cred_t cred;
  113 
  114         if ((error = copyin(SCARG(uap, alist), &kalist, sizeof(kalist))) != 0)
  115                 return error;
  116 
  117         if (kalist.bitmapcount != DARWIN_ATTR_BIT_MAP_COUNT)
  118                 return EINVAL;
  119 
  120         len = SCARG(uap, buflen);
  121         if (len > DARWIN_ATTR_MAXBUFLEN)
  122                 return E2BIG;
  123 
  124         if ((SCARG(uap, options) & DARWIN_FSOPT_NOFOLLOW) != 0)
  125                 follow = FOLLOW;
  126 
  127 #ifdef DEBUG_DARWIN
  128         printf("getattrlist: %08x %08x %08x %08x %08x\n",
  129             kalist.commonattr, kalist.volattr, kalist.dirattr,
  130             kalist.fileattr, kalist.forkattr);
  131 #endif
  132 
  133         /* Allocate buffers now... */
  134         f = STATVFSBUF_GET();
  135         tbuf = malloc(len, M_TEMP, M_WAITOK);
  136 
  137         /* We are going to need the vnode itself... */
  138 
  139         cred = kauth_cred_dup(l->l_cred);
  140         kauth_cred_seteuid(cred, kauth_cred_getuid(l->l_cred));
  141         kauth_cred_setegid(cred, kauth_cred_getgid(l->l_cred));
  142 
  143         NDINIT(&nd, LOOKUP, follow | LOCKLEAF | TRYEMULROOT, UIO_USERSPACE,
  144             SCARG(uap, path));
  145         if ((error = namei(&nd)) != 0)
  146                 goto out2;
  147 
  148         vp = nd.ni_vp;
  149         if ((error = VOP_ACCESS(vp, VREAD | VEXEC, cred)) != 0)
  150                 goto out3;
  151 
  152         /* Get the informations for path: file related info */
  153         error = vn_stat(vp, &st);
  154         if (error != 0)
  155                 goto out3;
  156 
  157         /* filesystem related info */
  158         error = dostatvfs(vp->v_mount, f, l, 0, 1);
  159         if (error != 0)
  160                 goto out3;
  161 
  162         /*
  163          * Prepare the buffer
  164          */
  165         bp = tbuf;
  166 
  167         /*
  168          * Buffer whole length: is always present
  169          */
  170         if (1) {
  171                 u_long whole_len;
  172 
  173                 whole_len = 0;
  174                 whole_len_p = (u_long *)bp;
  175                 if (ATTR_APPEND(whole_len, bp, len) != 0)
  176                         goto out3;
  177         }
  178 
  179         if (kalist.commonattr & DARWIN_ATTR_CMN_NAME) {
  180                 darwin_attrreference_t dar;
  181 
  182                 cmn_name_p = (darwin_attrreference_t *)bp;
  183                 if (ATTR_APPEND(dar, bp, len) != 0)
  184                         goto out3;
  185         }
  186 
  187         if (kalist.commonattr & DARWIN_ATTR_CMN_DEVID) {
  188                 dev_t device;
  189 
  190                 device = st.st_dev;
  191                 if (ATTR_APPEND(device, bp, len) != 0)
  192                         goto out3;
  193         }
  194 
  195         if (kalist.commonattr & DARWIN_ATTR_CMN_FSID) {
  196                 fsid_t fs;
  197                 fs = f->f_fsidx;
  198                 if (ATTR_APPEND(fs, bp, len) != 0)
  199                         goto out3;
  200         }
  201 
  202         if (kalist.commonattr & DARWIN_ATTR_CMN_OBJTYPE) {
  203                 darwin_fsobj_type_t dft;
  204 
  205                 dft = vp->v_type;
  206                 if (ATTR_APPEND(dft, bp, len) != 0)
  207                         goto out3;
  208         }
  209 
  210         if (kalist.commonattr & DARWIN_ATTR_CMN_OBJTAG) {
  211                 darwin_fsobj_tag_t dft;
  212 
  213                 dft = vp->v_tag;
  214                 if (ATTR_APPEND(dft, bp, len) != 0)
  215                         goto out3;
  216         }
  217 
  218         if (kalist.commonattr & DARWIN_ATTR_CMN_OBJID) {
  219                 darwin_fsobj_id_t dfi;
  220 
  221                 dfi.fid_objno = st.st_ino;
  222                 dfi.fid_generation = 0; /* XXX root can read real value */
  223                 if (ATTR_APPEND(dfi, bp, len) != 0)
  224                         goto out3;
  225         }
  226 
  227         if (kalist.commonattr & DARWIN_ATTR_CMN_OBJPERMANENTID) {
  228                 darwin_fsobj_id_t dfi;
  229 
  230                 dfi.fid_objno = st.st_ino; /* This is not really persistent */
  231                 dfi.fid_generation = 0; /* XXX root can read real value */
  232                 if (ATTR_APPEND(dfi, bp, len) != 0)
  233                         goto out3;
  234         }
  235 
  236         if (kalist.commonattr & DARWIN_ATTR_CMN_PAROBJID) {
  237                 darwin_fsobj_id_t dfi;
  238 
  239                 dfi.fid_objno = 0;      /* XXX do me */
  240                 dfi.fid_generation = 0; /* XXX root can read real value */
  241                 if (ATTR_APPEND(dfi, bp, len) != 0)
  242                         goto out3;
  243         }
  244 
  245         if (kalist.commonattr & DARWIN_ATTR_CMN_SCRIPT) {
  246                 darwin_text_encoding_t dte;
  247 
  248                 dte = DARWIN_US_ASCII;
  249                 if (ATTR_APPEND(dte, bp, len) != 0)
  250                         goto out3;
  251         }
  252 
  253         if (kalist.commonattr & DARWIN_ATTR_CMN_CRTIME) {
  254                 if (ATTR_APPEND(st.st_ctimespec, bp, len) != 0)
  255                         goto out3;
  256         }
  257 
  258         if (kalist.commonattr & DARWIN_ATTR_CMN_MODTIME) {
  259                 if (ATTR_APPEND(st.st_mtimespec, bp, len) != 0)
  260                         goto out3;
  261         }
  262 
  263         if (kalist.commonattr & DARWIN_ATTR_CMN_CHGTIME) {
  264                 if (ATTR_APPEND(st.st_ctimespec, bp, len) != 0)
  265                         goto out3;
  266         }
  267 
  268         if (kalist.commonattr & DARWIN_ATTR_CMN_ACCTIME) {
  269                 if (ATTR_APPEND(st.st_atimespec, bp, len) != 0)
  270                         goto out3;
  271         }
  272 
  273         if (kalist.commonattr & DARWIN_ATTR_CMN_BKUPTIME) {
  274                 struct timespec ts;
  275 
  276                 /* XXX no way I can do that one */
  277 
  278                 (void)bzero(&ts, sizeof(ts));
  279                 if (ATTR_APPEND(ts, bp, len) != 0)
  280                         goto out3;
  281         }
  282 
  283         if (kalist.commonattr & DARWIN_ATTR_CMN_FNDRINFO) { /* XXX */
  284                 char data[32];
  285 
  286                 (void)bzero(&data, sizeof(data));
  287                 if (ATTR_APPEND(data, bp, len) != 0)
  288                         goto out3;
  289         }
  290 
  291         if (kalist.commonattr & DARWIN_ATTR_CMN_OWNERID) {
  292                 uid_t uid;
  293 
  294                 uid = st.st_uid;
  295                 if (ATTR_APPEND(uid, bp, len) != 0)
  296                         goto out3;
  297         }
  298 
  299         if (kalist.commonattr & DARWIN_ATTR_CMN_GRPID) {
  300                 gid_t gid;
  301 
  302                 gid = st.st_gid;
  303                 if (ATTR_APPEND(gid, bp, len) != 0)
  304                         goto out3;
  305         }
  306 
  307         if (kalist.commonattr & DARWIN_ATTR_CMN_ACCESSMASK) {
  308                 mode_t mode;
  309 
  310                 mode = st.st_mode;
  311                 if (ATTR_APPEND(mode, bp, len) != 0)
  312                         goto out3;
  313         }
  314 
  315         if (kalist.commonattr & DARWIN_ATTR_CMN_NAMEDATTRCOUNT) {
  316                 /* Data is unsigned long. Unsupported in Darwin */
  317                 error = EINVAL;
  318                 goto out3;
  319         }
  320 
  321         if (kalist.commonattr & DARWIN_ATTR_CMN_NAMEDATTRLIST) {
  322                 /* Data is darwin_attrreference_t. Unsupported in Darwin */
  323 
  324                 error = EINVAL;
  325                 goto out3;
  326         }
  327 
  328         if (kalist.commonattr & DARWIN_ATTR_CMN_FLAGS) {
  329                 unsigned long flags;
  330 
  331                 flags = st.st_flags;    /* XXX need convertion */
  332                 if (ATTR_APPEND(flags, bp, len) != 0)
  333                         goto out3;
  334         }
  335 
  336         if (kalist.commonattr & DARWIN_ATTR_CMN_USERACCESS) {
  337                 unsigned long ua = 0;
  338                 struct sys_access_args cup3;
  339                 register_t rv;
  340 
  341                 SCARG(&cup3, path) = SCARG(uap, path);
  342 
  343                 SCARG(&cup3, flags) = R_OK;
  344                 if (sys_access(l, &cup3, &rv) == 0)
  345                         ua |= R_OK;
  346 
  347                 SCARG(&cup3, flags) = W_OK;
  348                 if (sys_access(l, &cup3, &rv) == 0)
  349                         ua |= W_OK;
  350 
  351                 SCARG(&cup3, flags) = X_OK;
  352                 if (sys_access(l, &cup3, &rv) == 0)
  353                         ua |= X_OK;
  354 
  355                 if (ATTR_APPEND(ua, bp, len) != 0)
  356                         goto out3;
  357         }
  358 
  359 
  360         if (kalist.volattr & DARWIN_ATTR_VOL_INFO) {
  361                 /* Nothing added, just skip */
  362         }
  363 
  364         if (kalist.volattr & DARWIN_ATTR_VOL_FSTYPE) {
  365                 unsigned long fstype;
  366 
  367                 /* We'd need to convert f_fstypename - done for COMPAT_09 */
  368                 fstype = 0;  /* f->f_type; */
  369                 if (ATTR_APPEND(fstype, bp, len) != 0)
  370                         goto out3;
  371         }
  372 
  373         if (kalist.volattr & DARWIN_ATTR_VOL_SIGNATURE) {
  374                 unsigned long sign;
  375 
  376                 /*
  377                  * XXX Volume signature, used to distinguish
  378                  * between volumes inside the same filesystem.
  379                  */
  380                 sign = f->f_fsidx.__fsid_val[0];
  381                 if (ATTR_APPEND(sign, bp, len) != 0)
  382                         goto out3;
  383         }
  384 
  385         if (kalist.volattr & DARWIN_ATTR_VOL_SIZE) {
  386                 off_t size;
  387 
  388                 size = f->f_blocks * f->f_bsize;
  389                 if (ATTR_APPEND(size, bp, len) != 0)
  390                         goto out3;
  391         }
  392 
  393         if (kalist.volattr & DARWIN_ATTR_VOL_SPACEFREE) {
  394                 off_t ofree;
  395 
  396                 ofree = f->f_bfree * f->f_bsize;
  397                 if (ATTR_APPEND(ofree, bp, len) != 0)
  398                         goto out3;
  399         }
  400 
  401         if (kalist.volattr & DARWIN_ATTR_VOL_SPACEAVAIL) {
  402                 off_t avail;
  403 
  404                 avail = f->f_bavail * f->f_bsize;
  405                 if (ATTR_APPEND(avail, bp, len) != 0)
  406                         goto out3;
  407         }
  408 
  409         if (kalist.volattr & DARWIN_ATTR_VOL_MINALLOCATION) {
  410                 off_t omin;
  411 
  412                 omin = f->f_bsize; /* XXX probably wrong */
  413                 if (ATTR_APPEND(omin, bp, len) != 0)
  414                         goto out3;
  415         }
  416 
  417         if (kalist.volattr & DARWIN_ATTR_VOL_ALLOCATIONCLUMP) {
  418                 off_t clump;
  419 
  420                 clump = f->f_bsize; /* XXX proably wrong */
  421                 if (ATTR_APPEND(clump, bp, len) != 0)
  422                         goto out3;
  423         }
  424 
  425         if (kalist.volattr & DARWIN_ATTR_VOL_IOBLOCKSIZE) {
  426                 unsigned long size;
  427 
  428                 size = f->f_iosize;
  429                 if (ATTR_APPEND(size, bp, len) != 0)
  430                         goto out3;
  431         }
  432 
  433         if (kalist.volattr & DARWIN_ATTR_VOL_OBJCOUNT) {
  434                 unsigned long cnt;
  435 
  436                 cnt = f->f_files;
  437                 if (ATTR_APPEND(cnt, bp, len) != 0)
  438                         goto out3;
  439         }
  440 
  441         if (kalist.volattr & DARWIN_ATTR_VOL_FILECOUNT) {
  442                 unsigned long cnt;
  443 
  444                 cnt = f->f_files; /* XXX only files */
  445                 if (ATTR_APPEND(cnt, bp, len) != 0)
  446                         goto out3;
  447         }
  448 
  449         if (kalist.volattr & DARWIN_ATTR_VOL_DIRCOUNT) {
  450                 unsigned long cnt;
  451 
  452                 cnt = 0; /* XXX wrong, of course */
  453                 if (ATTR_APPEND(cnt, bp, len) != 0)
  454                         goto out3;
  455         }
  456 
  457         if (kalist.volattr & DARWIN_ATTR_VOL_MAXOBJCOUNT) {
  458                 unsigned long cnt;
  459 
  460                 cnt = f->f_files + f->f_ffree;
  461                 if (ATTR_APPEND(cnt, bp, len) != 0)
  462                         goto out3;
  463         }
  464 
  465         if (kalist.volattr & DARWIN_ATTR_VOL_MOUNTPOINT) {
  466                 darwin_attrreference_t dar;
  467 
  468                 vol_mountpoint_p = (darwin_attrreference_t *)bp;
  469                 if (ATTR_APPEND(dar, bp, len) != 0)
  470                         goto out3;
  471         }
  472 
  473         if (kalist.volattr & DARWIN_ATTR_VOL_NAME) {
  474                 darwin_attrreference_t dar;
  475 
  476                 vol_name_p = (darwin_attrreference_t *)bp;
  477                 if (ATTR_APPEND(dar, bp, len) != 0)
  478                         goto out3;
  479         }
  480 
  481         if (kalist.volattr & DARWIN_ATTR_VOL_MOUNTFLAGS) {
  482                 unsigned long flags;
  483 
  484                 flags = f->f_flag; /* XXX need convertion? */
  485                 if (ATTR_APPEND(flags, bp, len) != 0)
  486                         goto out3;
  487         }
  488 
  489         if (kalist.volattr & DARWIN_ATTR_VOL_MOUNTEDDEVICE) {
  490                 darwin_attrreference_t dar;
  491 
  492                 vol_mounteddevice_p = (darwin_attrreference_t *)bp;
  493                 if (ATTR_APPEND(dar, bp, len) != 0)
  494                         goto out3;
  495         }
  496 
  497         if (kalist.volattr & DARWIN_ATTR_VOL_ENCODINGSUSED) {
  498                 unsigned long long data;
  499 
  500                 /*
  501                  * XXX bitmap of encoding used in this volume
  502                  */
  503                 (void)bzero(&data, sizeof(data));
  504                 if (ATTR_APPEND(data, bp, len) != 0)
  505                         goto out3;
  506         }
  507 
  508         if (kalist.volattr & DARWIN_ATTR_VOL_CAPABILITIES) { /* XXX */
  509                 darwin_vol_capabilities_attr_t data;
  510 
  511                 (void)bzero(&data, sizeof(data));
  512                 if (ATTR_APPEND(data, bp, len) != 0)
  513                         goto out3;
  514         }
  515 
  516         if (kalist.volattr & DARWIN_ATTR_VOL_ATTRIBUTES) { /* XXX */
  517                 darwin_vol_attributes_attr_t data;
  518 
  519                 (void)bzero(&data, sizeof(data));
  520                 if (ATTR_APPEND(data, bp, len) != 0)
  521                         goto out3;
  522         }
  523 
  524         if (kalist.dirattr & DARWIN_ATTR_DIR_LINKCOUNT) {
  525                 unsigned long cnt;
  526 
  527                 cnt = st.st_nlink;
  528                 if (ATTR_APPEND(cnt, bp, len) != 0)
  529                         goto out3;
  530         }
  531 
  532         if (kalist.dirattr & DARWIN_ATTR_DIR_ENTRYCOUNT) { /* XXX */
  533                 unsigned long data;
  534 
  535                 (void)bzero(&data, sizeof(data));
  536                 if (ATTR_APPEND(data, bp, len) != 0)
  537                         goto out3;
  538         }
  539 
  540         if (kalist.dirattr & DARWIN_ATTR_DIR_MOUNTSTATUS) { /* XXX */
  541                 unsigned long data;
  542 
  543                 (void)bzero(&data, sizeof(data));
  544                 if (ATTR_APPEND(data, bp, len) != 0)
  545                         goto out3;
  546         }
  547 
  548         if (kalist.fileattr & DARWIN_ATTR_FILE_LINKCOUNT) {
  549                 unsigned long cnt;
  550 
  551                 cnt = st.st_nlink;
  552                 if (ATTR_APPEND(cnt, bp, len) != 0)
  553                         goto out3;
  554         }
  555 
  556         if (kalist.fileattr & DARWIN_ATTR_FILE_TOTALSIZE) {
  557                 off_t size;
  558 
  559                 size = st.st_size;
  560                 if (ATTR_APPEND(size, bp, len) != 0)
  561                         goto out3;
  562         }
  563 
  564         if (kalist.fileattr & DARWIN_ATTR_FILE_ALLOCSIZE) {
  565                 off_t size;
  566 
  567                 size = st.st_blocks * f->f_bsize;
  568                 if (ATTR_APPEND(size, bp, len) != 0)
  569                         goto out3;
  570         }
  571 
  572         if (kalist.fileattr & DARWIN_ATTR_FILE_IOBLOCKSIZE) {
  573                 unsigned long size;
  574 
  575                 size = st.st_blksize;
  576                 if (ATTR_APPEND(size, bp, len) != 0)
  577                         goto out3;
  578         }
  579 
  580         if (kalist.fileattr & DARWIN_ATTR_FILE_CLUMPSIZE) {
  581                 unsigned long size;
  582 
  583                 size = st.st_blksize; /* XXX probably wrong */
  584                 if (ATTR_APPEND(size, bp, len) != 0)
  585                         goto out3;
  586         }
  587 
  588         if (kalist.fileattr & DARWIN_ATTR_FILE_DEVTYPE) {
  589                 unsigned long type;
  590 
  591                 type = st.st_rdev;
  592                 if (ATTR_APPEND(type, bp, len) != 0)
  593                         goto out3;
  594         }
  595 
  596         if (kalist.fileattr & DARWIN_ATTR_FILE_FILETYPE) {
  597                 unsigned long data;
  598 
  599                 /* Reserved, returns 0 */
  600                 (void)bzero(&data, sizeof(data));
  601                 if (ATTR_APPEND(data, bp, len) != 0)
  602                         goto out3;
  603         }
  604 
  605         if (kalist.fileattr & DARWIN_ATTR_FILE_FORKCOUNT) { /* XXX */
  606                 unsigned long cnt;
  607 
  608                 cnt = 1; /* Only one fork, of course */
  609                 if (ATTR_APPEND(cnt, bp, len) != 0)
  610                         goto out3;
  611         }
  612 
  613         if (kalist.fileattr & DARWIN_ATTR_FILE_FORKLIST) {
  614                 /* Unsupported in Darwin */
  615                 error = EINVAL;
  616                 goto out3;
  617         }
  618 
  619         if (kalist.fileattr & DARWIN_ATTR_FILE_DATALENGTH) { /* All forks */
  620                 off_t size;
  621 
  622                 size = st.st_size;
  623                 if (ATTR_APPEND(size, bp, len) != 0)
  624                         goto out3;
  625         }
  626 
  627         if (kalist.fileattr & DARWIN_ATTR_FILE_DATAALLOCSIZE) { /* All forks */
  628                 off_t size;
  629 
  630                 size = st.st_blocks * f->f_bsize;
  631                 if (ATTR_APPEND(size, bp, len) != 0)
  632                         goto out3;
  633         }
  634 
  635         if (kalist.fileattr & DARWIN_ATTR_FILE_DATAEXTENTS) {
  636                 darwin_extentrecord data;
  637 
  638                 /* Obsolete in Darwin */
  639                 (void)bzero(&data, sizeof(data));
  640                 if (ATTR_APPEND(data, bp, len) != 0)
  641                         goto out3;
  642         }
  643 
  644         if (kalist.fileattr & DARWIN_ATTR_FILE_RSRCLENGTH) {
  645                 off_t size;
  646 
  647                 size = 0;
  648                 if (ATTR_APPEND(size, bp, len) != 0)
  649                         goto out3;
  650         }
  651 
  652         if (kalist.fileattr & DARWIN_ATTR_FILE_RSRCALLOCSIZE) {
  653                 off_t size;
  654 
  655                 size = 0;
  656                 if (ATTR_APPEND(size, bp, len) != 0)
  657                         goto out3;
  658         }
  659 
  660         if (kalist.fileattr & DARWIN_ATTR_FILE_RSRCEXTENTS) {
  661                 darwin_extentrecord data;
  662 
  663                 /* Obsolete in Darwin */
  664                 (void)bzero(&data, sizeof(data));
  665                 if (ATTR_APPEND(data, bp, len) != 0)
  666                         goto out3;
  667         }
  668 
  669         if (kalist.forkattr & DARWIN_ATTR_FORK_TOTALSIZE) {
  670                 off_t size;
  671 
  672                 size = st.st_size;
  673                 if (ATTR_APPEND(size, bp, len) != 0)
  674                         goto out3;
  675         }
  676 
  677         if (kalist.forkattr & DARWIN_ATTR_FORK_ALLOCSIZE) {
  678                 off_t size;
  679 
  680                 size = st.st_blocks * f->f_bsize;
  681                 if (ATTR_APPEND(size, bp, len) != 0)
  682                         goto out3;
  683         }
  684 
  685         /*
  686          * Now the variable length fields
  687          */
  688 
  689         if (cmn_name_p) {               /* DARWIN_ATTR_CMN_NAME */
  690                 cmn_name_p->attr_dataoffset = (u_long)bp - (u_long)cmn_name_p;
  691                 cmn_name_p->attr_length = nd.ni_cnd.cn_namelen;
  692                 if (darwin_attr_append(nd.ni_cnd.cn_nameptr,
  693                     cmn_name_p->attr_length, &bp, &len) != 0)
  694                         goto out3;
  695 
  696                 /* word alignement */
  697                 shift = (((u_long)bp & ~0x3UL) + 4) - (u_long)bp;
  698                 if (darwin_attr_append((char *)null, shift, &bp, &len) != 0)
  699                         goto out3;
  700         }
  701 
  702         if (vol_mountpoint_p) {         /* DARWIN_ATTR_VOL_MOUNTPOINT */
  703                 vol_mountpoint_p->attr_dataoffset =
  704                     (u_long)bp - (u_long)vol_mountpoint_p;
  705                 vol_mountpoint_p->attr_length = strlen(f->f_mntonname);
  706                 if (darwin_attr_append(f->f_mntonname,
  707                     vol_mountpoint_p->attr_length, &bp, &len) != 0)
  708                         goto out3;
  709 
  710                 /* word alignement */
  711                 shift = (((u_long)bp & ~0x3UL) + 4) - (u_long)bp;
  712                 if (darwin_attr_append((char *)null, shift, &bp, &len) != 0)
  713                         goto out3;
  714         }
  715 
  716         if (vol_mounteddevice_p) {      /* DARWIN_ATTR_VOL_MOUNTEDDEVICE */
  717                 vol_mounteddevice_p->attr_dataoffset =
  718                     (u_long)bp - (u_long)vol_mounteddevice_p;
  719                 vol_mounteddevice_p->attr_length = strlen(f->f_mntfromname);
  720                 if (darwin_attr_append(f->f_mntfromname,
  721                     vol_mounteddevice_p->attr_length, &bp, &len) != 0)
  722                         goto out3;
  723 
  724                 /* word alignement */
  725                 shift = (((u_long)bp & ~0x3UL) + 4) - (u_long)bp;
  726                 if (darwin_attr_append((char *)null, shift, &bp, &len) != 0)
  727                         goto out3;
  728         }
  729 
  730         if (vol_name_p) {               /* DARWIN_ATTR_VOL_NAME */
  731                 char name[] = "Volume"; /* XXX We have no volume names... */
  732                 size_t namelen = strlen(name);
  733 
  734                 vol_name_p->attr_dataoffset = (u_long)bp - (u_long)vol_name_p;
  735                 vol_name_p->attr_length = namelen;
  736                 if (darwin_attr_append(name, namelen, &bp, &len) != 0)
  737                         goto out3;
  738 
  739                 /* word alignement */
  740                 shift = (((u_long)bp & ~0x3UL) + 4) - (u_long)bp;
  741                 if (darwin_attr_append((char *)null, shift, &bp, &len) != 0)
  742                         goto out3;
  743         }
  744 
  745         /* And, finnally, the whole buffer length */
  746         if (whole_len_p) {
  747                 *whole_len_p = SCARG(uap, buflen) - len;
  748         }
  749 
  750         /*
  751          * We are done! Copyout the stuff and get away
  752          */
  753         if (error == 0)
  754                 error = copyout(tbuf, SCARG(uap, attributes), *whole_len_p);
  755 out3:
  756         vput(vp);
  757 out2:
  758         kauth_cred_free(cred);
  759         free(tbuf, M_TEMP);
  760 
  761         STATVFSBUF_PUT(f);
  762         return error;
  763 }

Cache object: cdd5916ee53b26cc75badf3381a9a96c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.