252 lines
5.5 KiB
C
252 lines
5.5 KiB
C
#ifndef lint
|
|
static char sccsid[] = "@(#)opt_software.c 1.10 88/03/08 Copyr 1987 Sun Micro";
|
|
#endif
|
|
|
|
/*
|
|
* @(#)opt_software.c 1.1 88/06/08 4.0NFSSRC; from 1.10 88/03/08 D/NFS
|
|
* Copyright (c) 1987 by Sun Microsystems, Inc.
|
|
*/
|
|
|
|
/*
|
|
* Create the extractlist for given architecture
|
|
*
|
|
* Usage: opt_software arch tapedev tapehost
|
|
*/
|
|
|
|
#include "mktp.h"
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
extern int errno;
|
|
|
|
#undef ALWAYS_GET_REQUIRED
|
|
#define EXTFILE "/tmp/EXTRACTLIST."
|
|
#define STRSZ 256
|
|
char *Prog;
|
|
|
|
main(argc,argv)
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
char *arch, *tapedev, *tapehost;
|
|
char buf[STRSZ], ans[STRSZ];
|
|
char *swtype;
|
|
FILE *ip;
|
|
toc_entry *eptr;
|
|
Information *infoptr;
|
|
tapeaddress *tapeptr;
|
|
int nentries, foundone;
|
|
u_int software_size;
|
|
int status;
|
|
char *oneword();
|
|
|
|
Prog = argv[0];
|
|
if (argc != 3 && argc != 4)
|
|
usage();
|
|
|
|
arch = argv[1];
|
|
tapedev = argv[2];
|
|
if (argc == 3)
|
|
tapehost = NULL;
|
|
else {
|
|
tapehost = argv[3];
|
|
if (*tapehost == '\0')
|
|
tapehost = NULL;
|
|
if (tapehost && strncmp("/dev/", tapedev, 5)) {
|
|
fprintf(stderr, "\
|
|
%s: tapedev must start with \"/dev/\" if tapehost if given.\n", Prog);
|
|
usage();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Set up toc entry table
|
|
*/
|
|
printf("Reading the table of contents for %s architecture...\n", arch);
|
|
do {
|
|
tryagain:
|
|
if (!strncmp("/dev/", tapedev, 5)) {
|
|
for (;;) {
|
|
printf("\n\
|
|
Mount a %s release tape%s%s and hit ENTER, or type \"exit\" : ",
|
|
arch, tapehost? " on " : "",
|
|
tapehost? tapehost : "");
|
|
if (gets(ans) == NULL || !strcmp(ans, "exit")) {
|
|
printf("\n%s: terminating\n", Prog);
|
|
exit(1);
|
|
}
|
|
if (tapehost) {
|
|
sprintf(buf, "\
|
|
rsh %s -n \"mt -f %s rew && mt -f %s fsf 1\" 2>&1", tapehost, tapedev, tapedev);
|
|
ip = popen(buf, "r");
|
|
if (ip == 0)
|
|
fatal("run", buf);
|
|
status = 0;
|
|
while (fgets(ans, sizeof ans, ip)) {
|
|
fputs(ans, stdout);
|
|
status++;
|
|
}
|
|
pclose(ip);
|
|
} else {
|
|
sprintf(buf, "\
|
|
mt -t %s rew && mt -t %s fsf 1", tapedev, tapedev);
|
|
status = system(buf);
|
|
}
|
|
if (status == 0)
|
|
break;
|
|
printf("\
|
|
Unable to position tape; command sent:\n %s\n", buf);
|
|
}
|
|
}
|
|
if (tapehost) {
|
|
sprintf(buf, "rsh %s -n dd if=%s 2>/dev/null",
|
|
tapehost, tapedev);
|
|
ip = popen(buf, "r");
|
|
if (ip == NULL)
|
|
fatal("run", buf);
|
|
} else {
|
|
ip = fopen(tapedev, "r");
|
|
if (ip == NULL)
|
|
fatal("open", tapedev);
|
|
}
|
|
nentries = read_xdr_toc(ip,&dinfo,&vinfo,entries,NENTRIES);
|
|
if (tapehost)
|
|
pclose(ip);
|
|
else
|
|
fclose(ip);
|
|
} while (nentries == 0);
|
|
/*
|
|
* Start select software for the specified architecture
|
|
*/
|
|
sprintf(buf, "%s%s", EXTFILE, arch);
|
|
unlink(buf);
|
|
ip = fopen(buf, "w");
|
|
if (ip == NULL)
|
|
fatal("create", buf);
|
|
fprintf(ip, "IDENT %s %s\n", oneword(dinfo.Title), dinfo.Version);
|
|
foundone = 0;
|
|
for (eptr = entries; --nentries >= 0; eptr++) {
|
|
infoptr = &eptr->Info;
|
|
tapeptr = &eptr->Where.Address_u.tape;
|
|
/*
|
|
* Skip over files which are not installable or are
|
|
* of the wrong architecture.
|
|
*/
|
|
if (infoptr->kind != INSTALLABLE
|
|
|| !cmp_strlist(&infoptr->Information_u.Install.arch_for,
|
|
arch)) {
|
|
continue;
|
|
}
|
|
/*
|
|
* If this is the root entry, just write it out to
|
|
* the extractlist.
|
|
*/
|
|
if (!strcmp(eptr->Name, "root")) {
|
|
fprintf(ip,
|
|
"ENTRY root %d %d / required not_movable %d\n",
|
|
tapeptr->volno,
|
|
tapeptr->file_number,
|
|
tapeptr->size);
|
|
continue;
|
|
}
|
|
if (foundone++ == 0) {
|
|
printf("\n\
|
|
Select optional software for the %s architecture:\n", arch);
|
|
}
|
|
software_size = infoptr->Information_u.Install.size;
|
|
if (infoptr->Information_u.Install.required)
|
|
swtype = "required";
|
|
else if (infoptr->Information_u.Install.desirable)
|
|
swtype = "desirable";
|
|
else if (infoptr->Information_u.Install.common)
|
|
swtype = "common";
|
|
else
|
|
swtype = "optional";
|
|
for (;;) {
|
|
printf("Install \"%s\" [%d bytes; %s] ? [y/n]: ",
|
|
eptr->LongName, software_size, swtype);
|
|
#ifdef ALWAYS_GET_REQUIRED
|
|
if (infoptr->Information_u.Install.required) {
|
|
printf("y\n");
|
|
strcpy(ans, "y\n");
|
|
break;
|
|
}
|
|
#endif ALWAYS_GET_REQUIRED
|
|
gets(ans);
|
|
if (*ans == 'y' || *ans == 'n')
|
|
break;
|
|
printf(" Please answer \"yes\" or \"no\"\n");
|
|
}
|
|
if (*ans == 'y') {
|
|
fprintf(ip, "ENTRY %s %d %d %s %s %s %d\n",
|
|
eptr->Name,
|
|
tapeptr->volno,
|
|
tapeptr->file_number,
|
|
infoptr->Information_u.Install.loadpoint,
|
|
swtype,
|
|
infoptr->Information_u.Install.moveable == TRUE?
|
|
"movable" : "not_movable",
|
|
tapeptr->size);
|
|
}
|
|
}
|
|
fclose(ip);
|
|
if (!foundone) {
|
|
printf("\nRelease tape is not for %s architecture.\n", arch);
|
|
if (strncmp("/dev/", tapedev, 5))
|
|
exit(1);
|
|
goto tryagain;
|
|
}
|
|
exit(0);
|
|
}
|
|
|
|
char *
|
|
oneword(s)
|
|
char *s;
|
|
{
|
|
char *p;
|
|
|
|
p = s;
|
|
while ((p = strpbrk(p, " \t")) != NULL)
|
|
*p++ = '_';
|
|
return s;
|
|
}
|
|
|
|
/*
|
|
* search the string_list looking for a match of s. Returns
|
|
* 1 if match, 0 if no match.
|
|
*/
|
|
cmp_strlist(list, s)
|
|
string_list *list;
|
|
char *s;
|
|
{
|
|
int cnt;
|
|
char **p;
|
|
|
|
if (list == NULL)
|
|
return 0;
|
|
|
|
cnt = list->string_list_len;
|
|
for (p = list->string_list_val; --cnt >= 0; p++) {
|
|
if (!strcmp(*p, s))
|
|
return 1; /* found a match */
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
usage()
|
|
{
|
|
fprintf(stderr, "Usage: %s arch tapedev [tapehost]\n", Prog);
|
|
exit(1);
|
|
}
|
|
|
|
fatal(verb, object)
|
|
char *verb, *object;
|
|
{
|
|
int error;
|
|
|
|
error = errno;
|
|
fprintf(stderr, "%s: Cannot %s ", Prog, verb);
|
|
errno = error;
|
|
perror(object);
|
|
exit(1);
|
|
}
|