which.c (b7a311f2b8b14ef9b7dd0f741a447315fa8d43ee) | which.c (cc70d84c4a6b6e1c0224bbdfd5bd306252d9fb4f) |
---|---|
1/** 2 * Copyright (c) 2000 Dan Papasian. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 8 unchanged lines hidden (view full) --- 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 1/** 2 * Copyright (c) 2000 Dan Papasian. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 8 unchanged lines hidden (view full) --- 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 * 26 * $FreeBSD$ |
|
25 */ 26 | 27 */ 28 |
27#include <sys/cdefs.h> 28 29__FBSDID("$FreeBSD$"); 30 | |
31#include <sys/stat.h> 32#include <sys/param.h> 33 34#include <err.h> 35#include <stdio.h> 36#include <stdlib.h> 37#include <string.h> 38#include <unistd.h> --- 8 unchanged lines hidden (view full) --- 47main(int argc, char **argv) 48{ 49 char *p, *path; 50 ssize_t pathlen; 51 int opt, status; 52 53 status = EXIT_SUCCESS; 54 | 29#include <sys/stat.h> 30#include <sys/param.h> 31 32#include <err.h> 33#include <stdio.h> 34#include <stdlib.h> 35#include <string.h> 36#include <unistd.h> --- 8 unchanged lines hidden (view full) --- 45main(int argc, char **argv) 46{ 47 char *p, *path; 48 ssize_t pathlen; 49 int opt, status; 50 51 status = EXIT_SUCCESS; 52 |
53 /* If called without args, die silently to conform */ 54 if (argc < 2) 55 exit(EXIT_FAILURE); 56 |
|
55 while ((opt = getopt(argc, argv, "as")) != -1) { 56 switch (opt) { 57 case 'a': 58 allpaths = 1; 59 break; 60 case 's': 61 silent = 1; 62 break; 63 default: 64 usage(); 65 break; 66 } 67 } 68 69 argv += optind; 70 argc -= optind; 71 | 57 while ((opt = getopt(argc, argv, "as")) != -1) { 58 switch (opt) { 59 case 'a': 60 allpaths = 1; 61 break; 62 case 's': 63 silent = 1; 64 break; 65 default: 66 usage(); 67 break; 68 } 69 } 70 71 argv += optind; 72 argc -= optind; 73 |
72 if (argc == 0) 73 usage(); 74 | |
75 if ((p = getenv("PATH")) == NULL) 76 exit(EXIT_FAILURE); 77 pathlen = strlen(p) + 1; 78 path = malloc(pathlen); 79 if (path == NULL) 80 err(EXIT_FAILURE, NULL); 81 | 74 if ((p = getenv("PATH")) == NULL) 75 exit(EXIT_FAILURE); 76 pathlen = strlen(p) + 1; 77 path = malloc(pathlen); 78 if (path == NULL) 79 err(EXIT_FAILURE, NULL); 80 |
81 if (argc == 0) 82 status = EXIT_FAILURE; 83 |
|
82 while (argc > 0) { 83 memcpy(path, p, pathlen); 84 | 84 while (argc > 0) { 85 memcpy(path, p, pathlen); 86 |
85 if (strlen(*argv) >= FILENAME_MAX || | 87 if (strlen(*argv) > FILENAME_MAX || |
86 print_matches(path, *argv) == -1) 87 status = EXIT_FAILURE; 88 89 argv++; 90 argc--; 91 } 92 93 exit(status); 94} 95 96static void 97usage(void) 98{ 99 | 88 print_matches(path, *argv) == -1) 89 status = EXIT_FAILURE; 90 91 argv++; 92 argc--; 93 } 94 95 exit(status); 96} 97 98static void 99usage(void) 100{ 101 |
100 (void)fprintf(stderr, "usage: which [-as] program ...\n"); 101 exit(EXIT_FAILURE); | 102 errx(EXIT_FAILURE, "usage: which [-as] program ..."); |
102} 103 104static int 105is_there(char *candidate) 106{ 107 struct stat fin; 108 109 /* XXX work around access(2) false positives for superuser */ --- 8 unchanged lines hidden (view full) --- 118 } 119 return (0); 120} 121 122static int 123print_matches(char *path, char *filename) 124{ 125 char candidate[PATH_MAX]; | 103} 104 105static int 106is_there(char *candidate) 107{ 108 struct stat fin; 109 110 /* XXX work around access(2) false positives for superuser */ --- 8 unchanged lines hidden (view full) --- 119 } 120 return (0); 121} 122 123static int 124print_matches(char *path, char *filename) 125{ 126 char candidate[PATH_MAX]; |
126 const char *d; | 127 char *d; |
127 int found; 128 | 128 int found; 129 |
129 if (strchr(filename, '/') != NULL) | 130 if (*filename == '/') |
130 return (is_there(filename) ? 0 : -1); 131 found = 0; 132 while ((d = strsep(&path, ":")) != NULL) { | 131 return (is_there(filename) ? 0 : -1); 132 found = 0; 133 while ((d = strsep(&path, ":")) != NULL) { |
133 if (*d == '\0') 134 d = "."; | |
135 if (snprintf(candidate, sizeof(candidate), "%s/%s", d, | 134 if (snprintf(candidate, sizeof(candidate), "%s/%s", d, |
136 filename) >= (int)sizeof(candidate)) | 135 filename) >= sizeof(candidate)) |
137 continue; 138 if (is_there(candidate)) { 139 found = 1; 140 if (!allpaths) 141 break; 142 } 143 } 144 return (found ? 0 : -1); 145} 146 | 136 continue; 137 if (is_there(candidate)) { 138 found = 1; 139 if (!allpaths) 140 break; 141 } 142 } 143 return (found ? 0 : -1); 144} 145 |