1 /* $NetBSD: main.c,v 1.1.1.6 2009/08/06 16:55:25 joerg Exp $ */ 2 3 #if HAVE_CONFIG_H 4 #include "config.h" 5 #endif 6 #include <nbcompat.h> 7 #if HAVE_SYS_CDEFS_H 8 #include <sys/cdefs.h> 9 #endif 10 __RCSID("$NetBSD: main.c,v 1.1.1.6 2009/08/06 16:55:25 joerg Exp $"); 11 12 /* 13 * 14 * FreeBSD install - a package for the installation and maintainance 15 * of non-core utilities. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions 19 * are met: 20 * 1. Redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer. 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution. 25 * 26 * Jordan K. Hubbard 27 * 18 July 1993 28 * 29 * This is the add module. 30 * 31 */ 32 33 #if HAVE_SYS_IOCTL_H 34 #include <sys/ioctl.h> 35 #endif 36 37 #if HAVE_TERMIOS_H 38 #include <termios.h> 39 #endif 40 #if HAVE_ERR_H 41 #include <err.h> 42 #endif 43 44 #include "lib.h" 45 #include "info.h" 46 47 static const char Options[] = ".aBbcDde:E:fFhIiK:kLl:mNnpQ:qrRsSuvVX"; 48 49 int Flags = 0; 50 enum which Which = WHICH_LIST; 51 Boolean File2Pkg = FALSE; 52 Boolean Quiet = FALSE; 53 const char *InfoPrefix = ""; 54 const char *BuildInfoVariable = ""; 55 size_t termwidth = 0; 56 lpkg_head_t pkgs; 57 58 static void 59 usage(void) 60 { 61 fprintf(stderr, "%s\n%s\n%s\n%s\n", 62 "usage: pkg_info [-BbcDdFfhIikLmNnpqrRSsVvX] [-e package] [-E package]", 63 " [-K pkg_dbdir] [-l prefix] pkg-name ...", 64 " pkg_info [-a | -u] [flags]", 65 " pkg_info [-Q variable] pkg-name ..."); 66 exit(1); 67 } 68 69 int 70 main(int argc, char **argv) 71 { 72 char *CheckPkg = NULL; 73 char *BestCheckPkg = NULL; 74 lpkg_t *lpp; 75 int ch; 76 int rc; 77 78 setprogname(argv[0]); 79 while ((ch = getopt(argc, argv, Options)) != -1) 80 switch (ch) { 81 case '.': /* for backward compatibility */ 82 break; 83 84 case 'a': 85 Which = WHICH_ALL; 86 break; 87 88 case 'B': 89 Flags |= SHOW_BUILD_INFO; 90 break; 91 92 case 'b': 93 Flags |= SHOW_BUILD_VERSION; 94 break; 95 96 case 'c': 97 Flags |= SHOW_COMMENT; 98 break; 99 100 case 'D': 101 Flags |= SHOW_DISPLAY; 102 break; 103 104 case 'd': 105 Flags |= SHOW_DESC; 106 break; 107 108 case 'E': 109 BestCheckPkg = optarg; 110 break; 111 112 case 'e': 113 CheckPkg = optarg; 114 break; 115 116 case 'f': 117 Flags |= SHOW_PLIST; 118 break; 119 120 case 'F': 121 File2Pkg = 1; 122 break; 123 124 case 'I': 125 Flags |= SHOW_INDEX; 126 break; 127 128 case 'i': 129 Flags |= SHOW_INSTALL; 130 break; 131 132 case 'K': 133 _pkgdb_setPKGDB_DIR(optarg); 134 break; 135 136 case 'k': 137 Flags |= SHOW_DEINSTALL; 138 break; 139 140 case 'L': 141 Flags |= SHOW_FILES; 142 break; 143 144 case 'l': 145 InfoPrefix = optarg; 146 break; 147 148 case 'm': 149 Flags |= SHOW_MTREE; 150 break; 151 152 case 'N': 153 Flags |= SHOW_BLD_DEPENDS; 154 break; 155 156 case 'n': 157 Flags |= SHOW_DEPENDS; 158 break; 159 160 case 'p': 161 Flags |= SHOW_PREFIX; 162 break; 163 164 case 'Q': 165 Flags |= SHOW_BI_VAR; 166 BuildInfoVariable = optarg; 167 break; 168 169 case 'q': 170 Quiet = TRUE; 171 break; 172 173 case 'r': 174 Flags |= SHOW_FULL_REQBY; 175 break; 176 177 case 'R': 178 Flags |= SHOW_REQBY; 179 break; 180 181 case 's': 182 Flags |= SHOW_PKG_SIZE; 183 break; 184 185 case 'S': 186 Flags |= SHOW_ALL_SIZE; 187 break; 188 189 case 'u': 190 Which = WHICH_USER; 191 break; 192 193 case 'v': 194 Verbose = TRUE; 195 /* Reasonable definition of 'everything' */ 196 Flags = SHOW_COMMENT | SHOW_DESC | SHOW_PLIST | SHOW_INSTALL | 197 SHOW_DEINSTALL | SHOW_DISPLAY | SHOW_MTREE | 198 SHOW_REQBY | SHOW_BLD_DEPENDS | SHOW_DEPENDS | SHOW_PKG_SIZE | SHOW_ALL_SIZE; 199 break; 200 201 case 'V': 202 show_version(); 203 /* NOTREACHED */ 204 205 case 'X': 206 Flags |= SHOW_SUMMARY; 207 break; 208 209 case 'h': 210 case '?': 211 default: 212 usage(); 213 /* NOTREACHED */ 214 } 215 216 argc -= optind; 217 argv += optind; 218 219 if (argc == 0 && !Flags && !CheckPkg) { 220 /* No argument or relevant flags specified - assume -I */ 221 Flags = SHOW_INDEX; 222 /* assume -a if neither -u nor -a is given */ 223 if (Which == WHICH_LIST) 224 Which = WHICH_ALL; 225 } 226 227 if (CheckPkg != NULL && BestCheckPkg != NULL) { 228 warnx("-E and -e are mutally exlusive"); 229 usage(); 230 } 231 232 if (argc != 0 && CheckPkg != NULL) { 233 warnx("can't give any additional arguments to -e"); 234 usage(); 235 } 236 237 if (argc != 0 && BestCheckPkg != NULL) { 238 warnx("can't give any additional arguments to -E"); 239 usage(); 240 } 241 242 if (argc != 0 && Which != WHICH_LIST) { 243 warnx("can't use both -a/-u and package name"); 244 usage(); 245 } 246 247 /* Set some reasonable defaults */ 248 if (!Flags) 249 Flags = SHOW_COMMENT | SHOW_DESC | SHOW_REQBY 250 | SHOW_DEPENDS | SHOW_DISPLAY; 251 252 /* -Fe /filename -> change CheckPkg to real packagename */ 253 if (CheckPkg) { 254 if (File2Pkg) { 255 char *s; 256 257 if (!pkgdb_open(ReadOnly)) 258 err(EXIT_FAILURE, "cannot open pkgdb"); 259 260 s = pkgdb_retrieve(CheckPkg); 261 262 if (s == NULL) 263 errx(EXIT_FAILURE, "No matching pkg for %s.", CheckPkg); 264 CheckPkg = xstrdup(s); 265 266 pkgdb_close(); 267 } 268 return CheckForPkg(CheckPkg); 269 } 270 271 if (BestCheckPkg) 272 return CheckForBestPkg(BestCheckPkg); 273 274 TAILQ_INIT(&pkgs); 275 276 /* Get all the remaining package names, if any */ 277 if (File2Pkg && Which == WHICH_LIST) 278 if (!pkgdb_open(ReadOnly)) { 279 err(EXIT_FAILURE, "cannot open pkgdb"); 280 } 281 while (*argv) { 282 /* pkgdb: if -F flag given, don't add pkgnames to the "pkgs" 283 * queue but rather resolve the given filenames to pkgnames 284 * using pkgdb_retrieve, then add them. */ 285 if (File2Pkg) { 286 char *s; 287 288 s = pkgdb_retrieve(*argv); 289 290 if (s) { 291 lpp = alloc_lpkg(s); 292 TAILQ_INSERT_TAIL(&pkgs, lpp, lp_link); 293 } else 294 errx(EXIT_FAILURE, "No matching pkg for %s.", *argv); 295 } else { 296 if (ispkgpattern(*argv)) { 297 switch (add_installed_pkgs_by_pattern(*argv, &pkgs)) { 298 case 0: 299 errx(EXIT_FAILURE, "No matching pkg for %s.", *argv); 300 case -1: 301 errx(EXIT_FAILURE, "Error during search in pkgdb for %s", *argv); 302 } 303 } else { 304 const char *dbdir; 305 306 dbdir = _pkgdb_getPKGDB_DIR(); 307 if (**argv == '/' && strncmp(*argv, dbdir, strlen(dbdir)) == 0) { 308 *argv += strlen(dbdir) + 1; 309 if ((*argv)[strlen(*argv) - 1] == '/') { 310 (*argv)[strlen(*argv) - 1] = 0; 311 } 312 } 313 lpp = alloc_lpkg(*argv); 314 TAILQ_INSERT_TAIL(&pkgs, lpp, lp_link); 315 } 316 } 317 argv++; 318 } 319 320 if (File2Pkg) 321 pkgdb_close(); 322 323 /* If no packages, yelp */ 324 if (TAILQ_FIRST(&pkgs) == NULL && Which == WHICH_LIST && !CheckPkg) 325 warnx("missing package name(s)"), usage(); 326 327 if (isatty(STDOUT_FILENO)) { 328 const char *p; 329 struct winsize win; 330 331 if ((p = getenv("COLUMNS")) != NULL) 332 termwidth = atoi(p); 333 else if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 && 334 win.ws_col > 0) 335 termwidth = win.ws_col; 336 } 337 338 rc = pkg_perform(&pkgs); 339 exit(rc); 340 /* NOTREACHED */ 341 } 342