main.c revision 76391
1#ifndef lint
2static const char rcsid[] =
3  "$FreeBSD: head/usr.sbin/pkg_install/add/main.c 76391 2001-05-09 01:37:49Z obrien $";
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 temppackageroot[MAXPATHLEN];
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		strcpy(temppackageroot, getpackagesite());
133		remotepkg = strcat(temppackageroot, *argv);
134		if (!((ptr = strrchr(remotepkg, '.')) && ptr[1] == 't' &&
135			ptr[2] == 'g' && ptr[3] == 'z' && !ptr[4]))
136		   strcat(remotepkg, ".tgz");
137    	    }
138	    if (!strcmp(*argv, "-"))	/* stdin? */
139		pkgs[ch] = "-";
140	    else if (isURL(*argv))	/* preserve URLs */
141		pkgs[ch] = strcpy(pkgnames[ch], *argv);
142	    else if ((Remote) && isURL(remotepkg))
143		pkgs[ch] = strcpy(pkgnames[ch], remotepkg);
144	    else {			/* expand all pathnames to fullnames */
145		if (fexists(*argv)) /* refers to a file directly */
146		    pkgs[ch] = realpath(*argv, pkgnames[ch]);
147		else {		/* look for the file in the expected places */
148		    if (!(cp = fileFindByPath(NULL, *argv)))
149			warnx("can't find package '%s'", *argv);
150		    else
151			pkgs[ch] = strcpy(pkgnames[ch], cp);
152		}
153	    }
154	}
155    }
156    /* If no packages, yelp */
157    else if (!ch) {
158	warnx("missing package name(s)");
159	usage();
160    }
161    else if (ch > 1 && AddMode == MASTER) {
162	warnx("only one package name may be specified with master mode");
163	usage();
164    }
165    /* Make sure the sub-execs we invoke get found */
166    setenv("PATH",
167	   "/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin",
168	   1);
169
170    /* Set a reasonable umask */
171    umask(022);
172
173    if ((err = pkg_perform(pkgs)) != 0) {
174	if (Verbose)
175	    warnx("%d package addition(s) failed", err);
176	return err;
177    }
178    else
179	return 0;
180}
181
182static char *
183getpackagesite(void)
184{
185    int reldate;
186    static char sitepath[MAXPATHLEN];
187    struct utsname u;
188
189    if (getenv("PACKAGESITE")) {
190	strcpy(sitepath, getenv("PACKAGESITE"));
191	return sitepath;
192    }
193
194    if (getenv("PACKAGEROOT"))
195	strcpy(sitepath, getenv("PACKAGEROOT"));
196    else
197	strcpy(sitepath, "ftp://ftp.FreeBSD.org");
198
199    strcat(sitepath, "/pub/FreeBSD/ports/");
200
201    uname(&u);
202    strcat(sitepath, u.machine);
203
204    reldate = getosreldate();
205    if (reldate == 410000)
206	strcat(sitepath, "/packages-4.1-release");
207    else if (reldate == 420000)
208	strcat(sitepath, "/packages-4.2-release");
209    else if (reldate == 430000)
210	strcat(sitepath, "/packages-4.3-release");
211    else if (reldate == 440000)
212	strcat(sitepath, "/packages-4.4-release");
213    else if (reldate == 450000)
214	strcat(sitepath, "/packages-4.5-release");
215    else if (300000 <= reldate && reldate <= 399000)
216	strcat(sitepath, "/packages-3-stable");
217    else if (400000 <= reldate && reldate <= 499000)
218	strcat(sitepath, "/packages-4-stable");
219    else if (510000 <= reldate && reldate <= 599000)	/* get real values!! */
220	strcat(sitepath, "/packages-5-stable");
221    else
222	strcat(sitepath, "/packages-current");
223
224    strcat(sitepath, "/Latest/");
225
226    return sitepath;
227
228}
229
230static void
231usage()
232{
233    fprintf(stderr, "%s\n%s\n",
234		"usage: pkg_add [-vInrfRMS] [-t template] [-p prefix]",
235		"               pkg-name [pkg-name ...]");
236    exit(1);
237}
238