1171801Sdelphij/* $NetBSD: h_tools.c,v 1.8 2007/07/23 15:05:43 jmmv Exp $ */ 2170809Sdelphij 3170809Sdelphij/*- 4170809Sdelphij * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc. 5170809Sdelphij * All rights reserved. 6170809Sdelphij * 7170809Sdelphij * This code is derived from software contributed to The NetBSD Foundation 8170809Sdelphij * by Julio M. Merino Vidal, developed as part of Google's Summer of Code 9170809Sdelphij * 2005 program. 10170809Sdelphij * 11170809Sdelphij * Redistribution and use in source and binary forms, with or without 12170809Sdelphij * modification, are permitted provided that the following conditions 13170809Sdelphij * are met: 14170809Sdelphij * 1. Redistributions of source code must retain the above copyright 15170809Sdelphij * notice, this list of conditions and the following disclaimer. 16170809Sdelphij * 2. Redistributions in binary form must reproduce the above copyright 17170809Sdelphij * notice, this list of conditions and the following disclaimer in the 18170809Sdelphij * documentation and/or other materials provided with the distribution. 19170809Sdelphij * 20170809Sdelphij * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21170809Sdelphij * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22170809Sdelphij * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23170809Sdelphij * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24170809Sdelphij * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25170809Sdelphij * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26170809Sdelphij * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27170809Sdelphij * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28170809Sdelphij * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29170809Sdelphij * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30170809Sdelphij * POSSIBILITY OF SUCH DAMAGE. 31170809Sdelphij * 32170809Sdelphij * $FreeBSD$ 33170809Sdelphij */ 34170809Sdelphij 35170809Sdelphij/* 36170809Sdelphij * Helper tools for several tests. These are kept in a single file due 37170809Sdelphij * to the limitations of bsd.prog.mk to build a single program in a 38170809Sdelphij * given directory. 39170809Sdelphij */ 40170809Sdelphij 41170809Sdelphij#include <sys/param.h> 42170809Sdelphij#include <sys/types.h> 43170809Sdelphij#include <sys/event.h> 44170809Sdelphij#include <sys/mount.h> 45170809Sdelphij#include <sys/statvfs.h> 46197849Sdelphij#include <sys/stdint.h> 47170809Sdelphij#include <sys/socket.h> 48170809Sdelphij#include <sys/time.h> 49170809Sdelphij#include <sys/un.h> 50170809Sdelphij 51170809Sdelphij#include <assert.h> 52170809Sdelphij#include <err.h> 53170809Sdelphij#include <errno.h> 54170809Sdelphij#include <fcntl.h> 55170809Sdelphij#include <stdio.h> 56170809Sdelphij#include <stdlib.h> 57170809Sdelphij#include <string.h> 58170809Sdelphij#include <unistd.h> 59170809Sdelphij 60170809Sdelphij/* --------------------------------------------------------------------- */ 61170809Sdelphij 62170809Sdelphijstatic int getfh_main(int, char **); 63170809Sdelphijstatic int kqueue_main(int, char **); 64170809Sdelphijstatic int rename_main(int, char **); 65170809Sdelphijstatic int sockets_main(int, char **); 66170809Sdelphijstatic int statvfs_main(int, char **); 67170809Sdelphij 68170809Sdelphij/* --------------------------------------------------------------------- */ 69170809Sdelphij 70170809Sdelphijint 71170809Sdelphijgetfh_main(int argc, char **argv) 72170809Sdelphij{ 73170809Sdelphij int error; 74170809Sdelphij fhandle_t fh; 75170809Sdelphij 76170809Sdelphij if (argc < 2) 77170809Sdelphij return EXIT_FAILURE; 78170809Sdelphij 79170809Sdelphij error = getfh(argv[1], &fh); 80170809Sdelphij if (error == 0) 81170809Sdelphij err(EXIT_FAILURE, "can not getfh"); 82170809Sdelphij 83170809Sdelphij error = write(STDOUT_FILENO, &fh, sizeof(fh)); 84170809Sdelphij if (error == -1) { 85170809Sdelphij perror("write"); 86170809Sdelphij return EXIT_FAILURE; 87170809Sdelphij } 88170809Sdelphij 89170809Sdelphij return 0; 90170809Sdelphij} 91170809Sdelphij 92170809Sdelphij/* --------------------------------------------------------------------- */ 93170809Sdelphij 94170809Sdelphijint 95170809Sdelphijkqueue_main(int argc, char **argv) 96170809Sdelphij{ 97170809Sdelphij char *line; 98170809Sdelphij int i, kq; 99170809Sdelphij size_t len; 100170809Sdelphij struct kevent *changes, event; 101170809Sdelphij 102170809Sdelphij if (argc < 2) 103170809Sdelphij return EXIT_FAILURE; 104170809Sdelphij 105170809Sdelphij argc--; 106170809Sdelphij argv++; 107170809Sdelphij 108170809Sdelphij changes = malloc(sizeof(struct kevent) * (argc - 1)); 109170809Sdelphij if (changes == NULL) 110170809Sdelphij errx(EXIT_FAILURE, "not enough memory"); 111170809Sdelphij 112170809Sdelphij for (i = 0; i < argc; i++) { 113170809Sdelphij int fd; 114170809Sdelphij 115170809Sdelphij fd = open(argv[i], O_RDONLY); 116170809Sdelphij if (fd == -1) 117170809Sdelphij err(EXIT_FAILURE, "cannot open %s", argv[i]); 118170809Sdelphij 119170809Sdelphij EV_SET(&changes[i], fd, EVFILT_VNODE, 120170809Sdelphij EV_ADD | EV_ENABLE | EV_ONESHOT, 121170809Sdelphij NOTE_ATTRIB | NOTE_DELETE | NOTE_EXTEND | NOTE_LINK | 122170809Sdelphij NOTE_RENAME | NOTE_REVOKE | NOTE_WRITE, 123170809Sdelphij 0, 0); 124170809Sdelphij } 125170809Sdelphij 126170809Sdelphij kq = kqueue(); 127170809Sdelphij if (kq == -1) 128170809Sdelphij err(EXIT_FAILURE, "kqueue"); 129170809Sdelphij 130170809Sdelphij while ((line = fgetln(stdin, &len)) != NULL) { 131170809Sdelphij int ec, nev; 132170809Sdelphij struct timespec to; 133170809Sdelphij 134170809Sdelphij to.tv_sec = 0; 135170809Sdelphij to.tv_nsec = 100000; 136170809Sdelphij 137170809Sdelphij (void)kevent(kq, changes, argc, &event, 1, &to); 138170809Sdelphij 139170809Sdelphij assert(len > 0); 140170809Sdelphij assert(line[len - 1] == '\n'); 141170809Sdelphij line[len - 1] = '\0'; 142170809Sdelphij ec = system(line); 143170809Sdelphij if (ec != EXIT_SUCCESS) 144170809Sdelphij errx(ec, "%s returned %d", line, ec); 145170809Sdelphij 146170809Sdelphij do { 147170809Sdelphij nev = kevent(kq, changes, argc, &event, 1, &to); 148170809Sdelphij if (nev == -1) 149170809Sdelphij err(EXIT_FAILURE, "kevent"); 150170809Sdelphij else if (nev > 0) { 151170809Sdelphij for (i = 0; i < argc; i++) 152170809Sdelphij if (event.ident == changes[i].ident) 153170809Sdelphij break; 154170809Sdelphij 155170809Sdelphij if (event.fflags & NOTE_ATTRIB) 156170809Sdelphij printf("%s - NOTE_ATTRIB\n", argv[i]); 157170809Sdelphij if (event.fflags & NOTE_DELETE) 158170809Sdelphij printf("%s - NOTE_DELETE\n", argv[i]); 159170809Sdelphij if (event.fflags & NOTE_EXTEND) 160170809Sdelphij printf("%s - NOTE_EXTEND\n", argv[i]); 161170809Sdelphij if (event.fflags & NOTE_LINK) 162170809Sdelphij printf("%s - NOTE_LINK\n", argv[i]); 163170809Sdelphij if (event.fflags & NOTE_RENAME) 164170809Sdelphij printf("%s - NOTE_RENAME\n", argv[i]); 165170809Sdelphij if (event.fflags & NOTE_REVOKE) 166170809Sdelphij printf("%s - NOTE_REVOKE\n", argv[i]); 167170809Sdelphij if (event.fflags & NOTE_WRITE) 168170809Sdelphij printf("%s - NOTE_WRITE\n", argv[i]); 169170809Sdelphij } 170170809Sdelphij } while (nev > 0); 171170809Sdelphij } 172170809Sdelphij 173170809Sdelphij for (i = 0; i < argc; i++) 174170809Sdelphij close(changes[i].ident); 175170809Sdelphij free(changes); 176170809Sdelphij 177170809Sdelphij return EXIT_SUCCESS; 178170809Sdelphij} 179170809Sdelphij 180170809Sdelphij/* --------------------------------------------------------------------- */ 181170809Sdelphij 182170809Sdelphijint 183170809Sdelphijrename_main(int argc, char **argv) 184170809Sdelphij{ 185170809Sdelphij 186170809Sdelphij if (argc < 3) 187170809Sdelphij return EXIT_FAILURE; 188170809Sdelphij 189171801Sdelphij if (rename(argv[1], argv[2]) == -1) { 190171801Sdelphij perror("rename"); 191171801Sdelphij return EXIT_FAILURE; 192171801Sdelphij } 193171801Sdelphij 194171801Sdelphij return EXIT_SUCCESS; 195170809Sdelphij} 196170809Sdelphij 197170809Sdelphij/* --------------------------------------------------------------------- */ 198170809Sdelphij 199170809Sdelphijint 200170809Sdelphijsockets_main(int argc, char **argv) 201170809Sdelphij{ 202170809Sdelphij int error, fd; 203170809Sdelphij struct sockaddr_un addr; 204170809Sdelphij 205170809Sdelphij if (argc < 2) 206170809Sdelphij return EXIT_FAILURE; 207170809Sdelphij 208170809Sdelphij fd = socket(PF_LOCAL, SOCK_STREAM, 0); 209170809Sdelphij if (fd == -1) { 210170809Sdelphij perror("socket"); 211170809Sdelphij return EXIT_FAILURE; 212170809Sdelphij } 213170809Sdelphij 214170809Sdelphij (void)strlcpy(addr.sun_path, argv[1], sizeof(addr.sun_path)); 215170809Sdelphij addr.sun_family = PF_UNIX; 216170809Sdelphij 217170809Sdelphij error = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); 218170809Sdelphij if (error == -1) { 219170809Sdelphij perror("connect"); 220170809Sdelphij return EXIT_FAILURE; 221170809Sdelphij } 222170809Sdelphij 223170809Sdelphij close(fd); 224170809Sdelphij 225170809Sdelphij return EXIT_SUCCESS; 226170809Sdelphij} 227170809Sdelphij 228170809Sdelphij/* --------------------------------------------------------------------- */ 229170809Sdelphij 230170809Sdelphijint 231170809Sdelphijstatvfs_main(int argc, char **argv) 232170809Sdelphij{ 233170809Sdelphij int error; 234170809Sdelphij struct statfs buf; 235170809Sdelphij 236170809Sdelphij if (argc < 2) 237170809Sdelphij return EXIT_FAILURE; 238170809Sdelphij 239170809Sdelphij memset(&buf, 0, sizeof(buf)); 240170809Sdelphij buf.f_version = STATFS_VERSION; 241170809Sdelphij error = statfs(argv[1], &buf); 242170809Sdelphij if (error != 0) { 243170809Sdelphij perror("statvfs"); 244170809Sdelphij return EXIT_FAILURE; 245170809Sdelphij } 246170809Sdelphij 247197849Sdelphij (void)printf("f_bsize=%ju\n", (uintmax_t)buf.f_bsize); 248197849Sdelphij (void)printf("f_blocks=%ju\n", (uintmax_t)buf.f_blocks); 249197849Sdelphij (void)printf("f_bfree=%ju\n", (uintmax_t)buf.f_bfree); 250197849Sdelphij (void)printf("f_files=%ju\n", (uintmax_t)buf.f_files); 251170809Sdelphij 252170809Sdelphij return EXIT_SUCCESS; 253170809Sdelphij} 254170809Sdelphij 255170809Sdelphij/* --------------------------------------------------------------------- */ 256170809Sdelphij 257170809Sdelphijint 258170809Sdelphijmain(int argc, char **argv) 259170809Sdelphij{ 260170809Sdelphij int error; 261170809Sdelphij 262170809Sdelphij if (argc < 2) 263170809Sdelphij return EXIT_FAILURE; 264170809Sdelphij 265170809Sdelphij argc -= 1; 266170809Sdelphij argv += 1; 267170809Sdelphij 268170809Sdelphij if (strcmp(argv[0], "getfh") == 0) 269170809Sdelphij error = getfh_main(argc, argv); 270170809Sdelphij else if (strcmp(argv[0], "kqueue") == 0) 271170809Sdelphij error = kqueue_main(argc, argv); 272170809Sdelphij else if (strcmp(argv[0], "rename") == 0) 273170809Sdelphij error = rename_main(argc, argv); 274170809Sdelphij else if (strcmp(argv[0], "sockets") == 0) 275170809Sdelphij error = sockets_main(argc, argv); 276170809Sdelphij else if (strcmp(argv[0], "statvfs") == 0) 277170809Sdelphij error = statvfs_main(argc, argv); 278170809Sdelphij else 279170809Sdelphij error = EXIT_FAILURE; 280170809Sdelphij 281170809Sdelphij return error; 282170809Sdelphij} 283