main.c revision 48170
1#ifndef lint
2static const char rcsid[] =
3	"$Id: main.c,v 1.25 1999/06/23 16:54:29 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 <sys/utsname.h>
30#include <objformat.h>
31#include "lib.h"
32#include "add.h"
33
34static char Options[] = "hvIRfnrp: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