/* $NetBSD: main.c,v 1.23 2001/09/25 10:28:16 agc Exp $ */ #include #ifndef lint #if 0 static char *rcsid = "from FreeBSD Id: main.c,v 1.16 1997/10/08 07:45:43 charnier Exp"; #else __RCSID("$NetBSD: main.c,v 1.23 2001/09/25 10:28:16 agc Exp $"); #endif #endif /* * * FreeBSD install - a package for the installation and maintainance * of non-core utilities. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Jordan K. Hubbard * 18 July 1993 * * This is the add module. * */ #include #include #include "lib.h" #include "add.h" #include "verify.h" static char Options[] = "hVvIRfnp:SMs:t:u"; char *Prefix = NULL; Boolean NoInstall = FALSE; Boolean NoRecord = FALSE; char *Mode = NULL; char *Owner = NULL; char *Group = NULL; char *PkgName = NULL; char *Directory = NULL; char FirstPen[FILENAME_MAX]; add_mode_t AddMode = NORMAL; int upgrade = 0; static void usage(void) { (void) fprintf(stderr, "%s\n%s\n", "usage: pkg_add [-hVvInfRMSu] [-t template] [-p prefix]", " [-s verification-type] pkg-name [pkg-name ...]"); exit(1); } int main(int argc, char **argv) { int ch, error=0; lpkg_head_t pkgs; lpkg_t *lpp; char *cp; char pkgname[MAXPATHLEN]; while ((ch = getopt(argc, argv, Options)) != -1) { switch (ch) { case 'v': Verbose = TRUE; break; case 'p': Prefix = optarg; break; case 'I': NoInstall = TRUE; break; case 'R': NoRecord = TRUE; break; case 'f': Force = TRUE; break; case 'n': Fake = TRUE; Verbose = TRUE; break; case 's': set_verification(optarg); break; case 't': strcpy(FirstPen, optarg); break; case 'S': AddMode = SLAVE; break; case 'M': AddMode = MASTER; break; case 'V': show_version(); /* NOTREACHED */ case 'u': upgrade = 1; break; case 'h': case '?': default: usage(); break; } } argc -= optind; argv += optind; TAILQ_INIT(&pkgs); if (AddMode != SLAVE) { /* Get all the remaining package names, if any */ for (ch = 0; *argv; ch++, argv++) { if (!strcmp(*argv, "-")) /* stdin? */ lpp = alloc_lpkg("-"); else if (IS_URL(*argv)) /* preserve URLs */ lpp = alloc_lpkg(*argv); else { /* expand all pathnames to fullnames */ char *s; if (fexists(*argv)) { /* refers to a file directly */ if (!(cp = realpath(*argv, pkgname))) { lpp = NULL; warn("realpath failed for '%s'", *argv); } else lpp = alloc_lpkg(cp); } else if (ispkgpattern(*argv)) { if ((s = findbestmatchingname(dirname_of(*argv), basename_of(*argv))) != NULL) { char tmp[FILENAME_MAX]; snprintf(tmp, sizeof(tmp), "%s/%s", dirname_of(*argv), s); if (Verbose) printf("Using %s for %s\n", tmp, *argv); if (!(cp = realpath(tmp, pkgname))) { lpp = NULL; warn("realpath failed for '%s'", tmp); error++; } else lpp = alloc_lpkg(cp); } else { lpp = NULL; warnx("can't find package pattern '%s'", *argv); error++; } } else { /* Maybe just a pkg name w/o pattern was given */ char tmp[FILENAME_MAX]; if (*argv[0] == '/'){ /* given arg has path - ignore PKG_PATH */ snprintf(tmp, sizeof(tmp), "%s-[0-9]*.t[bg]z", *argv); s = findbestmatchingname(dirname_of(tmp), basename_of(tmp)); } else { /* try all elements of PKG_PATH, see also loop * in file.c::fileFindByPath() */ /* This code prefers local pkgs over remote * pkgs - feature? */ char *e; if (getenv("PKG_PATH")) e = strdup(getenv("PKG_PATH")); else e = NULL; s = NULL; while(s==NULL && e && *e) { char *e2 = strsep(&e, ";"); if (IS_URL(e2)) { /* Let some other code do this */ ; } else { snprintf(tmp, sizeof(tmp), "%s/%s-[0-9]*.t[bg]z", e2, *argv); s = findbestmatchingname(dirname_of(tmp), basename_of(tmp)); } } } if (s) { char tmp2[FILENAME_MAX]; snprintf(tmp2, sizeof(tmp2), "%s/%s", dirname_of(tmp), s); if (Verbose) printf("Using %s for %s\n", tmp2, *argv); if (!(cp = realpath(tmp2, pkgname))) { lpp = NULL; warn("realpath failed for '%s'", tmp2); error++; } else lpp = alloc_lpkg(cp); } else { /* No go there... */ /* look for the file(pattern) in the expected places */ if (!(cp = fileFindByPath(NULL, *argv))) { lpp = NULL; warnx("can't find package '%s'", *argv); error++; } else lpp = alloc_lpkg(cp); } } } if (lpp) TAILQ_INSERT_TAIL(&pkgs, lpp, lp_link); } } /* If no packages, yelp */ else if (!ch) warnx("missing package name(s)"), usage(); else if (ch > 1 && AddMode == MASTER) warnx("only one package name may be specified with master mode"), usage(); error += pkg_perform(&pkgs); if (error != 0) { if (Verbose) warnx("%d package addition(s) failed", error); exit(1); } exit(0); }