main.c revision 42786
1#ifndef lint
2static const char rcsid[] =
3	"$Id: main.c,v 1.19 1999/01/17 01:22:54 billf 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 <objformat.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(char *);
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 binformat[1024];
66    static char packageroot[MAXPATHLEN] = "ftp://ftp.FreeBSD.org/pub/FreeBSD/";
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		if (getenv("PACKAGESITE") == NULL) {
134		   getobjformat(binformat, sizeof(binformat), &argc, argv);
135		   strcat(packageroot, getpackagesite(binformat));
136		}
137		else
138	    	   strcpy(packageroot, (getenv("PACKAGESITE")));
139		remotepkg = strcat(packageroot, *argv);
140		if (!((ptr = strrchr(remotepkg, '.')) && ptr[1] == 't' &&
141			ptr[2] == 'g' && ptr[3] == 'z' && !ptr[4]))
142		   strcat(remotepkg, ".tgz");
143    	    }
144	    if (!strcmp(*argv, "-"))	/* stdin? */
145		pkgs[ch] = "-";
146	    else if (isURL(*argv))	/* preserve URLs */
147		pkgs[ch] = strcpy(pkgnames[ch], *argv);
148	    else if ((Remote) && isURL(remotepkg))
149		pkgs[ch] = strcpy(pkgnames[ch], remotepkg);
150	    else {			/* expand all pathnames to fullnames */
151		if (fexists(*argv)) /* refers to a file directly */
152		    pkgs[ch] = realpath(*argv, pkgnames[ch]);
153		else {		/* look for the file in the expected places */
154		    if (!(cp = fileFindByPath(NULL, *argv)))
155			warnx("can't find package '%s'", *argv);
156		    else
157			pkgs[ch] = strcpy(pkgnames[ch], cp);
158		}
159	    }
160	}
161    }
162    /* If no packages, yelp */
163    else if (!ch) {
164	warnx("missing package name(s)");
165	usage();
166    }
167    else if (ch > 1 && AddMode == MASTER) {
168	warnx("only one package name may be specified with master mode");
169	usage();
170    }
171    /* Make sure the sub-execs we invoke get found */
172    setenv("PATH", "/sbin:/usr/sbin:/bin:/usr/bin", 1);
173
174    /* Set a reasonable umask */
175    umask(022);
176
177    if ((err = pkg_perform(pkgs)) != 0) {
178	if (Verbose)
179	    warnx("%d package addition(s) failed", err);
180	return err;
181    }
182    else
183	return 0;
184}
185
186static char *
187getpackagesite(char binform[1024])
188{
189    int reldate;
190
191    reldate = getosreldate();
192
193    if (reldate == 300005)
194  	return "packages-3.0/Latest/";
195    else if (30004 > reldate && reldate >= 300000)
196	return "packages-current-aout/Latest/" ;
197    else if (30004 < reldate)
198	return !strcmp(binform, "elf") ? "packages-current/Latest/" :
199		"packages-current-aout/Latest";
200
201    return(0);
202
203}
204
205static void
206usage()
207{
208    fprintf(stderr, "%s\n%s\n",
209		"usage: pkg_add [-vInrfRMS] [-t template] [-p prefix]",
210		"               pkg-name [pkg-name ...]");
211    exit(1);
212}
213