main.c revision 103149
113722Sasami/* 213722Sasami * 313722Sasami * FreeBSD install - a package for the installation and maintainance 413049Sasami * of non-core utilities. 513049Sasami * 613049Sasami * Redistribution and use in source and binary forms, with or without 713049Sasami * modification, are permitted provided that the following conditions 813049Sasami * are met: 913049Sasami * 1. Redistributions of source code must retain the above copyright 1013049Sasami * notice, this list of conditions and the following disclaimer. 1113049Sasami * 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 info module. 19 * 20 */ 21 22#include <sys/cdefs.h> 23__FBSDID("$FreeBSD: head/usr.sbin/pkg_install/info/main.c 103149 2002-09-09 19:43:30Z sobomax $"); 24 25#include "lib.h" 26#include "info.h" 27#include <err.h> 28 29static char Options[] = "acdDe:fgGhiIkl:LmoO:pPqrRst:vVW:x"; 30 31int Flags = 0; 32match_t MatchType = MATCH_GLOB; 33Boolean Quiet = FALSE; 34char *InfoPrefix = (char *)(uintptr_t)""; 35char PlayPen[FILENAME_MAX]; 36char *CheckPkg = NULL; 37char *LookUpOrigin = NULL; 38struct which_head *whead; 39 40static void usage __P((void)); 41 42int 43main(int argc, char **argv) 44{ 45 int ch; 46 char **pkgs, **start; 47 char *pkgs_split; 48 49 whead = malloc(sizeof(struct which_head)); 50 if (whead == NULL) 51 err(2, NULL); 52 TAILQ_INIT(whead); 53 54 pkgs = start = argv; 55 if (argc == 1) { 56 MatchType = MATCH_ALL; 57 Flags = SHOW_INDEX; 58 } 59 else while ((ch = getopt(argc, argv, Options)) != -1) { 60 switch(ch) { 61 case 'a': 62 MatchType = MATCH_ALL; 63 break; 64 65 case 'v': 66 Verbose = TRUE; 67 /* Reasonable definition of 'everything' */ 68 Flags = SHOW_COMMENT | SHOW_DESC | SHOW_PLIST | SHOW_INSTALL | 69 SHOW_DEINSTALL | SHOW_REQUIRE | SHOW_DISPLAY | SHOW_MTREE; 70 break; 71 72 case 'I': 73 Flags |= SHOW_INDEX; 74 break; 75 76 case 'p': 77 Flags |= SHOW_PREFIX; 78 break; 79 80 case 'c': 81 Flags |= SHOW_COMMENT; 82 break; 83 84 case 'd': 85 Flags |= SHOW_DESC; 86 break; 87 88 case 'D': 89 Flags |= SHOW_DISPLAY; 90 break; 91 92 case 'f': 93 Flags |= SHOW_PLIST; 94 break; 95 96 case 'g': 97 Flags |= SHOW_CKSUM; 98 break; 99 100 case 'G': 101 MatchType = MATCH_EXACT; 102 break; 103 104 case 'i': 105 Flags |= SHOW_INSTALL; 106 break; 107 108 case 'k': 109 Flags |= SHOW_DEINSTALL; 110 break; 111 112 case 'r': 113 Flags |= SHOW_REQUIRE; 114 break; 115 116 case 'R': 117 Flags |= SHOW_REQBY; 118 break; 119 120 case 'L': 121 Flags |= SHOW_FILES; 122 break; 123 124 case 'm': 125 Flags |= SHOW_MTREE; 126 break; 127 128 case 's': 129 Flags |= SHOW_SIZE; 130 break; 131 132 case 'o': 133 Flags |= SHOW_ORIGIN; 134 break; 135 136 case 'O': 137 LookUpOrigin = strdup(optarg); 138 if (LookUpOrigin == NULL) 139 err(2, NULL); 140 break; 141 142 case 'V': 143 Flags |= SHOW_FMTREV; 144 break; 145 146 case 'l': 147 InfoPrefix = optarg; 148 break; 149 150 case 'q': 151 Quiet = TRUE; 152 break; 153 154 case 't': 155 strlcpy(PlayPen, optarg, sizeof(PlayPen)); 156 break; 157 158 case 'x': 159 MatchType = MATCH_REGEX; 160 break; 161 162 case 'e': 163 CheckPkg = optarg; 164 break; 165 166 case 'W': 167 { 168 struct which_entry *entp; 169 170 entp = calloc(1, sizeof(struct which_entry)); 171 if (entp == NULL) 172 err(2, NULL); 173 174 strlcpy(entp->file, optarg, PATH_MAX); 175 entp->skip = FALSE; 176 TAILQ_INSERT_TAIL(whead, entp, next); 177 break; 178 } 179 180 case 'P': 181 Flags = SHOW_PTREV; 182 break; 183 184 case 'h': 185 case '?': 186 default: 187 usage(); 188 break; 189 } 190 } 191 192 argc -= optind; 193 argv += optind; 194 195 if (Flags & SHOW_PTREV) { 196 if (!Quiet) 197 printf("Package tools revision: "); 198 printf("%d\n", PKG_INSTALL_VERSION); 199 exit(0); 200 } 201 202 /* Set some reasonable defaults */ 203 if (!Flags) 204 Flags = SHOW_COMMENT | SHOW_DESC | SHOW_REQBY; 205 206 /* Get all the remaining package names, if any */ 207 while (*argv) { 208 /* 209 * Don't try to apply heuristics if arguments are regexs or if 210 * the argument refers to an existing file. 211 */ 212 if (MatchType != MATCH_REGEX && !isfile(*argv)) 213 while ((pkgs_split = strrchr(*argv, (int)'/')) != NULL) { 214 *pkgs_split++ = '\0'; 215 /* 216 * If character after the '/' is alphanumeric or shell 217 * metachar, then we've found the package name. Otherwise 218 * we've come across a trailing '/' and need to continue our 219 * quest. 220 */ 221 if (isalpha(*pkgs_split) || ((MatchType == MATCH_GLOB) && \ 222 strpbrk(pkgs_split, "*?[]") != NULL)) { 223 *argv = pkgs_split; 224 break; 225 } 226 } 227 *pkgs++ = *argv++; 228 } 229 230 /* If no packages, yelp */ 231 if (pkgs == start && MatchType != MATCH_ALL && !CheckPkg && 232 TAILQ_EMPTY(whead) && LookUpOrigin == NULL) 233 warnx("missing package name(s)"), usage(); 234 *pkgs = NULL; 235 return pkg_perform(start); 236} 237 238static void 239usage() 240{ 241 fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n", 242 "usage: pkg_info [-cdDfGiIkLmopqrRsvVx] [-e package] [-l prefix]", 243 " [-t template] [pkg-name ...]", 244 " pkg_info [-q] -W filename", 245 " pkg_info [-q] -O origin", 246 " pkg_info -a [flags]"); 247 exit(1); 248} 249