main.c revision 58010
1#ifndef lint 2static const char rcsid[] = 3 "$FreeBSD: head/usr.sbin/pkg_install/add/main.c 58010 2000-03-13 18:47:48Z 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 const char packageroot[MAXPATHLEN] = "ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/"; 66 static char temppackageroot[MAXPATHLEN]; 67 68 start = argv; 69 while ((ch = getopt(argc, argv, Options)) != -1) { 70 switch(ch) { 71 case 'v': 72 Verbose = TRUE; 73 break; 74 75 case 'p': 76 Prefix = optarg; 77 break; 78 79 case 'I': 80 NoInstall = TRUE; 81 break; 82 83 case 'R': 84 NoRecord = TRUE; 85 break; 86 87 case 'f': 88 Force = TRUE; 89 break; 90 91 case 'n': 92 Fake = TRUE; 93 Verbose = TRUE; 94 break; 95 96 case 'r': 97 Remote = TRUE; 98 break; 99 100 case 't': 101 strcpy(FirstPen, optarg); 102 break; 103 104 case 'S': 105 AddMode = SLAVE; 106 break; 107 108 case 'M': 109 AddMode = MASTER; 110 break; 111 112 case 'h': 113 case '?': 114 default: 115 usage(); 116 break; 117 } 118 } 119 argc -= optind; 120 argv += optind; 121 122 if (argc > MAX_PKGS) { 123 warnx("too many packages (max %d)", MAX_PKGS); 124 return(1); 125 } 126 127 if (AddMode != SLAVE) { 128 for (ch = 0; ch < MAX_PKGS; pkgs[ch++] = NULL) ; 129 130 /* Get all the remaining package names, if any */ 131 for (ch = 0; *argv; ch++, argv++) { 132 if (Remote) { 133 strcpy(temppackageroot, packageroot); 134 if (getenv("PACKAGESITE") == NULL) 135 strcat(temppackageroot, getpackagesite()); 136 else 137 strcpy(temppackageroot, (getenv("PACKAGESITE"))); 138 remotepkg = strcat(temppackageroot, *argv); 139 if (!((ptr = strrchr(remotepkg, '.')) && ptr[1] == 't' && 140 ptr[2] == 'g' && ptr[3] == 'z' && !ptr[4])) 141 strcat(remotepkg, ".tgz"); 142 } 143 if (!strcmp(*argv, "-")) /* stdin? */ 144 pkgs[ch] = "-"; 145 else if (isURL(*argv)) /* preserve URLs */ 146 pkgs[ch] = strcpy(pkgnames[ch], *argv); 147 else if ((Remote) && isURL(remotepkg)) 148 pkgs[ch] = strcpy(pkgnames[ch], remotepkg); 149 else { /* expand all pathnames to fullnames */ 150 if (fexists(*argv)) /* refers to a file directly */ 151 pkgs[ch] = realpath(*argv, pkgnames[ch]); 152 else { /* look for the file in the expected places */ 153 if (!(cp = fileFindByPath(NULL, *argv))) 154 warnx("can't find package '%s'", *argv); 155 else 156 pkgs[ch] = strcpy(pkgnames[ch], cp); 157 } 158 } 159 } 160 } 161 /* If no packages, yelp */ 162 else if (!ch) { 163 warnx("missing package name(s)"); 164 usage(); 165 } 166 else if (ch > 1 && AddMode == MASTER) { 167 warnx("only one package name may be specified with master mode"); 168 usage(); 169 } 170 /* Make sure the sub-execs we invoke get found */ 171 setenv("PATH", "/sbin:/usr/sbin:/bin:/usr/bin", 1); 172 173 /* Set a reasonable umask */ 174 umask(022); 175 176 if ((err = pkg_perform(pkgs)) != 0) { 177 if (Verbose) 178 warnx("%d package addition(s) failed", err); 179 return err; 180 } 181 else 182 return 0; 183} 184 185static char * 186getpackagesite(void) 187{ 188 int reldate; 189 static char sitepath[MAXPATHLEN]; 190 struct utsname u; 191 192 reldate = getosreldate(); 193 194 uname(&u); 195 strcpy(sitepath, u.machine); 196 197 if (reldate >= 500000) 198 strcat(sitepath, "/packages-current/Latest/"); 199 200 return sitepath; 201 202} 203 204static void 205usage() 206{ 207 fprintf(stderr, "%s\n%s\n", 208 "usage: pkg_add [-vInrfRMS] [-t template] [-p prefix]", 209 " pkg-name [pkg-name ...]"); 210 exit(1); 211} 212