1/* 2 * 3 * FreeBSD install - a package for the installation and maintainance 4 * of non-core utilities. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * Jordan K. Hubbard 16 * 18 July 1993 17 * 18 * This is the delete module. 19 * 20 */ 21 22#include <sys/cdefs.h> 23__FBSDID("$FreeBSD$"); 24 25#include <sys/types.h> 26#include <sys/stat.h> 27#include <getopt.h> 28#include <err.h> 29 30#include "lib.h" 31#include "delete.h" 32 33char *Prefix = NULL; 34Boolean CleanDirs = FALSE; 35Boolean Interactive = FALSE; 36Boolean NoDeInstall = FALSE; 37Boolean Recursive = FALSE; 38match_t MatchType = MATCH_GLOB; 39 40static void usage(void); 41 42static char opts[] = "adDfGhinp:rvxX"; 43static struct option longopts[] = { 44 { "all", no_argument, NULL, 'a' }, 45 { "clean-dirs", no_argument, NULL, 'd' }, 46 { "dry-run", no_argument, NULL, 'n' }, 47 { "extended", no_argument, NULL, 'X' }, 48 { "force", no_argument, NULL, 'f' }, 49 { "help", no_argument, NULL, 'h' }, 50 { "interactive",no_argument, NULL, 'i' }, 51 { "prefix", required_argument, NULL, 'p' }, 52 { "recursive", no_argument, NULL, 'r' }, 53 { "regex", no_argument, NULL, 'x' }, 54 { "no-glob", no_argument, NULL, 'G' }, 55 { "no-script", no_argument, NULL, 'D' }, 56 { "no-scripts", no_argument, NULL, 'D' }, 57 { "verbose", no_argument, NULL, 'v' }, 58 { NULL, 0, NULL, 0 }, 59}; 60 61int 62main(int argc, char **argv) 63{ 64 int ch, error; 65 char **pkgs, **start; 66 char *pkgs_split; 67 const char *tmp; 68 struct stat stat_s; 69 70 pkgs = start = argv; 71 while ((ch = getopt_long(argc, argv, opts, longopts, NULL)) != -1) 72 switch(ch) { 73 case 'v': 74 Verbose++; 75 break; 76 77 case 'f': 78 Force = TRUE; 79 break; 80 81 case 'p': 82 Prefix = optarg; 83 break; 84 85 case 'D': 86 NoDeInstall = TRUE; 87 break; 88 89 case 'd': 90 CleanDirs = TRUE; 91 break; 92 93 case 'n': 94 Fake = TRUE; 95 Verbose = TRUE; 96 break; 97 98 case 'a': 99 MatchType = MATCH_ALL; 100 break; 101 102 case 'G': 103 MatchType = MATCH_EXACT; 104 break; 105 106 case 'x': 107 MatchType = MATCH_REGEX; 108 break; 109 110 case 'X': 111 MatchType = MATCH_EREGEX; 112 break; 113 114 case 'i': 115 Interactive = TRUE; 116 break; 117 118 case 'r': 119 Recursive = TRUE; 120 break; 121 122 case 'h': 123 default: 124 usage(); 125 break; 126 } 127 128 argc -= optind; 129 argv += optind; 130 131 /* Get all the remaining package names, if any */ 132 while (*argv) { 133 /* Don't try to apply heuristics if arguments are regexs */ 134 if (MatchType != MATCH_REGEX) 135 while ((pkgs_split = strrchr(*argv, (int)'/')) != NULL) { 136 *pkgs_split++ = '\0'; 137 /* 138 * If character after the '/' is alphanumeric, then we've found the 139 * package name. Otherwise we've come across a trailing '/' and 140 * need to continue our quest. 141 */ 142 if (isalnum(*pkgs_split) || ((MatchType == MATCH_GLOB) && \ 143 strpbrk(pkgs_split, "*?[]") != NULL)) { 144 *argv = pkgs_split; 145 break; 146 } 147 } 148 *pkgs++ = *argv++; 149 } 150 151 /* If no packages, yelp */ 152 if (pkgs == start && MatchType != MATCH_ALL) 153 warnx("missing package name(s)"), usage(); 154 *pkgs = NULL; 155 tmp = LOG_DIR; 156 (void) stat(tmp, &stat_s); 157 if (!Fake && getuid() && geteuid() != stat_s.st_uid) { 158 if (!Force) 159 errx(1, "you do not own %s, use -f to force", tmp); 160 else 161 warnx("you do not own %s (proceeding anyways)", tmp); 162 } 163 if ((error = pkg_perform(start)) != 0) { 164 if (Verbose) 165 warnx("%d package deletion(s) failed", error); 166 return error; 167 } 168 else 169 return 0; 170} 171 172static void 173usage(void) 174{ 175 fprintf(stderr, "%s\n%s\n", 176 "usage: pkg_delete [-dDfGinrvxX] [-p prefix] pkg-name ...", 177 " pkg_delete -a [flags]"); 178 exit(1); 179} 180