1 1.17 christos /* $NetBSD: rot13fs.c,v 1.17 2008/09/12 14:40:47 christos Exp $ */ 2 1.1 pooka 3 1.1 pooka /* 4 1.1 pooka * Copyright (c) 2007 Antti Kantee. All Rights Reserved. 5 1.1 pooka * 6 1.1 pooka * Redistribution and use in source and binary forms, with or without 7 1.1 pooka * modification, are permitted provided that the following conditions 8 1.1 pooka * are met: 9 1.1 pooka * 1. Redistributions of source code must retain the above copyright 10 1.1 pooka * notice, this list of conditions and the following disclaimer. 11 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 pooka * notice, this list of conditions and the following disclaimer in the 13 1.1 pooka * documentation and/or other materials provided with the distribution. 14 1.1 pooka * 15 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16 1.1 pooka * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 1.1 pooka * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 1.1 pooka * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 1.1 pooka * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 1.1 pooka * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 1.1 pooka * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 1.1 pooka * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 1.1 pooka * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 1.1 pooka * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 1.1 pooka * SUCH DAMAGE. 26 1.1 pooka */ 27 1.1 pooka 28 1.1 pooka /* 29 1.1 pooka * rot13fs: puffs layering experiment 30 1.1 pooka * (unfinished, as is probably fairly easy to tell) 31 1.11 pooka * 32 1.11 pooka * This also demonstrates how namemod can be easily set to any 33 1.11 pooka * function which reverses itself (argument -f provides a case-flipping 34 1.11 pooka * file system). 35 1.1 pooka */ 36 1.1 pooka 37 1.11 pooka #include <ctype.h> 38 1.1 pooka #include <err.h> 39 1.1 pooka #include <errno.h> 40 1.1 pooka #include <puffs.h> 41 1.1 pooka #include <stdio.h> 42 1.1 pooka #include <stdlib.h> 43 1.1 pooka #include <unistd.h> 44 1.1 pooka 45 1.1 pooka PUFFSOP_PROTOS(rot13) 46 1.1 pooka 47 1.1 pooka static void usage(void); 48 1.1 pooka 49 1.1 pooka static void 50 1.1 pooka usage() 51 1.1 pooka { 52 1.1 pooka 53 1.17 christos errx(1, "usage: %s [-s] [-o mntopts] rot13path mountpath", 54 1.1 pooka getprogname()); 55 1.1 pooka } 56 1.1 pooka 57 1.11 pooka static void (*flipflop)(void *, size_t); 58 1.11 pooka 59 1.1 pooka static uint8_t tbl[256]; 60 1.1 pooka 61 1.1 pooka static void 62 1.1 pooka dorot13(void *buf, size_t buflen) 63 1.1 pooka { 64 1.1 pooka uint8_t *b = buf; 65 1.1 pooka 66 1.1 pooka while (buflen--) { 67 1.1 pooka *b = tbl[*b]; 68 1.1 pooka b++; 69 1.1 pooka } 70 1.1 pooka } 71 1.1 pooka 72 1.11 pooka static void 73 1.11 pooka docase(void *buf, size_t buflen) 74 1.11 pooka { 75 1.11 pooka unsigned char *b = buf; 76 1.11 pooka 77 1.11 pooka while (buflen--) { 78 1.11 pooka if (isalpha(*b)) 79 1.11 pooka *b ^= 0x20; 80 1.11 pooka b++; 81 1.11 pooka } 82 1.11 pooka } 83 1.11 pooka 84 1.1 pooka static int 85 1.1 pooka rot13path(struct puffs_usermount *pu, struct puffs_pathobj *base, 86 1.1 pooka struct puffs_cn *pcn) 87 1.1 pooka { 88 1.1 pooka 89 1.11 pooka flipflop(pcn->pcn_name, pcn->pcn_namelen); 90 1.1 pooka 91 1.1 pooka return 0; 92 1.1 pooka } 93 1.1 pooka 94 1.1 pooka int 95 1.1 pooka main(int argc, char *argv[]) 96 1.1 pooka { 97 1.1 pooka struct puffs_usermount *pu; 98 1.1 pooka struct puffs_ops *pops; 99 1.1 pooka struct puffs_pathobj *po_root; 100 1.4 pooka struct puffs_node *pn_root; 101 1.1 pooka struct stat sb; 102 1.1 pooka mntoptparse_t mp; 103 1.13 pooka int mntflags, pflags; 104 1.13 pooka int detach; 105 1.1 pooka int ch; 106 1.1 pooka int i; 107 1.1 pooka 108 1.1 pooka setprogname(argv[0]); 109 1.1 pooka 110 1.1 pooka if (argc < 3) 111 1.1 pooka usage(); 112 1.1 pooka 113 1.11 pooka flipflop = dorot13; 114 1.13 pooka pflags = mntflags = 0; 115 1.13 pooka detach = 1; 116 1.11 pooka while ((ch = getopt(argc, argv, "fo:s")) != -1) { 117 1.1 pooka switch (ch) { 118 1.11 pooka case 'f': 119 1.11 pooka flipflop = docase; 120 1.11 pooka break; 121 1.1 pooka case 'o': 122 1.1 pooka mp = getmntopts(optarg, puffsmopts, &mntflags, &pflags); 123 1.1 pooka if (mp == NULL) 124 1.1 pooka err(1, "getmntopts"); 125 1.1 pooka freemntopts(mp); 126 1.1 pooka break; 127 1.1 pooka case 's': 128 1.13 pooka detach = 0; 129 1.1 pooka break; 130 1.1 pooka } 131 1.1 pooka } 132 1.1 pooka pflags |= PUFFS_FLAG_BUILDPATH; 133 1.1 pooka argv += optind; 134 1.1 pooka argc -= optind; 135 1.1 pooka 136 1.1 pooka if (pflags & PUFFS_FLAG_OPDUMP) 137 1.13 pooka detach = 0; 138 1.1 pooka 139 1.1 pooka if (argc != 2) 140 1.1 pooka usage(); 141 1.1 pooka 142 1.7 pooka if (lstat(argv[0], &sb) == -1) 143 1.7 pooka err(1, "stat %s", argv[0]); 144 1.7 pooka if ((sb.st_mode & S_IFDIR) == 0) 145 1.7 pooka errx(1, "%s is not a directory", argv[0]); 146 1.7 pooka 147 1.1 pooka PUFFSOP_INIT(pops); 148 1.10 pooka puffs_null_setops(pops); 149 1.1 pooka 150 1.1 pooka PUFFSOP_SET(pops, rot13, node, readdir); 151 1.1 pooka PUFFSOP_SET(pops, rot13, node, read); 152 1.1 pooka PUFFSOP_SET(pops, rot13, node, write); 153 1.1 pooka 154 1.12 pooka if ((pu = puffs_init(pops, argv[0], "rot13", NULL, pflags)) == NULL) 155 1.1 pooka err(1, "mount"); 156 1.1 pooka 157 1.4 pooka pn_root = puffs_pn_new(pu, NULL); 158 1.4 pooka if (pn_root == NULL) 159 1.1 pooka err(1, "puffs_pn_new"); 160 1.4 pooka puffs_setroot(pu, pn_root); 161 1.1 pooka 162 1.1 pooka po_root = puffs_getrootpathobj(pu); 163 1.1 pooka if (po_root == NULL) 164 1.1 pooka err(1, "getrootpathobj"); 165 1.1 pooka po_root->po_path = argv[0]; 166 1.1 pooka po_root->po_len = strlen(argv[0]); 167 1.7 pooka puffs_stat2vattr(&pn_root->pn_va, &sb); 168 1.1 pooka 169 1.1 pooka puffs_set_namemod(pu, rot13path); 170 1.1 pooka 171 1.1 pooka /* initialize rot13 tables */ 172 1.1 pooka for (i = 0; i < 256; i++) 173 1.1 pooka tbl[i] = (uint8_t)i; 174 1.1 pooka for (i = 0; i <= 26; i++) 175 1.1 pooka tbl[i + 'a'] = 'a' + ((i + 13) % 26); 176 1.1 pooka for (i = 0; i < 26; i++) 177 1.1 pooka tbl[i + 'A'] = 'A' + ((i + 13) % 26); 178 1.1 pooka 179 1.13 pooka if (detach) 180 1.15 pooka if (puffs_daemon(pu, 1, 1) == -1) 181 1.15 pooka err(1, "puffs_daemon"); 182 1.13 pooka 183 1.14 pooka if (puffs_mount(pu, argv[1], mntflags, pn_root) == -1) 184 1.14 pooka err(1, "puffs_mount"); 185 1.13 pooka if (puffs_mainloop(pu) == -1) 186 1.14 pooka err(1, "mainloop"); 187 1.13 pooka 188 1.13 pooka return 0; 189 1.1 pooka } 190 1.1 pooka 191 1.1 pooka int 192 1.16 pooka rot13_node_readdir(struct puffs_usermount *pu, void *opc, struct dirent *dent, 193 1.3 pooka off_t *readoff, size_t *reslen, const struct puffs_cred *pcr, 194 1.3 pooka int *eofflag, off_t *cookies, size_t *ncookies) 195 1.1 pooka { 196 1.1 pooka struct dirent *dp; 197 1.1 pooka size_t rl; 198 1.1 pooka int rv; 199 1.1 pooka 200 1.1 pooka dp = dent; 201 1.1 pooka rl = *reslen; 202 1.1 pooka 203 1.16 pooka rv = puffs_null_node_readdir(pu, opc, dent, readoff, reslen, pcr, 204 1.3 pooka eofflag, cookies, ncookies); 205 1.1 pooka if (rv) 206 1.1 pooka return rv; 207 1.1 pooka 208 1.1 pooka while (rl > *reslen) { 209 1.11 pooka flipflop((uint8_t *)dp->d_name, dp->d_namlen); 210 1.1 pooka rl -= _DIRENT_SIZE(dp); 211 1.1 pooka dp = _DIRENT_NEXT(dp); 212 1.1 pooka } 213 1.1 pooka 214 1.1 pooka return 0; 215 1.1 pooka } 216 1.1 pooka 217 1.1 pooka int 218 1.16 pooka rot13_node_read(struct puffs_usermount *pu, void *opc, 219 1.16 pooka uint8_t *buf, off_t offset, size_t *resid, 220 1.16 pooka const struct puffs_cred *pcr, int ioflag) 221 1.1 pooka { 222 1.1 pooka uint8_t *prebuf = buf; 223 1.1 pooka size_t preres = *resid; 224 1.1 pooka int rv; 225 1.1 pooka 226 1.16 pooka rv = puffs_null_node_read(pu, opc, buf, offset, resid, pcr, ioflag); 227 1.1 pooka if (rv) 228 1.1 pooka return rv; 229 1.1 pooka 230 1.11 pooka flipflop(prebuf, preres - *resid); 231 1.1 pooka 232 1.1 pooka return rv; 233 1.1 pooka } 234 1.1 pooka 235 1.1 pooka int 236 1.16 pooka rot13_node_write(struct puffs_usermount *pu, void *opc, 237 1.16 pooka uint8_t *buf, off_t offset, size_t *resid, 238 1.16 pooka const struct puffs_cred *pcr, int ioflag) 239 1.1 pooka { 240 1.1 pooka 241 1.11 pooka flipflop(buf, *resid); 242 1.16 pooka return puffs_null_node_write(pu, opc, buf, offset, resid, pcr, ioflag); 243 1.1 pooka } 244