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 2006 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 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <strings.h> 33 #include <sys/param.h> 34 #include <fcntl.h> 35 #include <sys/errno.h> 36 #include <sys/types.h> 37 #include <sys/uio.h> 38 #include <unistd.h> 39 #include <sys/stat.h> 40 #include <errno.h> 41 #include <libgen.h> 42 #include "stdusers.h" 43 44 45 #define FILE_BUFF 40960 46 47 int supress = 0; 48 49 50 void 51 usage(void) 52 { 53 (void) fprintf(stderr, 54 "usage: install [-sd][-m mode][-g group][-u owner] " 55 "-f dir file ...\n"); 56 } 57 58 void 59 file_copy(char *src_file, char *dest_file) 60 { 61 int src_fd; 62 int dest_fd; 63 int count; 64 static char file_buff[FILE_BUFF]; 65 66 if ((src_fd = open(src_file, O_RDONLY)) == -1) { 67 perror(src_file); 68 exit(1); 69 } 70 71 if ((dest_fd = open(dest_file, O_CREAT|O_WRONLY|O_TRUNC, 0755)) == -1) { 72 perror(dest_file); 73 exit(1); 74 } 75 76 while ((count = read(src_fd, file_buff, FILE_BUFF)) > 0) { 77 write(dest_fd, file_buff, count); 78 } 79 80 if (count == -1) { 81 perror("file_copy(read)"); 82 exit(1); 83 } 84 85 if (!supress) 86 (void) printf("%s installed as %s\n", src_file, dest_file); 87 88 close(src_fd); 89 close(dest_fd); 90 } 91 92 93 void 94 chown_file(const char *file, const char *group, const char *owner) 95 { 96 gid_t grp = -1; 97 uid_t own = -1; 98 99 if (group) { 100 grp = stdfind(group, groupnames); 101 if (grp < 0) 102 (void) fprintf(stderr, "unknown group(%s)\n", group); 103 } 104 105 if (owner) { 106 own = stdfind(owner, usernames); 107 if (own < 0) { 108 (void) fprintf(stderr, "unknown owner(%s)\n", owner); 109 exit(1); 110 } 111 112 } 113 114 if (chown(file, own, grp) == -1) { 115 perror("chown"); 116 exit(1); 117 } 118 } 119 120 char * 121 find_basename(const char *str) 122 { 123 int i; 124 int len; 125 126 len = strlen(str); 127 128 for (i = len-1; i >= 0; i--) 129 if (str[i] == '/') 130 return ((char *)(str + i + 1)); 131 return ((char *)str); 132 } 133 134 135 int 136 main(int argc, char **argv) 137 { 138 int c; 139 int errflg = 0; 140 int dirflg = 0; 141 char *group = NULL; 142 char *owner = NULL; 143 char *dirb = NULL; 144 char *ins_file = NULL; 145 int mode = -1; 146 char dest_file[MAXPATHLEN]; 147 148 149 while ((c = getopt(argc, argv, "f:sm:du:g:")) != EOF) { 150 switch (c) { 151 case 'f': 152 dirb = optarg; 153 break; 154 case 'g': 155 group = optarg; 156 break; 157 case 'u': 158 owner = optarg; 159 break; 160 case 'd': 161 dirflg = 1; 162 break; 163 case 'm': 164 mode = strtol(optarg, NULL, 8); 165 break; 166 case 's': 167 supress = 1; 168 break; 169 case '?': 170 errflg++; 171 break; 172 } 173 } 174 175 if (errflg) { 176 usage(); 177 return (1); 178 } 179 180 if (argc == optind) { 181 usage(); 182 return (1); 183 } 184 185 if (!dirflg && (dirb == NULL)) { 186 (void) fprintf(stderr, 187 "install: no destination directory specified.\n"); 188 return (1); 189 } 190 191 192 for (c = optind; c < argc; c++) { 193 ins_file = argv[c]; 194 195 if (dirflg) { 196 struct stat buf; 197 198 if (stat(ins_file, &buf) == 0) { 199 if ((buf.st_mode & S_IFMT) == S_IFDIR) 200 continue; 201 } else { 202 if (errno != ENOENT) { 203 perror("install: stat"); 204 return (1); 205 } 206 } 207 208 (void) strcpy(dest_file, ins_file); 209 210 if (mkdirp(dest_file, 0755) == -1) { 211 if (!supress) { 212 (void) printf( 213 "install: mkdirp of %s failed\n", 214 dest_file); 215 } 216 } else if (!supress) { 217 (void) printf("directory %s created\n", 218 dest_file); 219 } 220 } else { 221 (void) strcat(strcat(strcpy(dest_file, dirb), "/"), 222 find_basename(ins_file)); 223 file_copy(ins_file, dest_file); 224 } 225 226 if (group || owner) 227 chown_file(dest_file, group, owner); 228 229 if (mode != -1) { 230 umask(0); 231 if (chmod(dest_file, mode) == -1) { 232 perror("chmod"); 233 return (1); 234 } 235 } 236 } 237 return (0); 238 } 239