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