main.c revision 53388
10SN/A#ifndef lint
2474SN/Astatic const char rcsid[] =
30SN/A  "$FreeBSD: head/usr.sbin/pkg_install/add/main.c 53388 1999-11-18 23:32:43Z cpiazza $";
40SN/A#endif
50SN/A
60SN/A/*
7157SN/A *
80SN/A * FreeBSD install - a package for the installation and maintainance
9157SN/A * of non-core utilities.
100SN/A *
110SN/A * Redistribution and use in source and binary forms, with or without
120SN/A * modification, are permitted provided that the following conditions
130SN/A * are met:
140SN/A * 1. Redistributions of source code must retain the above copyright
150SN/A *    notice, this list of conditions and the following disclaimer.
160SN/A * 2. Redistributions in binary form must reproduce the above copyright
170SN/A *    notice, this list of conditions and the following disclaimer in the
180SN/A *    documentation and/or other materials provided with the distribution.
190SN/A *
200SN/A * Jordan K. Hubbard
21157SN/A * 18 July 1993
22157SN/A *
23157SN/A * This is the add module.
240SN/A *
250SN/A */
260SN/A
270SN/A#include <err.h>
280SN/A#include <sys/param.h>
290SN/A#include <sys/utsname.h>
300SN/A#include "lib.h"
310SN/A#include "add.h"
320SN/A
330SN/Astatic char Options[] = "hvIRfnrp:SMt:";
340SN/A
350SN/Achar	*Prefix		= NULL;
360SN/ABoolean	NoInstall	= FALSE;
370SN/ABoolean	NoRecord	= FALSE;
380SN/ABoolean Remote		= FALSE;
390SN/A
400SN/Achar	*Mode		= NULL;
410SN/Achar	*Owner		= NULL;
420SN/Achar	*Group		= NULL;
430SN/Achar	*PkgName	= NULL;
440SN/Achar	*Directory	= NULL;
450SN/Achar	FirstPen[FILENAME_MAX];
460SN/Aadd_mode_t AddMode	= NORMAL;
470SN/A
480SN/A#define MAX_PKGS	20
490SN/Achar	pkgnames[MAX_PKGS][MAXPATHLEN];
500SN/Achar	*pkgs[MAX_PKGS];
510SN/A
520SN/Astatic char *getpackagesite(void);
530SN/Aint getosreldate(void);
540SN/A
550SN/Astatic void usage __P((void));
560SN/A
570SN/Aint
580SN/Amain(int argc, char **argv)
590SN/A{
600SN/A    int ch, err;
610SN/A    char **start;
620SN/A    char *cp;
630SN/A
640SN/A    char *remotepkg = NULL, *ptr;
650SN/A    static const char packageroot[MAXPATHLEN] = "ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/";
660SN/A    static char temppackageroot[MAXPATHLEN];
670SN/A
680SN/A    start = argv;
690SN/A    while ((ch = getopt(argc, argv, Options)) != -1) {
700SN/A	switch(ch) {
710SN/A	case 'v':
720SN/A	    Verbose = TRUE;
730SN/A	    break;
740SN/A
750SN/A	case 'p':
760SN/A	    Prefix = optarg;
770SN/A	    break;
780SN/A
790SN/A	case 'I':
800SN/A	    NoInstall = TRUE;
810SN/A	    break;
820SN/A
830SN/A	case 'R':
840SN/A	    NoRecord = TRUE;
850SN/A	    break;
860SN/A
870SN/A	case 'f':
880SN/A	    Force = TRUE;
890SN/A	    break;
900SN/A
910SN/A	case 'n':
920SN/A	    Fake = TRUE;
930SN/A	    Verbose = TRUE;
940SN/A	    break;
950SN/A
96442SN/A	case 'r':
97442SN/A	    Remote = TRUE;
98442SN/A	    break;
99442SN/A
100442SN/A	case 't':
101474SN/A	    strcpy(FirstPen, optarg);
102474SN/A	    break;
103474SN/A
104474SN/A	case 'S':
105474SN/A	    AddMode = SLAVE;
106474SN/A	    break;
107474SN/A
108474SN/A	case 'M':
109442SN/A	    AddMode = MASTER;
110442SN/A	    break;
111442SN/A
1120SN/A	case 'h':
1130SN/A	case '?':
1140SN/A	default:
1150SN/A	    usage();
1160SN/A	    break;
1170SN/A	}
1180SN/A    }
1190SN/A    argc -= optind;
1200SN/A    argv += optind;
1210SN/A
1220SN/A    if (argc > MAX_PKGS) {
1230SN/A	warnx("too many packages (max %d)", MAX_PKGS);
1240SN/A	return(1);
1250SN/A    }
1260SN/A
1270SN/A    if (AddMode != SLAVE) {
1280SN/A	for (ch = 0; ch < MAX_PKGS; pkgs[ch++] = NULL) ;
1290SN/A
1300SN/A	/* Get all the remaining package names, if any */
1310SN/A	for (ch = 0; *argv; ch++, argv++) {
1320SN/A    	    if (Remote) {
1330SN/A		strcpy(temppackageroot, packageroot);
1340SN/A		if (getenv("PACKAGESITE") == NULL)
1350SN/A		   strcat(temppackageroot, getpackagesite());
1360SN/A		else
1370SN/A	    	   strcpy(temppackageroot, (getenv("PACKAGESITE")));
1380SN/A		remotepkg = strcat(temppackageroot, *argv);
1390SN/A		if (!((ptr = strrchr(remotepkg, '.')) && ptr[1] == 't' &&
1400SN/A			ptr[2] == 'g' && ptr[3] == 'z' && !ptr[4]))
1410SN/A		   strcat(remotepkg, ".tgz");
1420SN/A    	    }
1430SN/A	    if (!strcmp(*argv, "-"))	/* stdin? */
1440SN/A		pkgs[ch] = "-";
1450SN/A	    else if (isURL(*argv))	/* preserve URLs */
1460SN/A		pkgs[ch] = strcpy(pkgnames[ch], *argv);
1470SN/A	    else if ((Remote) && isURL(remotepkg))
1480SN/A		pkgs[ch] = strcpy(pkgnames[ch], remotepkg);
1490SN/A	    else {			/* expand all pathnames to fullnames */
1500SN/A		if (fexists(*argv)) /* refers to a file directly */
1510SN/A		    pkgs[ch] = realpath(*argv, pkgnames[ch]);
1520SN/A		else {		/* look for the file in the expected places */
1530SN/A		    if (!(cp = fileFindByPath(NULL, *argv)))
1540SN/A			warnx("can't find package '%s'", *argv);
1550SN/A		    else
1560SN/A			pkgs[ch] = strcpy(pkgnames[ch], cp);
1570SN/A		}
1580SN/A	    }
1590SN/A	}
1600SN/A    }
1610SN/A    /* If no packages, yelp */
1620SN/A    else if (!ch) {
1630SN/A	warnx("missing package name(s)");
1640SN/A	usage();
1650SN/A    }
1660SN/A    else if (ch > 1 && AddMode == MASTER) {
1670SN/A	warnx("only one package name may be specified with master mode");
1680SN/A	usage();
1690SN/A    }
1700SN/A    /* Make sure the sub-execs we invoke get found */
1710SN/A    setenv("PATH", "/sbin:/usr/sbin:/bin:/usr/bin", 1);
1720SN/A
1730SN/A    /* Set a reasonable umask */
1740SN/A    umask(022);
1750SN/A
1760SN/A    if ((err = pkg_perform(pkgs)) != 0) {
1770SN/A	if (Verbose)
1780SN/A	    warnx("%d package addition(s) failed", err);
1790SN/A	return err;
1800SN/A    }
1810SN/A    else
1820SN/A	return 0;
1830SN/A}
1840SN/A
1850SN/Astatic char *
1860SN/Agetpackagesite(void)
1870SN/A{
1880SN/A    int reldate;
1890SN/A    static char sitepath[MAXPATHLEN];
1900SN/A    struct utsname u;
1910SN/A
1920SN/A    reldate = getosreldate();
1930SN/A
1940SN/A    uname(&u);
1950SN/A    strcpy(sitepath, u.machine);
1960SN/A
1970SN/A    if (reldate >= 400000)
1980SN/A	strcat(sitepath, "/packages-current/Latest/");
1990SN/A
2000SN/A    return sitepath;
2010SN/A
2020SN/A}
2030SN/A
2040SN/Astatic void
2050SN/Ausage()
2060SN/A{
2070SN/A    fprintf(stderr, "%s\n%s\n",
2080SN/A		"usage: pkg_add [-vInrfRMS] [-t template] [-p prefix]",
2090SN/A		"               pkg-name [pkg-name ...]");
2100SN/A    exit(1);
2110SN/A}
2120SN/A