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