1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright (c) 2001 by Sun Microsystems, Inc. 24*7c478bd9Sstevel@tonic-gate * All rights reserved. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * runat: run a command in attribute directory. 31*7c478bd9Sstevel@tonic-gate * 32*7c478bd9Sstevel@tonic-gate * runat file [command] 33*7c478bd9Sstevel@tonic-gate * 34*7c478bd9Sstevel@tonic-gate * when command is not specified an interactive shell is started 35*7c478bd9Sstevel@tonic-gate * in the attribute directory. 36*7c478bd9Sstevel@tonic-gate */ 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #include <stdio.h> 39*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 40*7c478bd9Sstevel@tonic-gate #include <unistd.h> 41*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 42*7c478bd9Sstevel@tonic-gate #include <libintl.h> 43*7c478bd9Sstevel@tonic-gate #include <errno.h> 44*7c478bd9Sstevel@tonic-gate #include <strings.h> 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate static void 47*7c478bd9Sstevel@tonic-gate usage() 48*7c478bd9Sstevel@tonic-gate { 49*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("usage: runat filename [command]\n")); 50*7c478bd9Sstevel@tonic-gate } 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate int 53*7c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 54*7c478bd9Sstevel@tonic-gate { 55*7c478bd9Sstevel@tonic-gate int fd; 56*7c478bd9Sstevel@tonic-gate int dirfd; 57*7c478bd9Sstevel@tonic-gate int i; 58*7c478bd9Sstevel@tonic-gate int argslen; 59*7c478bd9Sstevel@tonic-gate char *shell; 60*7c478bd9Sstevel@tonic-gate char *args[4]; 61*7c478bd9Sstevel@tonic-gate char *cmdargs; 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate if (argc < 2) { 64*7c478bd9Sstevel@tonic-gate usage(); 65*7c478bd9Sstevel@tonic-gate exit(127); 66*7c478bd9Sstevel@tonic-gate } 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate if ((fd = open64(argv[1], O_RDONLY)) == -1) { 69*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 70*7c478bd9Sstevel@tonic-gate gettext("runat: cannot open %s: %s\n"), argv[1], 71*7c478bd9Sstevel@tonic-gate strerror(errno)); 72*7c478bd9Sstevel@tonic-gate exit(125); 73*7c478bd9Sstevel@tonic-gate } 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate if ((dirfd = openat64(fd, ".", O_RDONLY|O_XATTR)) == -1) { 76*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 77*7c478bd9Sstevel@tonic-gate gettext("runat: cannot open attribute" 78*7c478bd9Sstevel@tonic-gate " directory for %s: %s\n"), argv[1], strerror(errno)); 79*7c478bd9Sstevel@tonic-gate exit(125); 80*7c478bd9Sstevel@tonic-gate } 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate (void) close(fd); 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate if (fchdir(dirfd) == -1) { 85*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 86*7c478bd9Sstevel@tonic-gate gettext("runat: cannot fchdir to attribute" 87*7c478bd9Sstevel@tonic-gate " directory: %s\n"), strerror(errno)); 88*7c478bd9Sstevel@tonic-gate exit(125); 89*7c478bd9Sstevel@tonic-gate } 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate if (argc < 3) { 92*7c478bd9Sstevel@tonic-gate shell = getenv("SHELL"); 93*7c478bd9Sstevel@tonic-gate if (shell == NULL) { 94*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 95*7c478bd9Sstevel@tonic-gate gettext( 96*7c478bd9Sstevel@tonic-gate "runat: shell not found, using /bin/sh\n")); 97*7c478bd9Sstevel@tonic-gate shell = "/bin/sh"; 98*7c478bd9Sstevel@tonic-gate } 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate (void) execl(shell, shell, NULL); 101*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 102*7c478bd9Sstevel@tonic-gate gettext("runat: Failed to exec %s: %s\n"), shell, 103*7c478bd9Sstevel@tonic-gate strerror(errno)); 104*7c478bd9Sstevel@tonic-gate return (126); 105*7c478bd9Sstevel@tonic-gate } 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate /* 108*7c478bd9Sstevel@tonic-gate * Count up the size of all of the args 109*7c478bd9Sstevel@tonic-gate */ 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate for (i = 2, argslen = 0; i < argc; i++) { 112*7c478bd9Sstevel@tonic-gate argslen += strlen(argv[i]) + 1; 113*7c478bd9Sstevel@tonic-gate } 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate cmdargs = calloc(1, argslen); 116*7c478bd9Sstevel@tonic-gate if (cmdargs == NULL) { 117*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 118*7c478bd9Sstevel@tonic-gate "runat: failed to allocate memory for" 119*7c478bd9Sstevel@tonic-gate " command arguments: %s\n"), strerror(errno)); 120*7c478bd9Sstevel@tonic-gate exit(126); 121*7c478bd9Sstevel@tonic-gate } 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate /* 125*7c478bd9Sstevel@tonic-gate * create string with all of the args concatenated together 126*7c478bd9Sstevel@tonic-gate * This is done so that the shell will interpret the args 127*7c478bd9Sstevel@tonic-gate * and do globbing if necessary. 128*7c478bd9Sstevel@tonic-gate */ 129*7c478bd9Sstevel@tonic-gate for (i = 2; i < argc; i++) { 130*7c478bd9Sstevel@tonic-gate if (strlcat(cmdargs, argv[i], argslen) >= argslen) { 131*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 132*7c478bd9Sstevel@tonic-gate "runat: arguments won't fit in" 133*7c478bd9Sstevel@tonic-gate " allocated buffer\n")); 134*7c478bd9Sstevel@tonic-gate exit(126); 135*7c478bd9Sstevel@tonic-gate } 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate /* 138*7c478bd9Sstevel@tonic-gate * tack on a space if there are more args 139*7c478bd9Sstevel@tonic-gate */ 140*7c478bd9Sstevel@tonic-gate if ((i + 1) < argc) { 141*7c478bd9Sstevel@tonic-gate if (strlcat(cmdargs, " ", argslen) >= argslen) { 142*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 143*7c478bd9Sstevel@tonic-gate "runat: arguments won't fit in" 144*7c478bd9Sstevel@tonic-gate " allocated buffer\n")); 145*7c478bd9Sstevel@tonic-gate exit(126); 146*7c478bd9Sstevel@tonic-gate } 147*7c478bd9Sstevel@tonic-gate } 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate } 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate args[0] = "/bin/sh"; 152*7c478bd9Sstevel@tonic-gate args[1] = "-c"; 153*7c478bd9Sstevel@tonic-gate args[2] = cmdargs; 154*7c478bd9Sstevel@tonic-gate args[3] = NULL; 155*7c478bd9Sstevel@tonic-gate (void) execvp(args[0], args); 156*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("runat: Failed to exec %s: %s\n"), 157*7c478bd9Sstevel@tonic-gate argv[0], strerror(errno)); 158*7c478bd9Sstevel@tonic-gate return (126); 159*7c478bd9Sstevel@tonic-gate } 160