main.c revision 48143
1#ifndef lint 2static const char rcsid[] = 3 "$Id: main.c,v 1.24 1999/06/14 21:58:59 obrien Exp $"; 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 <objformat.h> 31#include "lib.h" 32#include "add.h" 33 34static char Options[] = "hvIRfnr?p:SMt:"; 35 36char *Prefix = NULL; 37Boolean NoInstall = FALSE; 38Boolean NoRecord = FALSE; 39Boolean Remote = FALSE; 40 41char *Mode = NULL; 42char *Owner = NULL; 43char *Group = NULL; 44char *PkgName = NULL; 45char *Directory = NULL; 46char FirstPen[FILENAME_MAX]; 47add_mode_t AddMode = NORMAL; 48 49#define MAX_PKGS 20 50char pkgnames[MAX_PKGS][MAXPATHLEN]; 51char *pkgs[MAX_PKGS]; 52 53static char *getpackagesite(char *); 54int getosreldate(void); 55 56static void usage __P((void)); 57 58int 59main(int argc, char **argv) 60{ 61 int ch, err; 62 char **start; 63 char *cp; 64 65 char *remotepkg = NULL, *ptr; 66 static char binformat[1024]; 67 static char packageroot[MAXPATHLEN] = "ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/"; 68 69 start = argv; 70 while ((ch = getopt(argc, argv, Options)) != -1) { 71 switch(ch) { 72 case 'v': 73 Verbose = TRUE; 74 break; 75 76 case 'p': 77 Prefix = optarg; 78 break; 79 80 case 'I': 81 NoInstall = TRUE; 82 break; 83 84 case 'R': 85 NoRecord = TRUE; 86 break; 87 88 case 'f': 89 Force = TRUE; 90 break; 91 92 case 'n': 93 Fake = TRUE; 94 Verbose = TRUE; 95 break; 96 97 case 'r': 98 Remote = TRUE; 99 break; 100 101 case 't': 102 strcpy(FirstPen, optarg); 103 break; 104 105 case 'S': 106 AddMode = SLAVE; 107 break; 108 109 case 'M': 110 AddMode = MASTER; 111 break; 112 113 case 'h': 114 case '?': 115 default: 116 usage(); 117 break; 118 } 119 } 120 argc -= optind; 121 argv += optind; 122 123 if (argc > MAX_PKGS) { 124 warnx("too many packages (max %d)", MAX_PKGS); 125 return(1); 126 } 127 128 if (AddMode != SLAVE) { 129 for (ch = 0; ch < MAX_PKGS; pkgs[ch++] = NULL) ; 130 131 /* Get all the remaining package names, if any */ 132 for (ch = 0; *argv; ch++, argv++) { 133 if (Remote) { 134 if (getenv("PACKAGESITE") == NULL) { 135 getobjformat(binformat, sizeof(binformat), &argc, argv); 136 strcat(packageroot, getpackagesite(binformat)); 137 } 138 else 139 strcpy(packageroot, (getenv("PACKAGESITE"))); 140 remotepkg = strcat(packageroot, *argv); 141 if (!((ptr = strrchr(remotepkg, '.')) && ptr[1] == 't' && 142 ptr[2] == 'g' && ptr[3] == 'z' && !ptr[4])) 143 strcat(remotepkg, ".tgz"); 144 } 145 if (!strcmp(*argv, "-")) /* stdin? */ 146 pkgs[ch] = "-"; 147 else if (isURL(*argv)) /* preserve URLs */ 148 pkgs[ch] = strcpy(pkgnames[ch], *argv); 149 else if ((Remote) && isURL(remotepkg)) 150 pkgs[ch] = strcpy(pkgnames[ch], remotepkg); 151 else { /* expand all pathnames to fullnames */ 152 if (fexists(*argv)) /* refers to a file directly */ 153 pkgs[ch] = realpath(*argv, pkgnames[ch]); 154 else { /* look for the file in the expected places */ 155 if (!(cp = fileFindByPath(NULL, *argv))) 156 warnx("can't find package '%s'", *argv); 157 else 158 pkgs[ch] = strcpy(pkgnames[ch], cp); 159 } 160 } 161 } 162 } 163 /* If no packages, yelp */ 164 else if (!ch) { 165 warnx("missing package name(s)"); 166 usage(); 167 } 168 else if (ch > 1 && AddMode == MASTER) { 169 warnx("only one package name may be specified with master mode"); 170 usage(); 171 } 172 /* Make sure the sub-execs we invoke get found */ 173 setenv("PATH", "/sbin:/usr/sbin:/bin:/usr/bin", 1); 174 175 /* Set a reasonable umask */ 176 umask(022); 177 178 if ((err = pkg_perform(pkgs)) != 0) { 179 if (Verbose) 180 warnx("%d package addition(s) failed", err); 181 return err; 182 } 183 else 184 return 0; 185} 186 187static char * 188getpackagesite(char binform[1024]) 189{ 190 int reldate; 191 static char sitepath[MAXPATHLEN]; 192 struct utsname u; 193 194 reldate = getosreldate(); 195 196 uname(&u); 197 strcpy(sitepath, u.machine); 198 199 if (reldate == 300005) 200 strcat(sitepath, "/packages-3.0/"); 201 else if (300000 < reldate && reldate <= 300004) 202 strcat(sitepath, "/packages-3.0-aout/Latest/"); 203 else if (300004 < reldate && reldate < 400000) 204 strcat(sitepath, !strcmp(binform, "elf") ? "/packages-3-stable/Latest/" : 205 "/packages-3.0-aout/Latest/"); 206 else 207 strcat(sitepath, "/packages-current/Latest/"); 208 209 return sitepath; 210 211} 212 213static void 214usage() 215{ 216 fprintf(stderr, "%s\n%s\n", 217 "usage: pkg_add [-vInrfRMS] [-t template] [-p prefix]", 218 " pkg-name [pkg-name ...]"); 219 exit(1); 220} 221