1*57718be8SEnji Cooper /* $NetBSD: h_tools.c,v 1.4 2011/06/11 18:03:17 christos Exp $ */ 2*57718be8SEnji Cooper 3*57718be8SEnji Cooper /* 4*57718be8SEnji Cooper * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc. 5*57718be8SEnji Cooper * All rights reserved. 6*57718be8SEnji Cooper * 7*57718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without 8*57718be8SEnji Cooper * modification, are permitted provided that the following conditions 9*57718be8SEnji Cooper * are met: 10*57718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 11*57718be8SEnji Cooper * notice, this list of conditions and the following disclaimer. 12*57718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 13*57718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the 14*57718be8SEnji Cooper * documentation and/or other materials provided with the distribution. 15*57718be8SEnji Cooper * 16*57718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17*57718be8SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18*57718be8SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19*57718be8SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20*57718be8SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21*57718be8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22*57718be8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23*57718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24*57718be8SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25*57718be8SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26*57718be8SEnji Cooper * POSSIBILITY OF SUCH DAMAGE. 27*57718be8SEnji Cooper */ 28*57718be8SEnji Cooper 29*57718be8SEnji Cooper /* 30*57718be8SEnji Cooper * Helper tools for several tests. These are kept in a single file due 31*57718be8SEnji Cooper * to the limitations of bsd.prog.mk to build a single program in a 32*57718be8SEnji Cooper * given directory. 33*57718be8SEnji Cooper */ 34*57718be8SEnji Cooper 35*57718be8SEnji Cooper #include <sys/param.h> 36*57718be8SEnji Cooper #include <sys/types.h> 37*57718be8SEnji Cooper #include <sys/event.h> 38*57718be8SEnji Cooper #include <sys/mount.h> 39*57718be8SEnji Cooper #include <sys/statvfs.h> 40*57718be8SEnji Cooper #include <sys/socket.h> 41*57718be8SEnji Cooper #include <sys/time.h> 42*57718be8SEnji Cooper #include <sys/un.h> 43*57718be8SEnji Cooper 44*57718be8SEnji Cooper #include <assert.h> 45*57718be8SEnji Cooper #include <err.h> 46*57718be8SEnji Cooper #include <errno.h> 47*57718be8SEnji Cooper #include <fcntl.h> 48*57718be8SEnji Cooper #include <stdio.h> 49*57718be8SEnji Cooper #include <stdlib.h> 50*57718be8SEnji Cooper #include <string.h> 51*57718be8SEnji Cooper #include <unistd.h> 52*57718be8SEnji Cooper 53*57718be8SEnji Cooper /* --------------------------------------------------------------------- */ 54*57718be8SEnji Cooper 55*57718be8SEnji Cooper static int getfh_main(int, char **); 56*57718be8SEnji Cooper static int kqueue_main(int, char **); 57*57718be8SEnji Cooper static int rename_main(int, char **); 58*57718be8SEnji Cooper static int sockets_main(int, char **); 59*57718be8SEnji Cooper static int statvfs_main(int, char **); 60*57718be8SEnji Cooper 61*57718be8SEnji Cooper /* --------------------------------------------------------------------- */ 62*57718be8SEnji Cooper 63*57718be8SEnji Cooper int 64*57718be8SEnji Cooper getfh_main(int argc, char **argv) 65*57718be8SEnji Cooper { 66*57718be8SEnji Cooper int error; 67*57718be8SEnji Cooper void *fh; 68*57718be8SEnji Cooper size_t fh_size; 69*57718be8SEnji Cooper 70*57718be8SEnji Cooper if (argc < 2) 71*57718be8SEnji Cooper return EXIT_FAILURE; 72*57718be8SEnji Cooper 73*57718be8SEnji Cooper fh_size = 0; 74*57718be8SEnji Cooper fh = NULL; 75*57718be8SEnji Cooper for (;;) { 76*57718be8SEnji Cooper if (fh_size) { 77*57718be8SEnji Cooper fh = malloc(fh_size); 78*57718be8SEnji Cooper if (fh == NULL) { 79*57718be8SEnji Cooper fprintf(stderr, "out of memory"); 80*57718be8SEnji Cooper return EXIT_FAILURE; 81*57718be8SEnji Cooper } 82*57718be8SEnji Cooper } 83*57718be8SEnji Cooper /* 84*57718be8SEnji Cooper * The kernel provides the necessary size in fh_size - 85*57718be8SEnji Cooper * but it may change if someone moves things around, 86*57718be8SEnji Cooper * so retry untill we have enough memory. 87*57718be8SEnji Cooper */ 88*57718be8SEnji Cooper error = getfh(argv[1], fh, &fh_size); 89*57718be8SEnji Cooper if (error == 0) { 90*57718be8SEnji Cooper break; 91*57718be8SEnji Cooper } else { 92*57718be8SEnji Cooper if (fh != NULL) 93*57718be8SEnji Cooper free(fh); 94*57718be8SEnji Cooper if (errno != E2BIG) { 95*57718be8SEnji Cooper warn("getfh"); 96*57718be8SEnji Cooper return EXIT_FAILURE; 97*57718be8SEnji Cooper } 98*57718be8SEnji Cooper } 99*57718be8SEnji Cooper } 100*57718be8SEnji Cooper 101*57718be8SEnji Cooper error = write(STDOUT_FILENO, fh, fh_size); 102*57718be8SEnji Cooper if (error == -1) { 103*57718be8SEnji Cooper warn("write"); 104*57718be8SEnji Cooper return EXIT_FAILURE; 105*57718be8SEnji Cooper } 106*57718be8SEnji Cooper free(fh); 107*57718be8SEnji Cooper 108*57718be8SEnji Cooper return 0; 109*57718be8SEnji Cooper } 110*57718be8SEnji Cooper 111*57718be8SEnji Cooper /* --------------------------------------------------------------------- */ 112*57718be8SEnji Cooper 113*57718be8SEnji Cooper int 114*57718be8SEnji Cooper kqueue_main(int argc, char **argv) 115*57718be8SEnji Cooper { 116*57718be8SEnji Cooper char *line; 117*57718be8SEnji Cooper int i, kq; 118*57718be8SEnji Cooper size_t len; 119*57718be8SEnji Cooper struct kevent *changes, event; 120*57718be8SEnji Cooper 121*57718be8SEnji Cooper if (argc < 2) 122*57718be8SEnji Cooper return EXIT_FAILURE; 123*57718be8SEnji Cooper 124*57718be8SEnji Cooper argc--; 125*57718be8SEnji Cooper argv++; 126*57718be8SEnji Cooper 127*57718be8SEnji Cooper changes = malloc(sizeof(struct kevent) * argc); 128*57718be8SEnji Cooper if (changes == NULL) 129*57718be8SEnji Cooper errx(EXIT_FAILURE, "not enough memory"); 130*57718be8SEnji Cooper 131*57718be8SEnji Cooper for (i = 0; i < argc; i++) { 132*57718be8SEnji Cooper int fd; 133*57718be8SEnji Cooper 134*57718be8SEnji Cooper fd = open(argv[i], O_RDONLY); 135*57718be8SEnji Cooper if (fd == -1) 136*57718be8SEnji Cooper err(EXIT_FAILURE, "cannot open %s", argv[i]); 137*57718be8SEnji Cooper 138*57718be8SEnji Cooper EV_SET(&changes[i], fd, EVFILT_VNODE, 139*57718be8SEnji Cooper EV_ADD | EV_ENABLE | EV_ONESHOT, 140*57718be8SEnji Cooper NOTE_ATTRIB | NOTE_DELETE | NOTE_EXTEND | NOTE_LINK | 141*57718be8SEnji Cooper NOTE_RENAME | NOTE_REVOKE | NOTE_WRITE, 142*57718be8SEnji Cooper 0, 0); 143*57718be8SEnji Cooper } 144*57718be8SEnji Cooper 145*57718be8SEnji Cooper kq = kqueue(); 146*57718be8SEnji Cooper if (kq == -1) 147*57718be8SEnji Cooper err(EXIT_FAILURE, "kqueue"); 148*57718be8SEnji Cooper 149*57718be8SEnji Cooper while ((line = fgetln(stdin, &len)) != NULL) { 150*57718be8SEnji Cooper int ec, nev; 151*57718be8SEnji Cooper struct timespec to; 152*57718be8SEnji Cooper 153*57718be8SEnji Cooper to.tv_sec = 0; 154*57718be8SEnji Cooper to.tv_nsec = 100000; 155*57718be8SEnji Cooper 156*57718be8SEnji Cooper (void)kevent(kq, changes, argc, &event, 1, &to); 157*57718be8SEnji Cooper 158*57718be8SEnji Cooper assert(len > 0); 159*57718be8SEnji Cooper assert(line[len - 1] == '\n'); 160*57718be8SEnji Cooper line[len - 1] = '\0'; 161*57718be8SEnji Cooper ec = system(line); 162*57718be8SEnji Cooper if (ec != EXIT_SUCCESS) 163*57718be8SEnji Cooper errx(ec, "%s returned %d", line, ec); 164*57718be8SEnji Cooper 165*57718be8SEnji Cooper do { 166*57718be8SEnji Cooper nev = kevent(kq, changes, argc, &event, 1, &to); 167*57718be8SEnji Cooper if (nev == -1) 168*57718be8SEnji Cooper err(EXIT_FAILURE, "kevent"); 169*57718be8SEnji Cooper else if (nev > 0) { 170*57718be8SEnji Cooper for (i = 0; i < argc; i++) 171*57718be8SEnji Cooper if (event.ident == changes[i].ident) 172*57718be8SEnji Cooper break; 173*57718be8SEnji Cooper 174*57718be8SEnji Cooper if (event.fflags & NOTE_ATTRIB) 175*57718be8SEnji Cooper printf("%s - NOTE_ATTRIB\n", argv[i]); 176*57718be8SEnji Cooper if (event.fflags & NOTE_DELETE) 177*57718be8SEnji Cooper printf("%s - NOTE_DELETE\n", argv[i]); 178*57718be8SEnji Cooper if (event.fflags & NOTE_EXTEND) 179*57718be8SEnji Cooper printf("%s - NOTE_EXTEND\n", argv[i]); 180*57718be8SEnji Cooper if (event.fflags & NOTE_LINK) 181*57718be8SEnji Cooper printf("%s - NOTE_LINK\n", argv[i]); 182*57718be8SEnji Cooper if (event.fflags & NOTE_RENAME) 183*57718be8SEnji Cooper printf("%s - NOTE_RENAME\n", argv[i]); 184*57718be8SEnji Cooper if (event.fflags & NOTE_REVOKE) 185*57718be8SEnji Cooper printf("%s - NOTE_REVOKE\n", argv[i]); 186*57718be8SEnji Cooper if (event.fflags & NOTE_WRITE) 187*57718be8SEnji Cooper printf("%s - NOTE_WRITE\n", argv[i]); 188*57718be8SEnji Cooper } 189*57718be8SEnji Cooper } while (nev > 0); 190*57718be8SEnji Cooper } 191*57718be8SEnji Cooper 192*57718be8SEnji Cooper for (i = 0; i < argc; i++) 193*57718be8SEnji Cooper close(changes[i].ident); 194*57718be8SEnji Cooper free(changes); 195*57718be8SEnji Cooper 196*57718be8SEnji Cooper return EXIT_SUCCESS; 197*57718be8SEnji Cooper } 198*57718be8SEnji Cooper 199*57718be8SEnji Cooper /* --------------------------------------------------------------------- */ 200*57718be8SEnji Cooper 201*57718be8SEnji Cooper int 202*57718be8SEnji Cooper rename_main(int argc, char **argv) 203*57718be8SEnji Cooper { 204*57718be8SEnji Cooper 205*57718be8SEnji Cooper if (argc < 3) 206*57718be8SEnji Cooper return EXIT_FAILURE; 207*57718be8SEnji Cooper 208*57718be8SEnji Cooper if (rename(argv[1], argv[2]) == -1) { 209*57718be8SEnji Cooper warn("rename"); 210*57718be8SEnji Cooper return EXIT_FAILURE; 211*57718be8SEnji Cooper } 212*57718be8SEnji Cooper 213*57718be8SEnji Cooper return EXIT_SUCCESS; 214*57718be8SEnji Cooper } 215*57718be8SEnji Cooper 216*57718be8SEnji Cooper /* --------------------------------------------------------------------- */ 217*57718be8SEnji Cooper 218*57718be8SEnji Cooper int 219*57718be8SEnji Cooper sockets_main(int argc, char **argv) 220*57718be8SEnji Cooper { 221*57718be8SEnji Cooper int error, fd; 222*57718be8SEnji Cooper struct sockaddr_un addr; 223*57718be8SEnji Cooper 224*57718be8SEnji Cooper if (argc < 2) 225*57718be8SEnji Cooper return EXIT_FAILURE; 226*57718be8SEnji Cooper 227*57718be8SEnji Cooper fd = socket(PF_LOCAL, SOCK_STREAM, 0); 228*57718be8SEnji Cooper if (fd == -1) { 229*57718be8SEnji Cooper warn("socket"); 230*57718be8SEnji Cooper return EXIT_FAILURE; 231*57718be8SEnji Cooper } 232*57718be8SEnji Cooper 233*57718be8SEnji Cooper (void)strlcpy(addr.sun_path, argv[1], sizeof(addr.sun_path)); 234*57718be8SEnji Cooper addr.sun_family = PF_UNIX; 235*57718be8SEnji Cooper 236*57718be8SEnji Cooper error = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); 237*57718be8SEnji Cooper if (error == -1) { 238*57718be8SEnji Cooper warn("connect"); 239*57718be8SEnji Cooper return EXIT_FAILURE; 240*57718be8SEnji Cooper } 241*57718be8SEnji Cooper 242*57718be8SEnji Cooper close(fd); 243*57718be8SEnji Cooper 244*57718be8SEnji Cooper return EXIT_SUCCESS; 245*57718be8SEnji Cooper } 246*57718be8SEnji Cooper 247*57718be8SEnji Cooper /* --------------------------------------------------------------------- */ 248*57718be8SEnji Cooper 249*57718be8SEnji Cooper int 250*57718be8SEnji Cooper statvfs_main(int argc, char **argv) 251*57718be8SEnji Cooper { 252*57718be8SEnji Cooper int error; 253*57718be8SEnji Cooper struct statvfs buf; 254*57718be8SEnji Cooper 255*57718be8SEnji Cooper if (argc < 2) 256*57718be8SEnji Cooper return EXIT_FAILURE; 257*57718be8SEnji Cooper 258*57718be8SEnji Cooper error = statvfs(argv[1], &buf); 259*57718be8SEnji Cooper if (error != 0) { 260*57718be8SEnji Cooper warn("statvfs"); 261*57718be8SEnji Cooper return EXIT_FAILURE; 262*57718be8SEnji Cooper } 263*57718be8SEnji Cooper 264*57718be8SEnji Cooper (void)printf("f_bsize=%lu\n", buf.f_bsize); 265*57718be8SEnji Cooper (void)printf("f_blocks=%" PRId64 "\n", buf.f_blocks); 266*57718be8SEnji Cooper (void)printf("f_bfree=%" PRId64 "\n", buf.f_bfree); 267*57718be8SEnji Cooper (void)printf("f_files=%" PRId64 "\n", buf.f_files); 268*57718be8SEnji Cooper 269*57718be8SEnji Cooper return EXIT_SUCCESS; 270*57718be8SEnji Cooper } 271*57718be8SEnji Cooper 272*57718be8SEnji Cooper /* --------------------------------------------------------------------- */ 273*57718be8SEnji Cooper 274*57718be8SEnji Cooper int 275*57718be8SEnji Cooper main(int argc, char **argv) 276*57718be8SEnji Cooper { 277*57718be8SEnji Cooper int error; 278*57718be8SEnji Cooper 279*57718be8SEnji Cooper if (argc < 2) 280*57718be8SEnji Cooper return EXIT_FAILURE; 281*57718be8SEnji Cooper 282*57718be8SEnji Cooper argc -= 1; 283*57718be8SEnji Cooper argv += 1; 284*57718be8SEnji Cooper 285*57718be8SEnji Cooper if (strcmp(argv[0], "getfh") == 0) 286*57718be8SEnji Cooper error = getfh_main(argc, argv); 287*57718be8SEnji Cooper else if (strcmp(argv[0], "kqueue") == 0) 288*57718be8SEnji Cooper error = kqueue_main(argc, argv); 289*57718be8SEnji Cooper else if (strcmp(argv[0], "rename") == 0) 290*57718be8SEnji Cooper error = rename_main(argc, argv); 291*57718be8SEnji Cooper else if (strcmp(argv[0], "sockets") == 0) 292*57718be8SEnji Cooper error = sockets_main(argc, argv); 293*57718be8SEnji Cooper else if (strcmp(argv[0], "statvfs") == 0) 294*57718be8SEnji Cooper error = statvfs_main(argc, argv); 295*57718be8SEnji Cooper else 296*57718be8SEnji Cooper error = EXIT_FAILURE; 297*57718be8SEnji Cooper 298*57718be8SEnji Cooper return error; 299*57718be8SEnji Cooper } 300