main.c revision 51638
1#ifndef lint 2static const char rcsid[] = 3 "$FreeBSD: head/usr.sbin/pkg_install/add/main.c 51638 1999-09-25 03:02:08Z billf $"; 4#endif 5 6/* 7 * 8 * FreeBSD install - a package for the installation and maintainance 9 * of non-core utilities. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * Jordan K. Hubbard 21 * 18 July 1993 22 * 23 * This is the add module. 24 * 25 */ 26 27#include <err.h> 28#include <sys/param.h> 29#include <sys/utsname.h> 30#include "lib.h" 31#include "add.h" 32 33static char Options[] = "hvIRfnrp:SMt:"; 34 35char *Prefix = NULL; 36Boolean NoInstall = FALSE; 37Boolean NoRecord = FALSE; 38Boolean Remote = FALSE; 39 40char *Mode = NULL; 41char *Owner = NULL; 42char *Group = NULL; 43char *PkgName = NULL; 44char *Directory = NULL; 45char FirstPen[FILENAME_MAX]; 46add_mode_t AddMode = NORMAL; 47 48#define MAX_PKGS 20 49char pkgnames[MAX_PKGS][MAXPATHLEN]; 50char *pkgs[MAX_PKGS]; 51 52static char *getpackagesite(void); 53int getosreldate(void); 54 55static void usage __P((void)); 56 57int 58main(int argc, char **argv) 59{ 60 int ch, err; 61 char **start; 62 char *cp; 63 64 char *remotepkg = NULL, *ptr; 65 static char packageroot[MAXPATHLEN] = "ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/"; 66 67 start = argv; 68 while ((ch = getopt(argc, argv, Options)) != -1) { 69 switch(ch) { 70 case 'v': 71 Verbose = TRUE; 72 break; 73 74 case 'p': 75 Prefix = optarg; 76 break; 77 78 case 'I': 79 NoInstall = TRUE; 80 break; 81 82 case 'R': 83 NoRecord = TRUE; 84 break; 85 86 case 'f': 87 Force = TRUE; 88 break; 89 90 case 'n': 91 Fake = TRUE; 92 Verbose = TRUE; 93 break; 94 95 case 'r': 96 Remote = TRUE; 97 break; 98 99 case 't': 100 strcpy(FirstPen, optarg); 101 break; 102 103 case 'S': 104 AddMode = SLAVE; 105 break; 106 107 case 'M': 108 AddMode = MASTER; 109 break; 110 111 case 'h': 112 case '?': 113 default: 114 usage(); 115 break; 116 } 117 } 118 argc -= optind; 119 argv += optind; 120 121 if (argc > MAX_PKGS) { 122 warnx("too many packages (max %d)", MAX_PKGS); 123 return(1); 124 } 125 126 if (AddMode != SLAVE) { 127 for (ch = 0; ch < MAX_PKGS; pkgs[ch++] = NULL) ; 128 129 /* Get all the remaining package names, if any */ 130 for (ch = 0; *argv; ch++, argv++) { 131 if (Remote) { 132 if (getenv("PACKAGESITE") == NULL) 133 strcat(packageroot, getpackagesite()); 134 else 135 strcpy(packageroot, (getenv("PACKAGESITE"))); 136 remotepkg = strcat(packageroot, *argv); 137 if (!((ptr = strrchr(remotepkg, '.')) && ptr[1] == 't' && 138 ptr[2] == 'g' && ptr[3] == 'z' && !ptr[4])) 139 strcat(remotepkg, ".tgz"); 140 } 141 if (!strcmp(*argv, "-")) /* stdin? */ 142 pkgs[ch] = "-"; 143 else if (isURL(*argv)) /* preserve URLs */ 144 pkgs[ch] = strcpy(pkgnames[ch], *argv); 145 else if ((Remote) && isURL(remotepkg)) 146 pkgs[ch] = strcpy(pkgnames[ch], remotepkg); 147 else { /* expand all pathnames to fullnames */ 148 if (fexists(*argv)) /* refers to a file directly */ 149 pkgs[ch] = realpath(*argv, pkgnames[ch]); 150 else { /* look for the file in the expected places */ 151 if (!(cp = fileFindByPath(NULL, *argv))) 152 warnx("can't find package '%s'", *argv); 153 else 154 pkgs[ch] = strcpy(pkgnames[ch], cp); 155 } 156 } 157 } 158 } 159 /* If no packages, yelp */ 160 else if (!ch) { 161 warnx("missing package name(s)"); 162 usage(); 163 } 164 else if (ch > 1 && AddMode == MASTER) { 165 warnx("only one package name may be specified with master mode"); 166 usage(); 167 } 168 /* Make sure the sub-execs we invoke get found */ 169 setenv("PATH", "/sbin:/usr/sbin:/bin:/usr/bin", 1); 170 171 /* Set a reasonable umask */ 172 umask(022); 173 174 if ((err = pkg_perform(pkgs)) != 0) { 175 if (Verbose) 176 warnx("%d package addition(s) failed", err); 177 return err; 178 } 179 else 180 return 0; 181} 182 183static char * 184getpackagesite(void) 185{ 186 int reldate; 187 static char sitepath[MAXPATHLEN]; 188 struct utsname u; 189 190 reldate = getosreldate(); 191 192 uname(&u); 193 strcpy(sitepath, u.machine); 194 195 if (reldate >= 400000) 196 strcat(sitepath, "/packages-current/Latest/"); 197 198 return sitepath; 199 200} 201 202static void 203usage() 204{ 205 fprintf(stderr, "%s\n%s\n", 206 "usage: pkg_add [-vInrfRMS] [-t template] [-p prefix]", 207 " pkg-name [pkg-name ...]"); 208 exit(1); 209} 210