1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 1996-2003 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #pragma ident   "%Z%%M% %I%     %E% SMI"
  28 
  29 #include <locale.h>
  30 #include <sys/types.h>
  31 #include <sys/param.h>
  32 #include <stdio.h>
  33 #include <dirent.h>
  34 #include <sys/acl.h>
  35 #include <sys/fs/cachefs_fs.h>
  36 #include <sys/fs/cachefs_dlog.h>
  37 #include <sys/fs/cachefs_ioctl.h>
  38 #include <errno.h>
  39 #include <string.h>
  40 
  41 extern int verbose;
  42 
  43 /*
  44  * Function used by -d option to display pathname
  45  */
  46 int
  47 prtfn(char *pathnam, char *fnam, DIR *dirp, int depth)
  48 {
  49         printf("%s\n", pathnam);
  50         return (0);
  51 }
  52 
  53 /*
  54  * Function used by -p option to pack pathname
  55  */
  56 int
  57 packfn(char *pathnam, char *fnam, DIR *dirp, int depth)
  58 {
  59         cachefsio_pack_t pack;
  60         int xx;
  61         int len;
  62 
  63 #ifdef DEBUG
  64         printf("packfn: pathnam = %s", pathnam);
  65         fflush(stdout);
  66         if (fnam != NULL) {
  67                 printf("  fnam = %s\n",  fnam);
  68         } else {
  69                 printf("\n");
  70         }
  71         printf("packfn: dirp    = %x depth = %d\n", dirp, depth);
  72         fflush(stdout);
  73 #endif /* DEBUG */
  74         if (fnam != NULL) {
  75                 len = strlen(fnam);
  76                 if (len >= sizeof (pack.p_name)) {
  77                         fprintf(stderr, gettext(
  78                             "cachefspack: file name too long - %s\n"),
  79                             pathnam);
  80                         return (-1);
  81                 }
  82 #ifdef DEBUG
  83                 printf("packfn: len = %d\n", len);
  84                 fflush(stdout);
  85 #endif /* DEBUG */
  86                 while (fnam[len-1] == '/') {
  87                     len--;
  88                 }
  89                 strncpy(pack.p_name, fnam, len);
  90         } else {
  91                 len = 0;
  92         }
  93         pack.p_name[len] = '\0';
  94         pack.p_status = 0;
  95 #ifdef DEBUG
  96         printf("packfn: pack.p_name = %s  pack.p_status = %x\n",
  97                 pack.p_name, pack.p_status);
  98         fflush(stdout);
  99 #endif /* DEBUG */
 100 
 101         xx = ioctl(dirp->dd_fd, CACHEFSIO_PACK, &pack);
 102 #ifdef DEBUG
 103         printf("packfn: xx = %x  errno = %d\n", xx, errno);
 104         fflush(stdout);
 105 #endif /* DEBUG */
 106         if (xx) {
 107                 if (errno == ENOTTY) {
 108                         return (0);
 109                 }
 110                 if (errno == ENOSYS) {
 111                         return (0);
 112                 }
 113                 fprintf(stderr, gettext("cachefspack: %s -  "), pathnam);
 114                 perror(gettext("can't pack file"));
 115                 return (-1);
 116         }
 117         return (0);
 118 }
 119 
 120 /*
 121  * Function used by -p option to unpack pathname
 122  */
 123 int
 124 unpackfn(char *pathnam, char *fnam, DIR *dirp, int depth)
 125 {
 126         cachefsio_pack_t pack;
 127         int xx;
 128         int len;
 129 
 130 #ifdef DEBUG
 131         printf("unpackfn: pathnam = %s ", pathnam);
 132         if (fnam != NULL) {
 133                 printf("  fnam = %s\n", fnam);
 134         } else {
 135                 printf("\n");
 136         }
 137         printf("unpackfn: dirp    = %x depth = %d\n", dirp, depth);
 138         fflush(stdout);
 139 #endif /* DEBUG */
 140         if (fnam != NULL) {
 141                 len = strlen(fnam);
 142                 if (len >= sizeof (pack.p_name)) {
 143                         fprintf(stderr, gettext(
 144                             "cachefspack: file name too long - %s\n"), pathnam);
 145                         return (-1);
 146                 }
 147                 while (fnam[len-1] == '/') {
 148                     len--;
 149                 }
 150                 strncpy(pack.p_name, fnam, len);
 151         } else {
 152                 len = 0;
 153         }
 154         pack.p_name[len] = '\0';
 155         pack.p_status = 0;
 156 #ifdef DEBUG
 157         printf("unpackfn: pack.p_name = %s  pack.p_status = %x\n",
 158                 pack.p_name, pack.p_status);
 159         fflush(stdout);
 160 #endif /* DEBUG */
 161 
 162         xx = ioctl(dirp->dd_fd, CACHEFSIO_UNPACK, &pack);
 163 #ifdef DEBUG
 164         printf("unpackfn: pack.p_name = %s  pack.p_status = %x\n",
 165                 pack.p_name, pack.p_status);
 166         fflush(stdout);
 167 #endif /* DEBUG */
 168         if (xx) {
 169                 if (errno == ENOTTY) {
 170                         return (0);
 171                 }
 172                 if (errno == ENOSYS) {
 173                         return (0);
 174                 }
 175                 fprintf(stderr, gettext("cachefspack: %s - "), pathnam);
 176                 perror(gettext("can't unpack file"));
 177                 return (-1);
 178         }
 179         return (0);
 180 }
 181 
 182 /*
 183  * Function used by -i option to print status of pathname
 184  */
 185 int
 186 inquirefn(char *pathnam, char *fnam, DIR *dirp, int depth)
 187 {
 188         cachefsio_pack_t pack;
 189         int xx;
 190         int len;
 191 
 192 #ifdef DEBUG
 193         printf("inquirefn: pathnam = %s ", pathnam);
 194         if (fnam != NULL) {
 195                 printf("fnam = %s\n", fnam);
 196         } else {
 197                 printf("\n");
 198         }
 199         printf("inquirefn: dirp    = %x depth = %d\n", dirp, depth);
 200         fflush(stdout);
 201 #endif /* DEBUG */
 202         if (fnam != NULL) {
 203                 len = strlen(fnam);
 204                 if (len >= sizeof (pack.p_name)) {
 205                         fprintf(stderr,
 206                             gettext("cachefspack: file name too long - %s\n"),
 207                             pathnam);
 208                         return (-1);
 209                 }
 210                 while (fnam[len-1] == '/') {
 211                     len--;
 212                 }
 213                 strncpy(pack.p_name, fnam, len);
 214         } else {
 215                 len = 0;
 216         }
 217         pack.p_name[len] = '\0';
 218         pack.p_status = 0;
 219 #ifdef DEBUG
 220         printf("inquirefn: pack.p_name = %s  pack.p_status = %x\n",
 221                 pack.p_name, pack.p_status);
 222         fflush(stdout);
 223 #endif /* DEBUG */
 224 
 225         xx = ioctl(dirp->dd_fd, CACHEFSIO_PACKINFO, &pack);
 226 #ifdef DEBUG
 227         printf("inquirefn: xx = %x  errno = %d\n", xx, errno);
 228         fflush(stdout);
 229 #endif /* DEBUG */
 230         if (xx) {
 231                 if ((errno == ENOTTY) || (errno == ENOSYS)) {
 232 #ifdef CFS_MSG
 233                         fprintf(stderr, gettext("cachefspack:  "));
 234                         fprintf(stderr,
 235                             gettext("%s - is not in a cacheFS file system\n"),
 236                             pathnam);
 237 #endif /* CFS_MSG */
 238                         return (-1);
 239                 }
 240                 fprintf(stderr, gettext("cachefspack: %s - "), pathnam);
 241                 perror(gettext("can't get info"));
 242                 return (-2);
 243         }
 244 
 245         printf(gettext("cachefspack: file %s "), pathnam);
 246         printf(gettext("marked packed %s, packed %s\n"),
 247             (pack.p_status & CACHEFS_PACKED_FILE) ? "YES" : "NO",
 248             (pack.p_status & CACHEFS_PACKED_DATA) ? "YES" : "NO");
 249         if (verbose) {
 250                 printf(gettext("    nocache %s\n"),
 251                     (pack.p_status & CACHEFS_PACKED_NOCACHE) ?
 252                     "YES" : "NO");
 253         }
 254         return (0);
 255 }