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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/wait.h> 28 #include <sys/param.h> 29 #include <sys/stat.h> 30 #include <sys/modctl.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <unistd.h> 34 #include <string.h> 35 #include <fcntl.h> 36 #include <errno.h> 37 #include <zone.h> 38 39 void l_exec_userfile(char *execfile, int id, char **envp); 40 void l_usage(); 41 42 extern void fatal(char *fmt, ...); 43 extern void error(char *fmt, ...); 44 45 /* 46 * Load a module. 47 */ 48 int 49 main(int argc, char *argv[], char *envp[]) 50 { 51 char *execfile = NULL; /* name of file to exec after loading */ 52 char *modpath = NULL; 53 int id; 54 extern int optind; 55 extern char *optarg; 56 int opt; 57 int use_path = 0; 58 char path[1024]; 59 60 if (argc < 2 || argc > 5) { 61 l_usage(); 62 } 63 64 while ((opt = getopt(argc, argv, "e:p")) != -1) { 65 switch (opt) { 66 case 'e': 67 execfile = optarg; 68 break; 69 case 'p': 70 use_path++; 71 break; 72 case '?': 73 l_usage(); 74 } 75 } 76 77 if (getzoneid() != GLOBAL_ZONEID) { 78 fatal("modload can only be run from the global zone\n"); 79 } 80 81 modpath = argv[optind]; 82 83 if (modpath == NULL) { 84 (void) printf("modpath is null\n"); 85 l_usage(); 86 } 87 if (!use_path && modpath[0] != '/') { 88 if (getcwd(path, 1023 - strlen(modpath)) == NULL) 89 fatal("Can't get current directory\n"); 90 (void) strcat(path, "/"); 91 (void) strcat(path, modpath); 92 } else 93 (void) strcpy(path, modpath); 94 95 /* 96 * Load the module. 97 */ 98 if (modctl(MODLOAD, use_path, path, &id) != 0) { 99 if (errno == EPERM) 100 fatal("Insufficient privileges to load a module\n"); 101 else 102 error("can't load module"); 103 } 104 105 /* 106 * Exec the user's file (if any) 107 */ 108 if (execfile) 109 l_exec_userfile(execfile, id, envp); 110 111 return (0); /* success */ 112 } 113 114 /* 115 * Exec the user's file 116 */ 117 void 118 l_exec_userfile(char *execfile, int id, char **envp) 119 { 120 struct modinfo modinfo; 121 122 int child; 123 int status; 124 int waitret; 125 char module_id[8]; 126 char mod0[8]; 127 128 if ((child = fork()) == -1) 129 error("can't fork %s", execfile); 130 131 /* 132 * exec the user program. 133 */ 134 if (child == 0) { 135 modinfo.mi_id = id; 136 modinfo.mi_nextid = id; 137 modinfo.mi_info = MI_INFO_ONE; 138 if (modctl(MODINFO, id, &modinfo) < 0) 139 error("can't get module status"); 140 141 (void) sprintf(module_id, "%d", modinfo.mi_id); 142 (void) sprintf(mod0, "%d", modinfo.mi_msinfo[0].msi_p0); 143 (void) execle(execfile, execfile, module_id, mod0, NULL, envp); 144 145 /* Shouldn't get here if execle was successful */ 146 147 error("couldn't exec %s", execfile); 148 } else { 149 do { 150 /* wait for exec'd program to finish */ 151 waitret = wait(&status); 152 } while ((waitret != child) && (waitret != -1)); 153 154 waitret = (waitret == -1) ? waitret : status; 155 156 if ((waitret & 0377) != 0) { 157 /* exited because of a signal */ 158 (void) printf("'%s' terminated because of signal %d", 159 execfile, (waitret & 0177)); 160 if (waitret & 0200) 161 (void) printf(" and produced a core file\n"); 162 (void) printf(".\n"); 163 exit(waitret >> 8); 164 } else { 165 /* simple termination */ 166 if (((waitret >> 8) & 0377) != 0) { 167 (void) printf("'%s' returned error %d.\n", 168 execfile, (waitret >> 8) & 0377); 169 exit(waitret >> 8); 170 } 171 } 172 } 173 } 174 175 void 176 l_usage() 177 { 178 fatal("usage: modload [-p] [-e <exec_file>] <filename>\n"); 179 } 180