diff options
author | cvs2svn <cvs2svn@FreeBSD.org> | 1996-01-01 11:01:15 +0000 |
---|---|---|
committer | cvs2svn <cvs2svn@FreeBSD.org> | 1996-01-01 11:01:15 +0000 |
commit | a3ab491d642b34f2d3efbc0562abc8e79b38ce09 (patch) | |
tree | 959df5086a97d16c04b83842650d6ee1f3de4522 | |
parent | 4e2d078f4fc7fe46c0e3b0f1256c92e971891c67 (diff) |
This commit was manufactured by cvs2svn to create tagupstream/2.1.0release/2.1.0
'RELENG_2_1_0_RELEASE'.
Notes
Notes:
svn path=/stable/2.1/; revision=13148
svn path=/release/2.1.0/; revision=13149; tag=release/2.1.0
66 files changed, 10169 insertions, 3471 deletions
diff --git a/gnu/usr.bin/cvs/contrib/clmerge b/gnu/usr.bin/cvs/contrib/clmerge new file mode 100644 index 000000000000..1a29311a9c14 --- /dev/null +++ b/gnu/usr.bin/cvs/contrib/clmerge @@ -0,0 +1,156 @@ +#!/usr/local/bin/perl + +# Merge conflicted ChangeLogs +# tromey Mon Aug 15 1994 + +# Due to popular demand, I'm posting my ChangeLog auto-merge tool. Run +# this on your ChangeLog files when an update leaves them conflicted. +# The code is appended. +# +# Usage is: +# +# cl-merge [-i] file ... +# +# With -i, it works in place (backups put in a ~ file). Otherwise the +# merged ChangeLog is printed to stdout. +# +# Style comments are welcome. This is my third perl program ever. +# +# Please report any bugs to me. I wrote this yesterday, so there are no +# guarantees about its performance. I recommend checking its output +# carefully. If you do send a bug report, please includie the failing +# ChangeLog, so I can include it in my test suite. +# +# Tom +# --- +# tromey@busco.lanl.gov Member, League for Programming Freedom +# Sadism and farce are always inexplicably linked. +# -- Alexander Theroux + +# If '-i' is given, do it in-place. +if ($ARGV[0] eq '-i') { + shift (@ARGV); + $^I = '~'; +} + +$lastkey = ''; +$lastval = ''; +$conf = 0; +%conflist = (); + +$tjd = 0; + +# Simple state machine. The states: +# +# 0 Not in conflict. Just copy input to output. +# 1 Beginning an entry. Next non-blank line is key. +# 2 In entry. Entry beginner transitions to state 1. +while (<>) { + if (/^<<<</ || /^====/) { + # Start of a conflict. + + # Copy last key into array. + if ($lastkey ne '') { + $conflist{$lastkey} = $lastval; + + $lastkey = ''; + $lastval = ''; + } + + $conf = 1; + } elsif (/^>>>>/) { + # End of conflict. Output. + + # Copy last key into array. + if ($lastkey ne '') { + $conflist{$lastkey} = $lastval; + + $lastkey = ''; + $lastval = ''; + } + + foreach (reverse sort clcmp keys %conflist) { + print STDERR "doing $_" if $tjd; + print $_; + print $conflist{$_}; + } + + $lastkey = ''; + $lastval = ''; + $conf = 0; + %conflist = (); + } elsif ($conf == 1) { + # Beginning an entry. Skip empty lines. Error if not a real + # beginner. + if (/^$/) { + # Empty line; just skip at this point. + } elsif (/^[MTWFS]/) { + # Looks like the name of a day; assume opener and move to + # "in entry" state. + $lastkey = $_; + $conf = 2; + print STDERR "found $_" if $tjd; + } else { + die ("conflict crosses entry boundaries: $_"); + } + } elsif ($conf == 2) { + # In entry. Copy into variable until we see beginner line. + if (/^[MTWFS]/) { + # Entry beginner line. + + # Copy last key into array. + if ($lastkey ne '') { + $conflist{$lastkey} = $lastval; + + $lastkey = ''; + $lastval = ''; + } + + $lastkey = $_; + print STDERR "found $_" if $tjd; + $lastval = ''; + } else { + $lastval .= $_; + } + } else { + # Just copy. + print; + } +} + +%months = ('Jan', 0, + 'Feb', 1, + 'Mar', 2, + 'Apr', 3, + 'May', 4, + 'Jun', 5, + 'Jul', 6, + 'Aug', 7, + 'Sep', 8, + 'Oct', 9, + 'Nov', 10, + 'Dec', 11); + +# Compare ChangeLog time strings like <=>. +# +# 0 1 2 3 +# Thu Aug 11 13:22:42 1994 Tom Tromey (tromey@creche.colorado.edu) +# 0123456789012345678901234567890 +# +sub clcmp { + # First check year. + $r = substr ($a, 20, 4) <=> substr ($b, 20, 4); + + # Now check month. + $r = $months{$a} <=> $months{$b} if !$r; + + # Now check day. + $r = substr ($a, 8, 2) <=> substr ($b, 8, 2) if !$r; + + # Now check time (3 parts). + $r = substr ($a, 11, 2) <=> substr ($b, 11, 2) if !$r; + $r = substr ($a, 14, 2) <=> substr ($b, 14, 2) if !$r; + $r = substr ($a, 17, 2) <=> substr ($b, 17, 2) if !$r; + + $r; +} diff --git a/gnu/usr.bin/cvs/contrib/cvscheck b/gnu/usr.bin/cvs/contrib/cvscheck new file mode 100644 index 000000000000..1c66688cbd34 --- /dev/null +++ b/gnu/usr.bin/cvs/contrib/cvscheck @@ -0,0 +1,84 @@ +#! /bin/sh +# $Id: cvscheck,v 1.2 1992/04/10 03:04:19 berliner Exp $ +# +# cvscheck - identify files added, changed, or removed +# in CVS working directory +# +# Contributed by Lowell Skoog <fluke!lowell@uunet.uu.net> +# +# This program should be run in a working directory that has been +# checked out using CVS. It identifies files that have been added, +# changed, or removed in the working directory, but not "cvs +# committed". It also determines whether the files have been "cvs +# added" or "cvs removed". For directories, it is only practical to +# determine whether they have been added. + +name=cvscheck +changes=0 + +# If we can't run CVS commands in this directory +cvs status . > /dev/null 2>&1 +if [ $? != 0 ] ; then + + # Bail out + echo "$name: there is no version here; bailing out" 1>&2 + exit 1 +fi + +# Identify files added to working directory +for file in .* * ; do + + # Skip '.' and '..' + if [ $file = '.' -o $file = '..' ] ; then + continue + fi + + # If a regular file + if [ -f $file ] ; then + if cvs status $file | grep -s '^From:[ ]*New file' ; then + echo "file added: $file - not CVS committed" + changes=`expr $changes + 1` + elif cvs status $file | grep -s '^From:[ ]*no entry for' ; then + echo "file added: $file - not CVS added, not CVS committed" + changes=`expr $changes + 1` + fi + + # Else if a directory + elif [ -d $file -a $file != CVS.adm ] ; then + + # Move into it + cd $file + + # If CVS commands don't work inside + cvs status . > /dev/null 2>&1 + if [ $? != 0 ] ; then + echo "directory added: $file - not CVS added" + changes=`expr $changes + 1` + fi + + # Move back up + cd .. + fi +done + +# Identify changed files +changedfiles=`cvs diff | egrep '^diff' | awk '{print $3}'` +for file in $changedfiles ; do + echo "file changed: $file - not CVS committed" + changes=`expr $changes + 1` +done + +# Identify files removed from working directory +removedfiles=`cvs status | egrep '^File:[ ]*no file' | awk '{print $4}'` + +# Determine whether each file has been cvs removed +for file in $removedfiles ; do + if cvs status $file | grep -s '^From:[ ]*-' ; then + echo "file removed: $file - not CVS committed" + else + echo "file removed: $file - not CVS removed, not CVS committed" + fi + changes=`expr $changes + 1` +done + +exit $changes diff --git a/gnu/usr.bin/cvs/contrib/descend b/gnu/usr.bin/cvs/contrib/descend new file mode 100644 index 000000000000..999c46f4f0a8 --- /dev/null +++ b/gnu/usr.bin/cvs/contrib/descend @@ -0,0 +1,116 @@ +#! /bin/sh +# $Id: descend,v 1.1 1992/04/03 05:22:52 berliner Exp $ +# +# descend - walk down a directory tree and execute a command at each node + +fullname=$0 +name=descend +usage="Usage: $name [-afqrv] command [directory ...]\n +\040\040-a\040\040All: descend into directories starting with '.'\n +\040\040-f\040\040Force: ignore errors during descent\n +\040\040-q\040\040Quiet: don't print directory names\n +\040\040-r\040\040Restricted: don't descend into RCS, CVS.adm, SCCS directories\n +\040\040-v\040\040Verbose: print command before executing it" + +# Scan for options +while getopts afqrv option; do + case $option in + a) + alldirs=$option + options=$options" "-$option + ;; + f) + force=$option + options=$options" "-$option + ;; + q) + verbose= + quiet=$option + options=$options" "-$option + ;; + r) + restricted=$option + options=$options" "-$option + ;; + v) + verbose=$option + quiet= + options=$options" "-$option + ;; + \?) + /usr/5bin/echo $usage 1>&2 + exit 1 + ;; + esac +done +shift `expr $OPTIND - 1` + +# Get command to execute +if [ $# -lt 1 ] ; then + /usr/5bin/echo $usage 1>&2 + exit 1 +else + command=$1 + shift +fi + +# If no directory specified, use '.' +if [ $# -lt 1 ] ; then + default_dir=. +fi + +# For each directory specified +for dir in $default_dir "$@" ; do + + # Spawn sub-shell so we return to starting directory afterward + (cd $dir + + # Execute specified command + if [ -z "$quiet" ] ; then + echo In directory `hostname`:`pwd` + fi + if [ -n "$verbose" ] ; then + echo $command + fi + eval "$command" || if [ -z "$force" ] ; then exit 1; fi + + # Collect dot file names if necessary + if [ -n "$alldirs" ] ; then + dotfiles=.* + else + dotfiles= + fi + + # For each file in current directory + for file in $dotfiles * ; do + + # Skip '.' and '..' + if [ "$file" = "." -o "$file" = ".." ] ; then + continue + fi + + # If a directory but not a symbolic link + if [ -d "$file" -a ! -h "$file" ] ; then + + # If not skipping this type of directory + if [ \( "$file" != "RCS" -a \ + "$file" != "SCCS" -a \ + "$file" != "CVS" -a \ + "$file" != "CVS.adm" \) \ + -o -z "$restricted" ] ; then + + # Recursively descend into it + $fullname $options "$command" "$file" \ + || if [ -z "$force" ] ; then exit 1; fi + fi + + # Else if a directory AND a symbolic link + elif [ -d "$file" -a -h "$file" ] ; then + + if [ -z "$quiet" ] ; then + echo In directory `hostname`:`pwd`/$file: symbolic link: skipping + fi + fi + done + ) || if [ -z "$force" ] ; then exit 1; fi +done diff --git a/gnu/usr.bin/cvs/contrib/dirfns b/gnu/usr.bin/cvs/contrib/dirfns new file mode 100644 index 000000000000..8324c4198e35 --- /dev/null +++ b/gnu/usr.bin/cvs/contrib/dirfns @@ -0,0 +1,481 @@ +echo 'directory.3': +sed 's/^X//' >'directory.3' <<'!' +X.TH DIRECTORY 3 imported +X.DA 9 Oct 1985 +X.SH NAME +Xopendir, readdir, telldir, seekdir, rewinddir, closedir \- high-level directory operations +X.SH SYNOPSIS +X.B #include <sys/types.h> +X.br +X.B #include <ndir.h> +X.PP +X.SM +X.B DIR +X.B *opendir(filename) +X.br +X.B char *filename; +X.PP +X.SM +X.B struct direct +X.B *readdir(dirp) +X.br +X.B DIR *dirp; +X.PP +X.SM +X.B long +X.B telldir(dirp) +X.br +X.B DIR *dirp; +X.PP +X.SM +X.B seekdir(dirp, loc) +X.br +X.B DIR *dirp; +X.br +X.B long loc; +X.PP +X.SM +X.B rewinddir(dirp) +X.br +X.B DIR *dirp; +X.PP +X.SM +X.B closedir(dirp) +X.br +X.B DIR *dirp; +X.SH DESCRIPTION +XThis library provides high-level primitives for directory scanning, +Xsimilar to those available for 4.2BSD's (very different) directory system. +X.\"The purpose of this library is to simulate +X.\"the new flexible length directory names of 4.2bsd UNIX +X.\"on top of the old directory structure of v7. +XIt incidentally provides easy portability to and from 4.2BSD (insofar +Xas such portability is not compromised by other 4.2/VAX dependencies). +X.\"It allows programs to be converted immediately +X.\"to the new directory access interface, +X.\"so that they need only be relinked +X.\"when moved to 4.2bsd. +X.\"It is obtained with the loader option +X.\".BR \-lndir . +X.PP +X.I Opendir +Xopens the directory named by +X.I filename +Xand associates a +X.I directory stream +Xwith it. +X.I Opendir +Xreturns a pointer to be used to identify the +X.I directory stream +Xin subsequent operations. +XThe pointer +X.SM +X.B NULL +Xis returned if +X.I filename +Xcannot be accessed or is not a directory. +X.PP +X.I Readdir +Xreturns a pointer to the next directory entry. +XIt returns +X.B NULL +Xupon reaching the end of the directory or detecting +Xan invalid +X.I seekdir +Xoperation. +X.PP +X.I Telldir +Xreturns the current location associated with the named +X.I directory stream. +X.PP +X.I Seekdir +Xsets the position of the next +X.I readdir +Xoperation on the +X.I directory stream. +XThe new position reverts to the one associated with the +X.I directory stream +Xwhen the +X.I telldir +Xoperation was performed. +XValues returned by +X.I telldir +Xare good only for the lifetime of the DIR pointer from +Xwhich they are derived. +XIf the directory is closed and then reopened, +Xthe +X.I telldir +Xvalue may be invalidated +Xdue to undetected directory compaction in 4.2BSD. +XIt is safe to use a previous +X.I telldir +Xvalue immediately after a call to +X.I opendir +Xand before any calls to +X.I readdir. +X.PP +X.I Rewinddir +Xresets the position of the named +X.I directory stream +Xto the beginning of the directory. +X.PP +X.I Closedir +Xcauses the named +X.I directory stream +Xto be closed, +Xand the structure associated with the DIR pointer to be freed. +X.PP +XA +X.I direct +Xstructure is as follows: +X.PP +X.RS +X.nf +Xstruct direct { +X /* unsigned */ long d_ino; /* inode number of entry */ +X unsigned short d_reclen; /* length of this record */ +X unsigned short d_namlen; /* length of string in d_name */ +X char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */ +X}; +X.fi +X.RE +X.PP +XThe +X.I d_reclen +Xfield is meaningless in non-4.2BSD systems and should be ignored. +XThe use of a +X.I long +Xfor +X.I d_ino +Xis also a 4.2BSDism; +X.I ino_t +X(see +X.IR types (5)) +Xshould be used elsewhere. +XThe macro +X.I DIRSIZ(dp) +Xgives the minimum memory size needed to hold the +X.I direct +Xvalue pointed to by +X.IR dp , +Xwith the minimum necessary allocation for +X.IR d_name . +X.PP +XThe preferred way to search the current directory for entry ``name'' is: +X.PP +X.RS +X.nf +X len = strlen(name); +X dirp = opendir("."); +X if (dirp == NULL) { +X fprintf(stderr, "%s: can't read directory .\\n", argv[0]); +X return NOT_FOUND; +X } +X while ((dp = readdir(dirp)) != NULL) +X if (dp->d_namlen == len && strcmp(dp->d_name, name) == 0) { +X closedir(dirp); +X return FOUND; +X } +X closedir(dirp); +X return NOT_FOUND; +X.RE +X.\".SH LINKING +X.\"This library is accessed by specifying ``-lndir'' as the +X.\"last argument to the compile line, e.g.: +X.\".PP +X.\" cc -I/usr/include/ndir -o prog prog.c -lndir +X.SH "SEE ALSO" +Xopen(2), +Xclose(2), +Xread(2), +Xlseek(2) +X.SH HISTORY +XWritten by +XKirk McKusick at Berkeley (ucbvax!mckusick). +XMiscellaneous bug fixes from elsewhere. +XThe size of the data structure has been decreased to avoid excessive +Xspace waste under V7 (where filenames are 14 characters at most). +XFor obscure historical reasons, the include file is also available +Xas +X.IR <ndir/sys/dir.h> . +XThe Berkeley version lived in a separate library (\fI\-lndir\fR), +Xwhereas ours is +Xpart of the C library, although the separate library is retained to +Xmaximize compatibility. +X.PP +XThis manual page has been substantially rewritten to be informative in +Xthe absence of a 4.2BSD manual. +X.SH BUGS +XThe +X.I DIRSIZ +Xmacro actually wastes a bit of space due to some padding requirements +Xthat are an artifact of 4.2BSD. +X.PP +XThe returned value of +X.I readdir +Xpoints to a static area that will be overwritten by subsequent calls. +X.PP +XThere are some unfortunate name conflicts with the \fIreal\fR V7 +Xdirectory structure definitions. +! +echo 'dir.h': +sed 's/^X//' >'dir.h' <<'!' +X/* dir.h 4.4 82/07/25 */ +X +X/* +X * A directory consists of some number of blocks of DIRBLKSIZ +X * bytes, where DIRBLKSIZ is chosen such that it can be transferred +X * to disk in a single atomic operation (e.g. 512 bytes on most machines). +X * +X * Each DIRBLKSIZ byte block contains some number of directory entry +X * structures, which are of variable length. Each directory entry has +X * a struct direct at the front of it, containing its inode number, +X * the length of the entry, and the length of the name contained in +X * the entry. These are followed by the name padded to a 4 byte boundary +X * with null bytes. All names are guaranteed null terminated. +X * The maximum length of a name in a directory is MAXNAMLEN. +X * +X * The macro DIRSIZ(dp) gives the amount of space required to represent +X * a directory entry. Free space in a directory is represented by +X * entries which have dp->d_reclen >= DIRSIZ(dp). All DIRBLKSIZ bytes +X * in a directory block are claimed by the directory entries. This +X * usually results in the last entry in a directory having a large +X * dp->d_reclen. When entries are deleted from a directory, the +X * space is returned to the previous entry in the same directory +X * block by increasing its dp->d_reclen. If the first entry of +X * a directory block is free, then its dp->d_ino is set to 0. +X * Entries other than the first in a directory do not normally have +X * dp->d_ino set to 0. +X */ +X#define DIRBLKSIZ 512 +X#ifdef VMUNIX +X#define MAXNAMLEN 255 +X#else +X#define MAXNAMLEN 14 +X#endif +X +Xstruct direct { +X /* unsigned */ long d_ino; /* inode number of entry */ +X unsigned short d_reclen; /* length of this record */ +X unsigned short d_namlen; /* length of string in d_name */ +X char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */ +X}; +X +X/* +X * The DIRSIZ macro gives the minimum record length which will hold +X * the directory entry. This requires the amount of space in struct direct +X * without the d_name field, plus enough space for the name with a terminating +X * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary. +X */ +X#undef DIRSIZ +X#define DIRSIZ(dp) \ +X ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3)) +X +X#ifndef KERNEL +X/* +X * Definitions for library routines operating on directories. +X */ +Xtypedef struct _dirdesc { +X int dd_fd; +X long dd_loc; +X long dd_size; +X char dd_buf[DIRBLKSIZ]; +X} DIR; +X#ifndef NULL +X#define NULL 0 +X#endif +Xextern DIR *opendir(); +Xextern struct direct *readdir(); +Xextern long telldir(); +X#ifdef void +Xextern void seekdir(); +Xextern void closedir(); +X#endif +X#define rewinddir(dirp) seekdir((dirp), (long)0) +X#endif KERNEL +! +echo 'makefile': +sed 's/^X//' >'makefile' <<'!' +XDIR = closedir.o opendir.o readdir.o seekdir.o telldir.o +XCFLAGS=-O -I. -Dvoid=int +XDEST=.. +X +Xall: $(DIR) +X +Xmv: $(DIR) +X mv $(DIR) $(DEST) +X +Xcpif: dir.h +X cp dir.h /usr/include/ndir.h +X +Xclean: +X rm -f *.o +! +echo 'closedir.c': +sed 's/^X//' >'closedir.c' <<'!' +Xstatic char sccsid[] = "@(#)closedir.c 4.2 3/10/82"; +X +X#include <sys/types.h> +X#include <dir.h> +X +X/* +X * close a directory. +X */ +Xvoid +Xclosedir(dirp) +X register DIR *dirp; +X{ +X close(dirp->dd_fd); +X dirp->dd_fd = -1; +X dirp->dd_loc = 0; +X free((char *)dirp); +X} +! +echo 'opendir.c': +sed 's/^X//' >'opendir.c' <<'!' +X/* Copyright (c) 1982 Regents of the University of California */ +X +Xstatic char sccsid[] = "@(#)opendir.c 4.4 11/12/82"; +X +X#include <sys/types.h> +X#include <sys/stat.h> +X#include <dir.h> +X +X/* +X * open a directory. +X */ +XDIR * +Xopendir(name) +X char *name; +X{ +X register DIR *dirp; +X register int fd; +X struct stat statbuf; +X char *malloc(); +X +X if ((fd = open(name, 0)) == -1) +X return NULL; +X if (fstat(fd, &statbuf) == -1 || !(statbuf.st_mode & S_IFDIR)) { +X close(fd); +X return NULL; +X } +X if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) { +X close (fd); +X return NULL; +X } +X dirp->dd_fd = fd; +X dirp->dd_loc = 0; +X dirp->dd_size = 0; /* so that telldir will work before readdir */ +X return dirp; +X} +! +echo 'readdir.c': +sed 's/^X//' >'readdir.c' <<'!' +X/* Copyright (c) 1982 Regents of the University of California */ +X +Xstatic char sccsid[] = "@(#)readdir.c 4.3 8/8/82"; +X +X#include <sys/types.h> +X#include <dir.h> +X +X/* +X * read an old stlye directory entry and present it as a new one +X */ +X#define ODIRSIZ 14 +X +Xstruct olddirect { +X ino_t od_ino; +X char od_name[ODIRSIZ]; +X}; +X +X/* +X * get next entry in a directory. +X */ +Xstruct direct * +Xreaddir(dirp) +X register DIR *dirp; +X{ +X register struct olddirect *dp; +X static struct direct dir; +X +X for (;;) { +X if (dirp->dd_loc == 0) { +X dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, +X DIRBLKSIZ); +X if (dirp->dd_size <= 0) { +X dirp->dd_size = 0; +X return NULL; +X } +X } +X if (dirp->dd_loc >= dirp->dd_size) { +X dirp->dd_loc = 0; +X continue; +X } +X dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc); +X dirp->dd_loc += sizeof(struct olddirect); +X if (dp->od_ino == 0) +X continue; +X dir.d_ino = dp->od_ino; +X strncpy(dir.d_name, dp->od_name, ODIRSIZ); +X dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */ +X dir.d_namlen = strlen(dir.d_name); +X dir.d_reclen = DIRBLKSIZ; +X return (&dir); +X } +X} +! +echo 'seekdir.c': +sed 's/^X//' >'seekdir.c' <<'!' +Xstatic char sccsid[] = "@(#)seekdir.c 4.9 3/25/83"; +X +X#include <sys/param.h> +X#include <dir.h> +X +X/* +X * seek to an entry in a directory. +X * Only values returned by "telldir" should be passed to seekdir. +X */ +Xvoid +Xseekdir(dirp, loc) +X register DIR *dirp; +X long loc; +X{ +X long curloc, base, offset; +X struct direct *dp; +X extern long lseek(); +X +X curloc = telldir(dirp); +X if (loc == curloc) +X return; +X base = loc & ~(DIRBLKSIZ - 1); +X offset = loc & (DIRBLKSIZ - 1); +X (void) lseek(dirp->dd_fd, base, 0); +X dirp->dd_size = 0; +X dirp->dd_loc = 0; +X while (dirp->dd_loc < offset) { +X dp = readdir(dirp); +X if (dp == NULL) +X return; +X } +X} +! +echo 'telldir.c': +sed 's/^X//' >'telldir.c' <<'!' +Xstatic char sccsid[] = "@(#)telldir.c 4.1 2/21/82"; +X +X#include <sys/types.h> +X#include <dir.h> +X +X/* +X * return a pointer into a directory +X */ +Xlong +Xtelldir(dirp) +X DIR *dirp; +X{ +X long lseek(); +X +X return (lseek(dirp->dd_fd, 0L, 1) - dirp->dd_size + dirp->dd_loc); +X} +! +echo done diff --git a/gnu/usr.bin/cvs/contrib/easy-import.perl b/gnu/usr.bin/cvs/contrib/easy-import.perl new file mode 100644 index 000000000000..44f6f4cb2938 --- /dev/null +++ b/gnu/usr.bin/cvs/contrib/easy-import.perl @@ -0,0 +1,388 @@ +#!/usr/bin/perl +# +# Support for importing a source collection into CVS. +# Tries to prevent the user from the most common pitfalls (like creating +# new top-level repositories or second-level areas accidentally), and +# cares to do some of the `dirty' work like maintaining the modules +# database accordingly. +# +# Written by Jörg Wunsch, 95/03/07, and placed in the public domain. +# +# $Id: easy-import.perl,v 1.3 1995/07/23 17:34:00 joerg Exp $ + +require "complete.pl"; +require "getopts.pl"; + + +sub scan_opts +{ + local($status); + + $status = &Getopts("nv"); + + $dont_do_it = "-n" if $opt_n; + if($opt_v) { + print STDERR '$Source: /home/ncvs/src/gnu/usr.bin/cvs/contrib/easy-import.perl,v $ $Revision: 1.3 $' . "\n"; # 'emacs kludge + exit 0; + } + die "usage: $0 [-v] [-n] [moduledir]\n" . + " -n: don't do any commit, show only\n" . + " -v: show program version\n" + unless $status && $#ARGV <= 0; + + if($#ARGV == 0) { + $moduledir = $ARGV[0]; + shift; + } +} + +sub lsdir +{ + # find all subdirectories under @_ + # ignore all CVS entries, dot entries, and non-directories + + local($base) = @_; + local(@ls, @rv, $fname); + + opendir(DIR, $base) || die "Cannot find dir $base.\n"; + + @ls = readdir(DIR); + closedir(DIR); + + @rv = (); + + foreach $fname (@ls) { + next if $fname =~ /^CVS/ || $fname eq "Attic" + || $fname =~ /^\./ || ! -d "$base/$fname"; + @rv = (@rv, $fname); + } + + return sort(@rv); +} + + +sub contains +{ + # look if the first parameter is contained in the list following it + local($item, @list) = @_; + local($found, $i); + + $found = 0; + foreach $i (@list) { + return 1 if $i eq $item; + } + return 0; +} + + + +sub term_init +{ + # first, get some terminal attributes + + # try bold mode first + $so = `tput md`; $se = `tput me`; + + # if no bold mode available, use standout mode + if ($so eq "") { + $so = `tput so`; $se = `tput se`; + } + + # try if we can underscore + $us = `tput us`; $ue = `tput ue`; + # if we don't have it available, or same as bold/standout, disable it + if ($us eq "" || $us eq $so) { + $us = $ue = ""; + } + + # look how many columns we've got + if($ENV{'COLUMNS'} ne "") { + $columns = $ENV{'COLUMNS'}; + } elsif(-t STDIN) { # if we operate on a terminal... + local($word, $tmp); + + open(STTY, "stty -a|"); + $_ = <STTY>; # try getting the tty win structure value + close(STTY); + chop; + $columns = 0; + foreach $word (split) { + $columns = $tmp if $word eq "columns;"; # the number preceding + $tmp = $word; + } + } else { + $columns = 80; + } + # sanity + $columns = 80 unless $columns >= 5; +} + + +sub list +{ + # pretty-print a list + # imports: global variable $columns + local(@items) = @_; + local($longest,$i,$item,$cols,$width); + + # find the longest item + $longest = 0; + foreach $item (@items) { + $i = length($item); + $longest = $i if $longest < $i; + } + $width = $longest + 1; + $cols = int($columns / $width); + + $i = 0; + foreach $item (@items) { + print $item; + if(++$i == $cols) { + $i = 0; print "\n"; + } else { + print ' ' x ($width - length($item)); + } + } + print "\n" unless $i == 0; +} + +sub cvs_init +{ + # get the CVS repository(s) + + die "You need to have the \$CVSROOT variable set.\n" + unless $ENV{'CVSROOT'} ne ""; + + # get the list of available repositories + $cvsroot = $ENV{'CVSROOT'}; + @reps = &lsdir($cvsroot); +} + + +sub lsmodules +{ + # list all known CVS modules + local(@rv, $mname, $_); + + @rv = (); + + open(CVS, "cvs co -c|"); + while($_ = <CVS>) { + chop; + ($mname) = split; + next if $mname eq ""; + @rv = (@rv, $mname); + } + close(CVS); + + return @rv; +} + + +sub checktag +{ + # check a given string for tag rules + local($s, $name) = @_; + local($regexp); + + if($name eq "vendor") { $regexp = '^[A-Z][A-Z0-9_]*$'; } + elsif($name eq "release") { $regexp = '^[a-z][a-z0-9_]*$'; } + else { + print STDERR "Internal error: unknown tag name $name\n"; + exit(2); + } + + if($s !~ /$regexp/) { + print "\a${us}Valid $name tags must match the regexp " . + "$regexp.${ue}\n"; + return 0; + } + if($s =~ /^RELENG/) { + print "\a${us}Tags must not start with the word \"RELENG\".${ue}\n"; + return 0; + } + + return 1; +} + + +&scan_opts; +&term_init; +&cvs_init; + +if(! $moduledir) { + @dirs = &lsdir("."); + print "${so}Import from which directory?${se}\n"; + @dirs = (@dirs, "."); + &list(@dirs); + $moduledir = &Complete("Which? [.]: ", @dirs); + $moduledir = "." unless $moduledir ne ""; +} + +chdir $moduledir || die "Cannot chdir to $moduledir\n"; + +print "${so}Available repositories:${se}\n"; +&list(@reps); + +# the following kludge prevents the Complete package from starting +# over with the string just selected; Complete should better provide +# some reinitialize method +$Complete'return = ""; $Complete'r = 0; + +$selected = + &Complete("Enter repository (<TAB>=complete, ^D=show): ", + @reps); + +die "\aYou cannot create new repositories with this script.\n" + unless &contains($selected, @reps); + +$rep = $selected; + +print "\n${so}Selected repository:${se} ${us}$rep${ue}\n"; + + +@areas = &lsdir("$cvsroot/$rep"); + +print "${so}Existent areas in this repository:${se}\n"; +&list(@areas); + +$Complete'return = ""; $Complete'r = 0; + +$selected = + &Complete("Enter area name (<TAB>=complete, ^D=show): ", + @areas); + +print "\a${us}Warning: this will create a new area.${ue}\n" + unless &contains($selected, @areas); + +$area = "$rep/$selected"; + +print "\n${so}[Working on:${se} ${us}$area${ue}${so}]${se}\n"; + +for(;;) { + $| = 1; + print "${so}Enter the module path:${se} $area/"; + $| = 0; + $modpath = <>; + chop $modpath; + if ($modpath eq "") { + print "\a${us}You cannot use an empty module path.${ue}\n"; + next; + } + last if ! -d "$cvsroot/$area/$modpath"; + print "\a${us}This module path does already exist; " . + "choose another one.${ue}\n"; +} + + +@newdirs = (); +$dir1 = "$cvsroot/$area"; +$dir2 = "$area"; + +@newdirs = (@newdirs, "$dir2") if ! -d $dir1; + +foreach $ele (split(/\//, $modpath)) { + $dir1 = "$dir1/$ele"; + $dir2 = "$dir2/$ele"; + @newdirs = (@newdirs, "$dir2") if ! -d $dir1; +} + +print "${so}You're going to create the following new directories:${se}\n"; + +&list(@newdirs); + +@cvsmods = &lsmodules(); + +for(;;) { + $| = 1; + print "${so}Gimme the module name:${se} "; + $| = 0; + $modname = <>; + chop $modname; + if ($modname eq "") { + print "\a${us}You cannot use an empty module name.${ue}\n"; + next; + } + last if !&contains($modname, @cvsmods); + print "\a${us}This module name does already exist; " . + "choose another one.${ue}\n"; +} + + +for(;;) { + $| = 1; + print "${so}Enter a \`vendor\' tag (e. g. the authors ID):${se} "; + $| = 0; + $vtag = <>; + chop $vtag; + last if &checktag($vtag, "vendor"); +} + +for(;;) { + $| = 1; + print "${so}Enter a \`release\' tag (e. g. the version #):${se} "; + $| = 0; + $rtag = <>; + chop $rtag; + last if &checktag($rtag, "release"); +} + + +$| = 1; +print "${so}This is your last chance to interrupt, " . + "hit <return> to go on:${se} "; +$| = 0; +<>; + +$mod = ""; +foreach $tmp (@cvsmods) { + if($tmp gt $modname) { + $mod = $tmp; + last; + } +} + +if($mod eq "") { + # we are going to append our module + $cmd = "\$\na\n"; +} else { + # we can insert it + $cmd = "/^${mod}[ \t]/\ni\n"; +} + +print "${so}Checking out the modules database...${se}\n"; +system("cvs co modules") && die "${us}failed.\n${ue}"; + +print "${so}Inserting new module...${se}\n"; +open(ED, "|ed modules/modules") || die "${us}Cannot start ed${ue}\n"; +print(ED "${cmd}${modname}" . ' ' x (16 - length($modname)) . + "$area/${modpath}\n.\nw\nq\n"); +close(ED); + +print "${so}Commiting new modules database...${se}\n"; +system("cvs $dont_do_it commit -m \" " . + "${modname} --> $area/${modpath}\" modules") + && die "Commit failed\n"; + +system("cvs $dont_do_it release -dQ modules"); + +print "${so}Importing source. Enter a commit message in the editor.${se}\n"; + +system("cvs $dont_do_it import $area/$modpath $vtag $rtag"); + +print "${so}You are done now. Go to a different directory, perform a${se}\n". + "${us}cvs co ${modname}${ue} ${so}command, and see if your new module" . + " builds ok.${se}\n"; + +if($dont_do_it) { +print <<END + + +${so}Since you did not allow to commit anything, you'll have${se} +${so}to remove the edited modules' database yourself.${se} +${so}To do this, perform a${se} +${us}cd ${moduledir}; cvs release -dQ modules${ue} +${so}command.${se} +END +; +} diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/cookie.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/cookie.el new file mode 100644 index 000000000000..8bd4bdff6ce0 --- /dev/null +++ b/gnu/usr.bin/cvs/contrib/pcl-cvs/cookie.el @@ -0,0 +1,884 @@ +;;; cookie.el,v 1.2 1992/04/07 20:49:12 berliner Exp +;;; cookie.el -- Utility to display cookies in buffers +;;; Copyright (C) 1991, 1992 Per Cederqvist +;;; +;;; This program is free software; you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 2 of the License, or +;;; (at your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program; if not, write to the Free Software +;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +;;;; TO-DO: Byt namn! tin -> wrapper (eller n}got b{ttre). + +;;; Note that this file is still under development. Comments, +;;; enhancements and bug fixes are welcome. +;;; Send them to ceder@lysator.liu.se. + +(defun impl nil (error "Not yet implemented!")) + +;;; Cookie is a package that imlements a connection between an +;;; elib-dll and the contents of a buffer. Possible uses are dired +;;; (have all files in a list, and show them), buffer-list, +;;; kom-prioritize (in the LysKOM elisp client) and others. pcl-cvs.el +;;; uses cookie.el. +;;; +;;; A cookie buffer contains a header, any number of cookies, and a +;;; footer. The header and footer are constant strings that are given +;;; to cookie-create when the buffer is placed under cookie. Each cookie +;;; is displayed in the buffer by calling a user-supplied function +;;; that takes a cookie and returns a string. The string may be +;;; empty, or contain any number of lines. An extra newline is always +;;; appended unless the string is empty. +;;; +;;; Cookie does not affect the mode of the buffer in any way. It +;;; merely makes it easy to connect an underlying data representation +;;; to the buffer contents. +;;; +;;; The cookie-node data type: +;;; start-marker +;;; ;; end-marker This field is no longer present. +;;; cookie The user-supplied element. +;;; +;;; A dll of cookie-nodes are held in the buffer local variable +;;; cake-tin. +;;; +;;; A tin is an object that contains one cookie. You can get the next +;;; and previous tin. +;;; + +(require 'elib-dll) +(provide 'cookie) + +(defvar cookies nil + "A doubly linked list that contains the underlying data representation +for the contents of a cookie buffer. The package elib-dll is used to +manipulate this list.") + +(defvar cookie-pretty-printer nil + "The function that is used to pretty-print a cookie in this buffer.") + +(defvar cookie-header nil + "The tin that holds the header cookie.") + +(defvar cookie-footer nil + "The tin that holds the footer cookie.") + +(defvar cookie-last-tin nil + "The tin the cursor was positioned at, the last time the cookie +package checked the cursor position. Buffer local in all buffers +the cookie package works on. You may set this if your package +thinks it knows where the cursor will be the next time this +package is called. It can speed things up. + +It must never be set to a tin that has been deleted.") + +;;; ================================================================ +;;; Internal functions for use in the cookie package + +(put 'cookie-set-buffer 'lisp-indent-hook 1) + +(defmacro cookie-set-buffer (buffer &rest forms) + + ;; Execute FORMS with BUFFER selected as current buffer. + ;; Return value of last form in FORMS. INTERNAL USE ONLY. + + (let ((old-buffer (make-symbol "old-buffer"))) + (` (let (((, old-buffer) (current-buffer))) + (set-buffer (get-buffer-create (, buffer))) + (unwind-protect + (progn (,@ forms)) + (set-buffer (, old-buffer))))))) + + +(defmacro cookie-filter-hf (tin) + + ;; Evaluate TIN once and return it. BUT if it is + ;; equal to cookie-header or cookie-footer return nil instead. + ;; INTERNAL USE ONLY. + + (let ((tempvar (make-symbol "tin"))) + (` (let (((, tempvar) (, tin))) + (if (or (eq (, tempvar) cookie-header) + (eq (, tempvar) cookie-footer)) + nil + (, tempvar)))))) + + +;;; cookie-tin +;;; Constructor: + +(defun cookie-create-tin (start-marker + cookie) + ;; Create a tin. INTERNAL USE ONLY. + (cons 'COOKIE-TIN (vector start-marker nil cookie))) + + +;;; Selectors: + +(defun cookie-tin-start-marker (cookie-tin) + ;; Get start-marker from cookie-tin. INTERNAL USE ONLY. + (elt (cdr cookie-tin) 0)) + +;(defun cookie-tin-end-marker (cookie-tin) +; ;;Get end-marker from cookie-tin. INTERNAL USE ONLY. +; (elt (cdr cookie-tin) 1)) + +(defun cookie-tin-cookie-safe (cookie-tin) + ;; Get cookie from cookie-tin. INTERNAL USE ONLY. + ;; Returns nil if given nil as input. + ;; This is the same as cookie-tin-cookie in version 18.57 + ;; of emacs, but elt should signal an error when given nil + ;; as input (according to the info files). + (elt (cdr cookie-tin) 2)) + +(defun cookie-tin-cookie (cookie-tin) + ;; Get cookie from cookie-tin. INTERNAL USE ONLY. + (elt (cdr cookie-tin) 2)) + + +;;; Modifiers: + +(defun set-cookie-tin-start-marker (cookie-tin newval) + ;; Set start-marker in cookie-tin to NEWVAL. INTERNAL USE ONLY. + (aset (cdr cookie-tin) 0 newval)) + +;(defun set-cookie-tin-end-marker (cookie-tin newval) +; ;; Set end-marker in cookie-tin to NEWVAL. INTERNAL USE ONLY. +; (aset (cdr cookie-tin) 1 newval)) + +(defun set-cookie-tin-cookie (cookie-tin newval) + ;; Set cookie in cookie-tin to NEWVAL. INTERNAL USE ONLY. + (aset (cdr cookie-tin) 2 newval)) + + + +;;; Predicate: + +(defun cookie-tin-p (object) + ;; Return t if OBJECT is a tin. INTERNAL USE ONLY. + (eq (car-safe object) 'COOKIE-TIN)) + +;;; end of cookie-tin data type. + + +(defun cookie-create-tin-and-insert (cookie string pos) + ;; Insert STRING at POS in current buffer. Remember start + ;; position. Create a tin containing them and the COOKIE. + ;; INTERNAL USE ONLY. + + (save-excursion + (goto-char pos) + ;; Remember the position as a number so that it doesn't move + ;; when we insert the string. + (let ((start (if (markerp pos) + (marker-position pos) + pos))) + ;; Use insert-before-markers so that the marker for the + ;; next cookie is updated. + (insert-before-markers string) + (insert-before-markers ?\n) + (cookie-create-tin (copy-marker start) cookie)))) + + +(defun cookie-delete-tin-internal (tin) + ;; Delete a cookie from the buffer. INTERNAL USE ONLY. + ;; Can not be used on the footer. + (delete-region (cookie-tin-start-marker (dll-element cookies tin)) + (cookie-tin-start-marker + (dll-element cookies + (dll-next cookies tin))))) + + + +(defun cookie-refresh-tin (tin) + ;; Redisplay the cookie represented by TIN. INTERNAL USE ONLY. + ;; Can not be used on the footer. + + (save-excursion + ;; First, remove the string: + (delete-region (cookie-tin-start-marker (dll-element cookies tin)) + (1- (marker-position + (cookie-tin-start-marker + (dll-element cookies + (dll-next cookies tin)))))) + + ;; Calculate and insert the string. + + (goto-char (cookie-tin-start-marker (dll-element cookies tin))) + (insert + (funcall cookie-pretty-printer + (cookie-tin-cookie (dll-element cookies tin)))))) + + +;;; ================================================================ +;;; The public members of the cookie package + + +(defun cookie-cookie (buffer tin) + "Get the cookie from a TIN. Args: BUFFER TIN." + (cookie-set-buffer buffer + (cookie-tin-cookie (dll-element cookies tin)))) + + + + +(defun cookie-create (buffer pretty-printer &optional header footer) + + "Start to use the cookie package in BUFFER. +BUFFER may be a buffer or a buffer name. It is created if it does not exist. +Beware that the entire contents of the buffer will be erased. +PRETTY-PRINTER is a function that takes one cookie and returns a string +to be displayed in the buffer. The string may be empty. If it is not +empty a newline will be added automatically. It may span several lines. +Optional third argument HEADER is a string that will always be present +at the top of the buffer. HEADER should end with a newline. Optionaly +fourth argument FOOTER is similar, and will always be inserted at the +bottom of the buffer." + + (cookie-set-buffer buffer + + (erase-buffer) + + (make-local-variable 'cookie-last-tin) + (make-local-variable 'cookie-pretty-printer) + (make-local-variable 'cookie-header) + (make-local-variable 'cookie-footer) + (make-local-variable 'cookies) + + (setq cookie-last-tin nil) + (setq cookie-pretty-printer pretty-printer) + (setq cookies (dll-create)) + + (dll-enter-first cookies + (cookie-create-tin-and-insert + header header 0)) + (setq cookie-header (dll-nth cookies 0)) + + (dll-enter-last cookies + (cookie-create-tin-and-insert + footer footer (point-max))) + (setq cookie-footer (dll-nth cookies -1)) + + (goto-char (point-min)) + (forward-line 1))) + + +(defun cookie-set-header (buffer header) + "Change the header. Args: BUFFER HEADER." + (impl)) + + +(defun cookie-set-footer (buffer header) + "Change the footer. Args: BUFFER FOOTER." + (impl)) + + + +(defun cookie-enter-first (buffer cookie) + "Enter a COOKIE first in BUFFER. +Args: BUFFER COOKIE." + + (cookie-set-buffer buffer + + ;; It is always safe to insert an element after the first element, + ;; because the header is always present. (dll-nth cookies 0) should + ;; never return nil. + + (dll-enter-after + cookies + (dll-nth cookies 0) + (cookie-create-tin-and-insert + cookie + (funcall cookie-pretty-printer cookie) + (cookie-tin-start-marker + (dll-element cookies (dll-nth cookies 1))))))) + + + +(defun cookie-enter-last (buffer cookie) + "Enter a COOKIE last in BUFFER. +Args: BUFFER COOKIE." + + (cookie-set-buffer buffer + + ;; Remember that the header and footer are always present. There + ;; is no need to check if (dll-nth cookies -2) returns nil. + + (dll-enter-before + cookies + (dll-nth cookies -1) + (cookie-create-tin-and-insert + cookie + (funcall cookie-pretty-printer cookie) + (cookie-tin-start-marker (dll-last cookies)))))) + + +(defun cookie-enter-after (buffer node cookie) + (impl)) + + +(defun cookie-enter-before (buffer node cookie) + (impl)) + + + +(defun cookie-next (buffer tin) + "Get the next tin. Args: BUFFER TIN. +Returns nil if TIN is nil or the last cookie." + (if tin + (cookie-set-buffer buffer + (cookie-filter-hf (dll-next cookies tin))))) + + + +(defun cookie-previous (buffer tin) + "Get the previous tin. Args: BUFFER TIN. +Returns nil if TIN is nil or the first cookie." + (if tin + (cookie-set-buffer buffer + (cookie-filter-hf (dll-previous cookies tin))))) + + +(defun cookie-nth (buffer n) + + "Return the Nth tin. Args: BUFFER N. +N counts from zero. Nil is returned if there is less than N cookies. +If N is negative, return the -(N+1)th last element. +Thus, (cookie-nth dll 0) returns the first node, +and (cookie-nth dll -1) returns the last node. + +Use cookie-cookie to extract the cookie from the tin." + + (cookie-set-buffer buffer + + ;; Skip the header (or footer, if n is negative). + (if (< n 0) + (setq n (1- n)) + (setq n (1+ n))) + + (cookie-filter-hf (dll-nth cookies n)))) + + + +(defun cookie-delete (buffer tin) + "Delete a cookie. Args: BUFFER TIN." + + (cookie-set-buffer buffer + (if (eq cookie-last-tin tin) + (setq cookie-last-tin nil)) + + (cookie-delete-tin-internal tin) + (dll-delete cookies tin))) + + + +(defun cookie-delete-first (buffer) + "Delete first cookie and return it. Args: BUFFER. +Returns nil if there is no cookie left." + + (cookie-set-buffer buffer + + ;; We have to check that we do not try to delete the footer. + + (let ((tin (dll-nth cookies 1))) ;Skip the header. + (if (eq tin cookie-footer) + nil + (cookie-delete-tin-internal tin) + (cookie-tin-cookie (dll-delete cookies tin)))))) + + + +(defun cookie-delete-last (buffer) + "Delete last cookie and return it. Args: BUFFER. +Returns nil if there is no cookie left." + + (cookie-set-buffer buffer + + ;; We have to check that we do not try to delete the header. + + (let ((tin (dll-nth cookies -2))) ;Skip the footer. + (if (eq tin cookie-header) + nil + (cookie-delete-tin-internal tin) + (cookie-tin-cookie (dll-delete cookies tin)))))) + + + +(defun cookie-first (buffer) + + "Return the first cookie in BUFFER. The cookie is not removed." + + (cookie-set-buffer buffer + (let ((tin (cookie-filter-hf (dll-nth cookies -1)))) + (if tin + (cookie-tin-cookie-safe + (dll-element cookies tin)))))) + + +(defun cookie-last (buffer) + + "Return the last cookie in BUFFER. The cookie is not removed." + + (cookie-set-buffer buffer + (let ((tin (cookie-filter-hf (dll-nth cookies -2)))) + (if tin + (cookie-tin-cookie-safe + (dll-element cookies tin)))))) + + +(defun cookie-empty (buffer) + + "Return true if there are no cookies in BUFFER." + + (cookie-set-buffer buffer + (eq (dll-nth cookies 1) cookie-footer))) + + +(defun cookie-length (buffer) + + "Return number of cookies in BUFFER." + + ;; Don't count the footer and header. + + (cookie-set-buffer buffer + (- (dll-length cookies) 2))) + + +(defun cookie-all (buffer) + + "Return a list of all cookies in BUFFER." + + (cookie-set-buffer buffer + (let (result + (tin (dll-nth cookies -2))) + (while (not (eq tin cookie-header)) + (setq result (cons (cookie-tin-cookie (dll-element cookies tin)) + result)) + (setq tin (dll-previous cookies tin))) + result))) + +(defun cookie-clear (buffer) + + "Remove all cookies in buffer." + + (cookie-set-buffer buffer + (cookie-create buffer cookie-pretty-printer + (cookie-tin-cookie (dll-element cookies cookie-header)) + (cookie-tin-cookie (dll-element cookies cookie-footer))))) + + + +(defun cookie-map (map-function buffer &rest map-args) + + "Apply MAP-FUNCTION to all cookies in BUFFER. +MAP-FUNCTION is applied to the first element first. +If MAP-FUNCTION returns non-nil the cookie will be refreshed. + +Note that BUFFER will be current buffer when MAP-FUNCTION is called. + +If more than two arguments are given to cookie-map, remaining +arguments will be passed to MAP-FUNCTION." + + (cookie-set-buffer buffer + (let ((tin (dll-nth cookies 1)) + result) + + (while (not (eq tin cookie-footer)) + + (if (apply map-function + (cookie-tin-cookie (dll-element cookies tin)) + map-args) + (cookie-refresh-tin tin)) + + (setq tin (dll-next cookies tin)))))) + + + +(defun cookie-map-reverse (map-function buffer &rest map-args) + + "Apply MAP-FUNCTION to all cookies in BUFFER. +MAP-FUNCTION is applied to the last cookie first. +If MAP-FUNCTION returns non-nil the cookie will be refreshed. + +Note that BUFFER will be current buffer when MAP-FUNCTION is called. + +If more than two arguments are given to cookie-map, remaining +arguments will be passed to MAP-FUNCTION." + + (cookie-set-buffer buffer + (let ((tin (dll-nth cookies -2)) + result) + + (while (not (eq tin cookie-header)) + + (if (apply map-function + (cookie-tin-cookie (dll-element cookies tin)) + map-args) + (cookie-refresh-tin tin)) + + (setq tin (dll-previous cookies tin)))))) + + + +(defun cookie-enter-cookies (buffer cookie-list) + + "Insert all cookies in the list COOKIE-LIST last in BUFFER. +Args: BUFFER COOKIE-LIST." + + (while cookie-list + (cookie-enter-last buffer (car cookie-list)) + (setq cookie-list (cdr cookie-list)))) + + +(defun cookie-filter (buffer predicate) + + "Remove all cookies in BUFFER for which PREDICATE returns nil. +Note that BUFFER will be current-buffer when PREDICATE is called. + +The PREDICATE is called with one argument, the cookie." + + (cookie-set-buffer buffer + (let ((tin (dll-nth cookies 1)) + next) + (while (not (eq tin cookie-footer)) + (setq next (dll-next cookies tin)) + (if (funcall predicate (cookie-tin-cookie (dll-element cookies tin))) + nil + (cookie-delete-tin-internal tin) + (dll-delete cookies tin)) + (setq tin next))))) + + +(defun cookie-filter-tins (buffer predicate) + + "Remove all cookies in BUFFER for which PREDICATE returns nil. +Note that BUFFER will be current-buffer when PREDICATE is called. + +The PREDICATE is called with one argument, the tin." + + (cookie-set-buffer buffer + (let ((tin (dll-nth cookies 1)) + next) + (while (not (eq tin cookie-footer)) + (setq next (dll-next cookies tin)) + (if (funcall predicate tin) + nil + (cookie-delete-tin-internal tin) + (dll-delete cookies tin)) + (setq tin next))))) + +(defun cookie-pos-before-middle-p (pos tin1 tin2) + + "Return true if POS is in the first half of the region defined by TIN1 and +TIN2." + + (< pos (/ (+ (cookie-tin-start-marker (dll-element cookeis tin1)) + (cookie-tin-start-marker (dll-element cookeis tin2))) + 2))) + + +(defun cookie-get-selection (buffer pos &optional guess force-guess) + + "Return the tin the POS is within. +Args: BUFFER POS &optional GUESS FORCE-GUESS. +GUESS should be a tin that it is likely that POS is near. If FORCE-GUESS +is non-nil GUESS is always used as a first guess, otherwise the first +guess is the first tin, last tin, or GUESS, whichever is nearest to +pos in the BUFFER. + +If pos points within the header, the first cookie is returned. +If pos points within the footer, the last cookie is returned. +Nil is returned if there is no cookie. + +It is often good to specify cookie-last-tin as GUESS, but remember +that cookie-last-tin is buffer local in all buffers that cookie +operates on." + + (cookie-set-buffer buffer + + (cond + ; No cookies present? + ((eq (dll-nth cookies 1) (dll-nth cookies -1)) + nil) + + ; Before first cookie? + ((< pos (cookie-tin-start-marker + (dll-element cookies (dll-nth cookies 1)))) + (dll-nth cookies 1)) + + ; After last cookie? + ((>= pos (cookie-tin-start-marker (dll-last cookies))) + (dll-nth cookies -2)) + + ; We now now that pos is within a cookie. + (t + ; Make an educated guess about which of the three known + ; cookies (the first, the last, or GUESS) is nearest. + (setq + guess + (cond + (force-guess guess) + (guess + (cond + ;; Closest to first cookie? + ((cookie-pos-before-middle-p + pos guess + (dll-nth cookies 1)) + (dll-nth cookies 1)) + ;; Closest to GUESS? + ((cookie-pos-before-middle-p + pos guess + cookie-footer) + guess) + ;; Closest to last cookie. + (t (dll-previous cookies cookie-footer)))) + (t + ;; No guess given. + (cond + ;; First half? + ((cookie-pos-before-middle-p + pos (dll-nth cookies 1) + cookie-footer) + (dll-nth cookies 1)) + (t (dll-previous cookies cookie-footer)))))) + + ;; GUESS is now a "best guess". + + ;; Find the correct cookie. First determine in which direction + ;; it lies, and then move in that direction until it is found. + + (cond + ;; Is pos after the guess? + ((>= pos (cookie-tin-start-marker (dll-element cookiess guess))) + + ;; Loop until we are exactly one cookie too far down... + (while (>= pos (cookie-tin-start-marker (dll-element cookiess guess))) + (setq guess (dll-next cookies guess))) + + ;; ...and return the previous cookie. + (dll-previous cookies guess)) + + ;; Pos is before guess + (t + + (while (< pos (cookie-tin-start-marker (dll-element cookiess guess))) + (setq guess (dll-previous cookies guess))) + + guess)))))) + + +(defun cookie-start-marker (buffer tin) + + "Return start-position of a cookie in BUFFER. +Args: BUFFER TIN. +The marker that is returned should not be modified in any way, +and is only valid until the contents of the cookie buffer changes." + + (cookie-set-buffer buffer + (cookie-tin-start-marker (dll-element cookies tin)))) + + +(defun cookie-end-marker (buffer tin) + + "Return end-position of a cookie in BUFFER. +Args: BUFFER TIN. +The marker that is returned should not be modified in any way, +and is only valid until the contents of the cookie buffer changes." + + (cookie-set-buffer buffer + (cookie-tin-start-marker + (dll-element cookies (dll-next cookies tin))))) + + + +(defun cookie-refresh (buffer) + + "Refresh all cookies in BUFFER. +Cookie-pretty-printer will be called for all cookies and the new result +displayed. + +See also cookie-invalidate-tins." + + (cookie-set-buffer buffer + + (erase-buffer) + + (set-marker (cookie-tin-start-marker (dll-element cookies cookie-header)) + (point) buffer) + (insert (cookie-tin-cookie (dll-element cookies cookie-header))) + (insert "\n") + + (let ((tin (dll-nth cookies 1))) + (while (not (eq tin cookie-footer)) + + (set-marker (cookie-tin-start-marker (dll-element cookies tin)) + (point) buffer) + (insert + (funcall cookie-pretty-printer + (cookie-tin-cookie (dll-element cookies tin)))) + (insert "\n") + (setq tin (dll-next cookies tin)))) + + (set-marker (cookie-tin-start-marker (dll-element cookies cookie-footer)) + (point) buffer) + (insert (cookie-tin-cookie (dll-element cookies cookie-footer))) + (insert "\n"))) + + +(defun cookie-invalidate-tins (buffer &rest tins) + + "Refresh some cookies. +Args: BUFFER &rest TINS." + + (cookie-set-buffer buffer + + (while tins + (cookie-refresh-tin (car tins)) + (setq tins (cdr tins))))) + + +;;; Cookie movement commands. + +(defun cookie-set-goal-column (buffer goal) + "Set goal-column for BUFFER. +Args: BUFFER GOAL. +goal-column is made buffer-local." + (cookie-set-buffer buffer + (make-local-variable 'goal-column) + (setq goal-column goal))) + + +(defun cookie-previous-cookie (buffer pos arg) + "Move point to the ARGth previous cookie. +Don't move if we are at the first cookie. +ARG is the prefix argument when called interactively. +Args: BUFFER POS ARG. +Sets cookie-last-tin to the cookie we move to." + + (interactive (list (current-buffer) (point) + (prefix-numeric-value current-prefix-arg))) + + (cookie-set-buffer buffer + (setq cookie-last-tin + (cookie-get-selection buffer pos cookie-last-tin)) + + (while (and cookie-last-tin (> arg 0)) + (setq arg (1- arg)) + (setq cookie-last-tin + (dll-previous cookies cookie-last-tin))) + + ;; Never step above the first cookie. + + (if (null (cookie-filter-hf cookie-last-tin)) + (setq cookie-last-tin (dll-nth cookies 1))) + + (goto-char + (cookie-tin-start-marker + (dll-element cookies cookie-last-tin))) + + (if goal-column + (move-to-column goal-column)))) + + + +(defun cookie-next-cookie (buffer pos arg) + "Move point to the ARGth next cookie. +Don't move if we are at the last cookie. +ARG is the prefix argument when called interactively. +Args: BUFFER POS ARG. +Sets cookie-last-tin to the cookie we move to." + + (interactive (list (current-buffer) (point) + (prefix-numeric-value current-prefix-arg))) + + (cookie-set-buffer buffer + (setq cookie-last-tin + (cookie-get-selection buffer pos cookie-last-tin)) + + (while (and cookie-last-tin (> arg 0)) + (setq arg (1- arg)) + (setq cookie-last-tin + (dll-next cookies cookie-last-tin))) + + (if (null (cookie-filter-hf cookie-last-tin)) + (setq cookie-last-tin (dll-nth cookies -2))) + + (goto-char + (cookie-tin-start-marker + (dll-element cookies cookie-last-tin))) + + (if goal-column + (move-to-column goal-column)))) + + +(defun cookie-collect-tins (buffer predicate &rest predicate-args) + + "Return a list of all tins in BUFFER whose cookie PREDICATE +returns true for. +PREDICATE is a function that takes a cookie as its argument. +The tins on the returned list will appear in the same order +as in the buffer. You should not rely on in which order PREDICATE +is called. Note that BUFFER is current-buffer when PREDICATE +is called. (If you call cookie-collect with another buffer set +as current-buffer and need to access buffer-local variables +from that buffer within PREDICATE you must send them via +PREDICATE-ARGS). + +If more than two arguments are given to cookie-collect the remaining +arguments will be passed to PREDICATE. + +Use cookie-cookie to get the cookie from the tin." + + (cookie-set-buffer buffer + (let ((tin (dll-nth cookies -2)) + result) + + (while (not (eq tin cookie-header)) + + (if (apply predicate + (cookie-tin-cookie (dll-element cookies tin)) + predicate-args) + (setq result (cons tin result))) + + (setq tin (dll-previous cookies tin))) + result))) + + +(defun cookie-collect-cookies (buffer predicate &rest predicate-args) + + "Return a list of all cookies in BUFFER that PREDICATE +returns true for. +PREDICATE is a function that takes a cookie as its argument. +The cookie on the returned list will appear in the same order +as in the buffer. You should not rely on in which order PREDICATE +is called. Note that BUFFER is current-buffer when PREDICATE +is called. (If you call cookie-collect with another buffer set +as current-buffer and need to access buffer-local variables +from that buffer within PREDICATE you must send them via +PREDICATE-ARGS). + +If more than two arguments are given to cookie-collect the remaining +arguments will be passed to PREDICATE." + + (cookie-set-buffer buffer + (let ((tin (dll-nth cookies -2)) + result) + + (while (not (eq tin cookie-header)) + + (if (apply predicate + (cookie-tin-cookie (dll-element cookies tin)) + predicate-args) + (setq result (cons (cookie-tin-cookie (dll-element cookies tin)) + result))) + + (setq tin (dll-previous cookies tin))) + result))) diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll-debug.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll-debug.el new file mode 100644 index 000000000000..733ff86f46c0 --- /dev/null +++ b/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll-debug.el @@ -0,0 +1,298 @@ +;;; elib-dll-debug -- A slow implementation of elib-dll for debugging. +;;; elib-dll-debug.el,v 1.2 1992/04/07 20:49:13 berliner Exp +;;; Copyright (C) 1991,1992 Per Cederqvist +;;; +;;; This program is free software; you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 2 of the License, or +;;; (at your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program; if not, write to the Free Software +;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +;;; This is a plug-in replacement for elib-dll.el. It is dreadfully +;;; slow, but it facilitates debugging. Don't trust the comments in +;;; this file too much. +(provide 'elib-dll) + +;;; +;;; A doubly linked list consists of one cons cell which holds the tag +;;; 'DL-LIST in the car cell and the list in the cdr +;;; cell. The doubly linked list is implemented as a normal list. You +;;; should use elib-dll.el and not this package in debugged code. This +;;; package is not written for speed... +;;; + +;;; ================================================================ +;;; Internal functions for use in the doubly linked list package + +(defun dll-get-dummy-node (dll) + + ;; Return the dummy node. INTERNAL USE ONLY. + dll) + +(defun dll-list-nodes (dll) + + ;; Return a list of all nodes in DLL. INTERNAL USE ONLY. + + (cdr dll)) + +(defun dll-set-from-node-list (dll list) + + ;; Set the contents of DLL to the nodes in LIST. + ;; INTERNAL USE ONLY. + + (setcdr dll list)) + +(defun dll-get-node-before (dll node) + ;; Return the node in DLL that points to NODE. Use + ;; (dll-get-node-before some-list nil) to get the last node. + ;; INTERNAL USE ONLY. + (while (and dll (not (eq (cdr dll) node))) + (setq dll (cdr dll))) + (if (not dll) + (error "Node not on list")) + dll) + +(defmacro dll-insert-after (node element) + (let ((node-v (make-symbol "node")) + (element-v (make-symbol "element"))) + (` (let (((, node-v) (, node)) + ((, element-v) (, element))) + (setcdr (, node-v) (cons (, element-v) (cdr (, node-v)))))))) + +;;; =================================================================== +;;; The public functions which operate on doubly linked lists. + +(defmacro dll-element (dll node) + + "Get the element of a NODE in a doubly linked list DLL. +Args: DLL NODE." + + (` (car (, node)))) + + +(defun dll-create () + "Create an empty doubly linked list." + (cons 'DL-LIST nil)) + + +(defun dll-p (object) + "Return t if OBJECT is a doubly linked list, otherwise return nil." + (eq (car-safe object) 'DL-LIST)) + + +(defun dll-enter-first (dll element) + "Add an element first on a doubly linked list. +Args: DLL ELEMENT." + (setcdr dll (cons element (cdr dll)))) + + +(defun dll-enter-last (dll element) + "Add an element last on a doubly linked list. +Args: DLL ELEMENT." + (dll-insert-after (dll-get-node-before dll nil) element)) + + +(defun dll-enter-after (dll node element) + "In the doubly linked list DLL, insert a node containing ELEMENT after NODE. +Args: DLL NODE ELEMENT." + + (dll-get-node-before dll node) + (dll-insert-after node element)) + + +(defun dll-enter-before (dll node element) + "In the doubly linked list DLL, insert a node containing ELEMENT before NODE. +Args: DLL NODE ELEMENT." + + (dll-insert-after (dll-get-node-before dll node) element)) + + + +(defun dll-next (dll node) + "Return the node after NODE, or nil if NODE is the last node. +Args: DLL NODE." + + (dll-get-node-before dll node) + (cdr node)) + + +(defun dll-previous (dll node) + "Return the node before NODE, or nil if NODE is the first node. +Args: DLL NODE." + + (dll-get-node-before dll node)) + + +(defun dll-delete (dll node) + + "Delete NODE from the doubly linked list DLL. +Args: DLL NODE. Return the element of node." + + ;; This is a no-op when applied to the dummy node. This will return + ;; nil if applied to the dummy node since it always contains nil. + + (setcdr (dll-get-node-before dll node) (cdr node))) + + +(defun dll-delete-first (dll) + + "Delete the first NODE from the doubly linked list DLL. +Return the element. Args: DLL. Returns nil if the DLL was empty." + + ;; Relies on the fact that dll-delete does nothing and + ;; returns nil if given the dummy node. + + (setcdr dll (cdr (cdr dll)))) + + +(defun dll-delete-last (dll) + + "Delete the last NODE from the doubly linked list DLL. +Return the element. Args: DLL. Returns nil if the DLL was empty." + + ;; Relies on the fact that dll-delete does nothing and + ;; returns nil if given the dummy node. + + (setcdr dll (dll-get-node-before dll nil) nil)) + + +(defun dll-first (dll) + + "Return the first element on the doubly linked list DLL. +Return nil if the list is empty. The element is not removed." + + (car (cdr dll))) + + + + +(defun dll-last (dll) + + "Return the last element on the doubly linked list DLL. +Return nil if the list is empty. The element is not removed." + + (car (dll-get-node-before dll nil))) + + + +(defun dll-nth (dll n) + + "Return the Nth node from the doubly linked list DLL. + Args: DLL N +N counts from zero. If DLL is not that long, nil is returned. +If N is negative, return the -(N+1)th last element. +Thus, (dll-nth dll 0) returns the first node, +and (dll-nth dll -1) returns the last node." + + ;; Branch 0 ("follow left pointer") is used when n is negative. + ;; Branch 1 ("follow right pointer") is used otherwise. + + (if (>= n 0) + (nthcdr n (cdr dll)) + (unwind-protect + (progn (setcdr dll (nreverse (cdr dll))) + (nthcdr (- n) dll)) + (setcdr dll (nreverse (cdr dll)))))) + +(defun dll-empty (dll) + + "Return t if the doubly linked list DLL is empty, nil otherwise" + + (not (cdr dll))) + +(defun dll-length (dll) + + "Returns the number of elements in the doubly linked list DLL." + + (length (cdr dll))) + + + +(defun dll-copy (dll &optional element-copy-fnc) + + "Return a copy of the doubly linked list DLL. +If optional second argument ELEMENT-COPY-FNC is non-nil it should be +a function that takes one argument, an element, and returns a copy of it. +If ELEMENT-COPY-FNC is not given the elements are not copied." + + (if element-copy-fnc + (cons 'DL-LIST (mapcar element-copy-fnc (cdr dll))) + (copy-sequence dll))) + + +(defun dll-all (dll) + + "Return all elements on the double linked list DLL as an ordinary list." + + (cdr dll)) + + +(defun dll-clear (dll) + + "Clear the doubly linked list DLL, i.e. make it completely empty." + + (setcdr dll nil)) + + +(defun dll-map (map-function dll) + + "Apply MAP-FUNCTION to all elements in the doubly linked list DLL. +The function is applied to the first element first." + + (mapcar map-function (cdr dll))) + + +(defun dll-map-reverse (map-function dll) + + "Apply MAP-FUNCTION to all elements in the doubly linked list DLL. +The function is applied to the last element first." + + (unwind-protect + (setcdr dll (nreverse (cdr dll))) + (mapcar map-function (cdr dll)) + (setcdr dll (nreverse (cdr dll))))) + + +(defun dll-create-from-list (list) + + "Given an elisp LIST create a doubly linked list with the same elements." + + (cons 'DL-LIST list)) + + + +(defun dll-sort (dll predicate) + + "Sort the doubly linked list DLL, stably, comparing elements using PREDICATE. +Returns the sorted list. DLL is modified by side effects. +PREDICATE is called with two elements of DLL, and should return T +if the first element is \"less\" than the second." + + (setcdr dll (sort (cdr dll) predicate)) + dll) + + +(defun dll-filter (dll predicate) + + "Remove all elements in the doubly linked list DLL for which PREDICATE +return nil." + + (let* ((prev dll) + (node (cdr dll))) + + (while node + (cond + ((funcall predicate (car node)) + (setq prev node)) + (t + (setcdr prev (cdr node)))) + (setq node (cdr node))))) diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll.el new file mode 100644 index 000000000000..855bd19e8ee0 --- /dev/null +++ b/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll.el @@ -0,0 +1,386 @@ +;;; elib-dll.el,v 1.2 1992/04/07 20:49:15 berliner Exp +;;; elib-dll.el -- Some primitives for Doubly linked lists. +;;; Copyright (C) 1991, 1992 Per Cederqvist +;;; +;;; This program is free software; you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 2 of the License, or +;;; (at your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program; if not, write to the Free Software +;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +;;; Mail bug reports to ceder@lysator.liu.se. + +(require 'elib-node) +(provide 'elib-dll) + +;;; +;;; A doubly linked list consists of one cons cell which holds the tag +;;; 'DL-LIST in the car cell and a pointer to a dummy node in the cdr +;;; cell. The doubly linked list is implemented as a circular list +;;; with the dummy node first and last. The dummy node is recognized +;;; by comparing it to the node which the cdr of the cons cell points +;;; to. +;;; + +;;; ================================================================ +;;; Internal functions for use in the doubly linked list package + +(defun dll-get-dummy-node (dll) + + ;; Return the dummy node. INTERNAL USE ONLY. + (cdr dll)) + +(defun dll-list-nodes (dll) + + ;; Return a list of all nodes in DLL. INTERNAL USE ONLY. + + (let* ((result nil) + (dummy (dll-get-dummy-node dll)) + (node (elib-node-left dummy))) + + (while (not (eq node dummy)) + (setq result (cons node result)) + (setq node (elib-node-left node))) + + result)) + +(defun dll-set-from-node-list (dll list) + + ;; Set the contents of DLL to the nodes in LIST. + ;; INTERNAL USE ONLY. + + (dll-clear dll) + (let* ((dummy (dll-get-dummy-node dll)) + (left dummy)) + (while list + (elib-node-set-left (car list) left) + (elib-node-set-right left (car list)) + (setq left (car list)) + (setq list (cdr list))) + + (elib-node-set-right left dummy) + (elib-node-set-left dummy left))) + + +;;; =================================================================== +;;; The public functions which operate on doubly linked lists. + +(defmacro dll-element (dll node) + + "Get the element of a NODE in a doubly linked list DLL. +Args: DLL NODE." + + (` (elib-node-data (, node)))) + + +(defun dll-create () + "Create an empty doubly linked list." + (let ((dummy-node (elib-node-create nil nil nil))) + (elib-node-set-right dummy-node dummy-node) + (elib-node-set-left dummy-node dummy-node) + (cons 'DL-LIST dummy-node))) + +(defun dll-p (object) + "Return t if OBJECT is a doubly linked list, otherwise return nil." + (eq (car-safe object) 'DL-LIST)) + +(defun dll-enter-first (dll element) + "Add an element first on a doubly linked list. +Args: DLL ELEMENT." + (dll-enter-after + dll + (dll-get-dummy-node dll) + element)) + + +(defun dll-enter-last (dll element) + "Add an element last on a doubly linked list. +Args: DLL ELEMENT." + (dll-enter-before + dll + (dll-get-dummy-node dll) + element)) + + +(defun dll-enter-after (dll node element) + "In the doubly linked list DLL, insert a node containing ELEMENT after NODE. +Args: DLL NODE ELEMENT." + + (let ((new-node (elib-node-create + node (elib-node-right node) + element))) + (elib-node-set-left (elib-node-right node) new-node) + (elib-node-set-right node new-node))) + + +(defun dll-enter-before (dll node element) + "In the doubly linked list DLL, insert a node containing ELEMENT before NODE. +Args: DLL NODE ELEMENT." + + (let ((new-node (elib-node-create + (elib-node-left node) node + element))) + (elib-node-set-right (elib-node-left node) new-node) + (elib-node-set-left node new-node))) + + + +(defun dll-next (dll node) + "Return the node after NODE, or nil if NODE is the last node. +Args: DLL NODE." + + (if (eq (elib-node-right node) (dll-get-dummy-node dll)) + nil + (elib-node-right node))) + + +(defun dll-previous (dll node) + "Return the node before NODE, or nil if NODE is the first node. +Args: DLL NODE." + + (if (eq (elib-node-left node) (dll-get-dummy-node dll)) + nil + (elib-node-left node))) + + +(defun dll-delete (dll node) + + "Delete NODE from the doubly linked list DLL. +Args: DLL NODE. Return the element of node." + + ;; This is a no-op when applied to the dummy node. This will return + ;; nil if applied to the dummy node since it always contains nil. + + (elib-node-set-right (elib-node-left node) (elib-node-right node)) + (elib-node-set-left (elib-node-right node) (elib-node-left node)) + (dll-element dll node)) + + + +(defun dll-delete-first (dll) + + "Delete the first NODE from the doubly linked list DLL. +Return the element. Args: DLL. Returns nil if the DLL was empty." + + ;; Relies on the fact that dll-delete does nothing and + ;; returns nil if given the dummy node. + + (dll-delete dll (elib-node-right (dll-get-dummy-node dll)))) + + +(defun dll-delete-last (dll) + + "Delete the last NODE from the doubly linked list DLL. +Return the element. Args: DLL. Returns nil if the DLL was empty." + + ;; Relies on the fact that dll-delete does nothing and + ;; returns nil if given the dummy node. + + (dll-delete dll (elib-node-left (dll-get-dummy-node dll)))) + + +(defun dll-first (dll) + + "Return the first element on the doubly linked list DLL. +Return nil if the list is empty. The element is not removed." + + (if (eq (elib-node-right (dll-get-dummy-node dll)) + (dll-get-dummy-node dll)) + nil + (elib-node-data (elib-node-right (dll-get-dummy-node dll))))) + + + + +(defun dll-last (dll) + + "Return the last element on the doubly linked list DLL. +Return nil if the list is empty. The element is not removed." + + (if (eq (elib-node-left (dll-get-dummy-node dll)) + (dll-get-dummy-node dll)) + nil + (elib-node-data (elib-node-left (dll-get-dummy-node dll))))) + + + +(defun dll-nth (dll n) + + "Return the Nth node from the doubly linked list DLL. + Args: DLL N +N counts from zero. If DLL is not that long, nil is returned. +If N is negative, return the -(N+1)th last element. +Thus, (dll-nth dll 0) returns the first node, +and (dll-nth dll -1) returns the last node." + + ;; Branch 0 ("follow left pointer") is used when n is negative. + ;; Branch 1 ("follow right pointer") is used otherwise. + + (let* ((dummy (dll-get-dummy-node dll)) + (branch (if (< n 0) 0 1)) + (node (elib-node-branch dummy branch))) + + (if (< n 0) + (setq n (- -1 n))) + + (while (and (not (eq dummy node)) + (> n 0)) + (setq node (elib-node-branch node branch)) + (setq n (1- n))) + + (if (eq dummy node) + nil + node))) + + +(defun dll-empty (dll) + + "Return t if the doubly linked list DLL is empty, nil otherwise" + + (eq (elib-node-left (dll-get-dummy-node dll)) + (dll-get-dummy-node dll))) + +(defun dll-length (dll) + + "Returns the number of elements in the doubly linked list DLL." + + (let* ((dummy (dll-get-dummy-node dll)) + (node (elib-node-right dummy)) + (n 0)) + + (while (not (eq node dummy)) + (setq node (elib-node-right node)) + (setq n (1+ n))) + + n)) + + + +(defun dll-copy (dll &optional element-copy-fnc) + + "Return a copy of the doubly linked list DLL. +If optional second argument ELEMENT-COPY-FNC is non-nil it should be +a function that takes one argument, an element, and returns a copy of it. +If ELEMENT-COPY-FNC is not given the elements are not copied." + + (let ((result (dll-create)) + (node (dll-nth dll 0))) + (if element-copy-fnc + + ;; Copy the elements with the user-supplied function. + (while node + (dll-enter-last result + (funcall element-copy-fnc + (dll-element dll node))) + (setq node (dll-next dll node))) + + ;; Don't try to copy the elements - they might be + ;; circular lists, or anything at all... + (while node + (dll-enter-last result (dll-element dll node)) + (setq node (dll-next dll node)))) + + result)) + + + +(defun dll-all (dll) + + "Return all elements on the double linked list DLL as an ordinary list." + + (let* ((result nil) + (dummy (dll-get-dummy-node dll)) + (node (elib-node-left dummy))) + + (while (not (eq node dummy)) + (setq result (cons (dll-element dll node) result)) + (setq node (elib-node-left node))) + + result)) + + +(defun dll-clear (dll) + + "Clear the doubly linked list DLL, i.e. make it completely empty." + + (elib-node-set-left (dll-get-dummy-node dll) (dll-get-dummy-node dll)) + (elib-node-set-right (dll-get-dummy-node dll) (dll-get-dummy-node dll))) + + +(defun dll-map (map-function dll) + + "Apply MAP-FUNCTION to all elements in the doubly linked list DLL. +The function is applied to the first element first." + + (let* ((dummy (dll-get-dummy-node dll)) + (node (elib-node-right dummy))) + + (while (not (eq node dummy)) + (funcall map-function (dll-element dll node)) + (setq node (elib-node-right node))))) + + +(defun dll-map-reverse (map-function dll) + + "Apply MAP-FUNCTION to all elements in the doubly linked list DLL. +The function is applied to the last element first." + + (let* ((dummy (dll-get-dummy-node dll)) + (node (elib-node-left dummy))) + + (while (not (eq node dummy)) + (funcall map-function (dll-element dll node)) + (setq node (elib-node-left node))))) + + +(defun dll-create-from-list (list) + + "Given an elisp LIST create a doubly linked list with the same elements." + + (let ((dll (dll-create))) + (while list + (dll-enter-last dll (car list)) + (setq list (cdr list))) + dll)) + + + +(defun dll-sort (dll predicate) + + "Sort the doubly linked list DLL, stably, comparing elements using PREDICATE. +Returns the sorted list. DLL is modified by side effects. +PREDICATE is called with two elements of DLL, and should return T +if the first element is \"less\" than the second." + + (dll-set-from-node-list + dll (sort (dll-list-nodes dll) + (function (lambda (x1 x2) + (funcall predicate + (dll-element dll x1) + (dll-element dll x2)))))) + dll) + + +(defun dll-filter (dll predicate) + + "Remove all elements in the doubly linked list DLL for which PREDICATE +return nil." + + (let* ((dummy (dll-get-dummy-node dll)) + (node (elib-node-right dummy)) + next) + + (while (not (eq node dummy)) + (setq next (elib-node-right node)) + (if (funcall predicate (dll-element dll node)) + nil + (dll-delete dll node)) + (setq node next)))) diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-node.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-node.el new file mode 100644 index 000000000000..6c476a35ef3d --- /dev/null +++ b/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-node.el @@ -0,0 +1,89 @@ +;;;; elib-node.el,v 1.2 1992/04/07 20:49:16 berliner Exp +;;;; This file implements the nodes used in binary trees and +;;;; doubly linked lists +;;;; +;;;; Copyright (C) 1991 Inge Wallin +;;;; +;;;; This file is part of the GNU Emacs lisp library, Elib. +;;;; +;;;; GNU Elib is free software; you can redistribute it and/or modify +;;;; it under the terms of the GNU General Public License as published by +;;;; the Free Software Foundation; either version 1, or (at your option) +;;;; any later version. +;;;; +;;;; GNU Elib is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;;; GNU General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU General Public License +;;;; along with GNU Emacs; see the file COPYING. If not, write to +;;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;;;; +;;;; Author: Inge Wallin +;;;; + +;;; +;;; A node is implemented as an array with three elements, using +;;; (elt node 0) as the left pointer +;;; (elt node 1) as the right pointer +;;; (elt node 2) as the data +;;; +;;; Some types of trees, e.g. AVL trees, need bigger nodes, but +;;; as long as the first three parts are the left pointer, the +;;; right pointer and the data field, these macros can be used. +;;; + + +(provide 'elib-node) + + +(defmacro elib-node-create (left right data) + "Create a tree node from LEFT, RIGHT and DATA." + (` (vector (, left) (, right) (, data)))) + + +(defmacro elib-node-left (node) + "Return the left pointer of NODE." + (` (aref (, node) 0))) + + +(defmacro elib-node-right (node) + "Return the right pointer of NODE." + (` (aref (, node) 1))) + + +(defmacro elib-node-data (node) + "Return the data of NODE." + (` (aref (, node) 2))) + + +(defmacro elib-node-set-left (node newleft) + "Set the left pointer of NODE to NEWLEFT." + (` (aset (, node) 0 (, newleft)))) + + +(defmacro elib-node-set-right (node newright) + "Set the right pointer of NODE to NEWRIGHT." + (` (aset (, node) 1 (, newright)))) + + +(defmacro elib-node-set-data (node newdata) + "Set the data of NODE to NEWDATA." + (` (aset (, node) 2 (, newdata)))) + + + +(defmacro elib-node-branch (node branch) + "Get value of a branch of a node. +NODE is the node, and BRANCH is the branch. +0 for left pointer, 1 for right pointer and 2 for the data." + (` (aref (, node) (, branch)))) + + +(defmacro elib-node-set-branch (node branch newval) + "Set value of a branch of a node. +NODE is the node, and BRANCH is the branch. +0 for left pointer, 1 for the right pointer and 2 for the data. +NEWVAL is new value of the branch." + (` (aset (, node) (, branch) (, newval)))) diff --git a/gnu/usr.bin/cvs/contrib/rcs-to-cvs b/gnu/usr.bin/cvs/contrib/rcs-to-cvs new file mode 100644 index 000000000000..5863ed87414c --- /dev/null +++ b/gnu/usr.bin/cvs/contrib/rcs-to-cvs @@ -0,0 +1,184 @@ +#!/bin/sh +# +# $Id: rcs-to-cvs,v 1.4 1994/09/21 07:23:16 berliner Exp $ +# Based on the CVS 1.0 checkin csh script. +# Contributed by Per Cederqvist <ceder@signum.se>. +# Rewritten in sh by David MacKenzie <djm@cygnus.com>. +# +# Copyright (c) 1989, Brian Berliner +# +# You may distribute under the terms of the GNU General Public License. +# +############################################################################# +# +# Check in sources that previously were under RCS or no source control system. +# +# The repository is the directory where the sources should be deposited. +# +# Traverses the current directory, ensuring that an +# identical directory structure exists in the repository directory. It +# then checks the files in in the following manner: +# +# 1) If the file doesn't yet exist, check it in as revision 1.1 +# +# The script also is somewhat verbose in letting the user know what is +# going on. It prints a diagnostic when it creates a new file, or updates +# a file that has been modified on the trunk. +# +# Bugs: doesn't put the files in branch 1.1.1 +# doesn't put in release and vendor tags +# +############################################################################# + +usage="Usage: rcs-to-cvs [-v] [-m message] [-f message_file] repository" +vbose=0 +message="" +message_file=/usr/tmp/checkin.$$ +got_one=0 + +if [ $# -lt 1 ]; then + echo "$usage" >&2 + exit 1 +fi + +while [ $# -ne 0 ]; do + case "$1" in + -v) + vbose=1 + ;; + -m) + shift + echo $1 > $message_file + got_one=1 + ;; + -f) + shift + message_file=$1 + got_one=2 + ;; + *) + break + esac + shift +done + +if [ $# -lt 1 ]; then + echo "$usage" >&2 + exit 1 +fi + +repository=$1 +shift + +if [ -z "$CVSROOT" ]; then + echo "Please the environmental variable CVSROOT to the root" >&2 + echo " of the tree you wish to update" >&2 + exit 1 +fi + +if [ $got_one -eq 0 ]; then + echo "Please Edit this file to contain the RCS log information" >$message_file + echo "to be associated with this directory (please remove these lines)">>$message_file + ${EDITOR-/usr/ucb/vi} $message_file + got_one=1 +fi + +umask 22 + +update_dir=${CVSROOT}/${repository} +[ ! -d ${update_dir} ] && mkdir $update_dir + +if [ -d SCCS ]; then + echo SCCS files detected! >&2 + exit 1 +fi +if [ -d RCS ]; then + co RCS/* +fi + +for name in * .[a-zA-Z0-9]* +do + case "$name" in + RCS | \* | .\[a-zA-Z0-9\]\* ) continue ;; + esac + echo $name + if [ $vbose -ne 0 ]; then + echo "Updating ${repository}/${name}" + fi + if [ -d "$name" ]; then + if [ ! -d "${update_dir}/${name}" ]; then + echo "WARNING: Creating new directory ${repository}/${name}" + mkdir "${update_dir}/${name}" + if [ $? -ne 0 ]; then + echo "ERROR: mkdir failed - aborting" >&2 + exit 1 + fi + fi + cd "$name" + if [ $? -ne 0 ]; then + echo "ERROR: Couldn\'t cd to $name - aborting" >&2 + exit 1 + fi + if [ $vbose -ne 0 ]; then + $0 -v -f $message_file "${repository}/${name}" + else + $0 -f $message_file "${repository}/${name}" + fi + if [ $? -ne 0 ]; then + exit 1 + fi + cd .. + else # if not directory + if [ ! -f "$name" ]; then + echo "WARNING: $name is neither a regular file" + echo " nor a directory - ignored" + continue + fi + file="${update_dir}/${name},v" + comment="" + if grep -s '\$Log.*\$' "${name}"; then # If $Log keyword + myext=`echo $name | sed 's,.*\.,,'` + [ "$myext" = "$name" ] && myext= + case "$myext" in + c | csh | e | f | h | l | mac | me | mm | ms | p | r | red | s | sh | sl | cl | ml | el | tex | y | ye | yr | "" ) + ;; + + * ) + echo "For file ${file}:" + grep '\$Log.*\$' "${name}" + echo -n "Please insert a comment leader for file ${name} > " + read comment + ;; + esac + fi + if [ ! -f "$file" ]; then # If not exists in repository + if [ ! -f "${update_dir}/Attic/${name},v" ]; then + echo "WARNING: Creating new file ${repository}/${name}" + if [ -f RCS/"${name}",v ]; then + echo "MSG: Copying old rcs file." + cp RCS/"${name}",v "$file" + else + if [ -n "${comment}" ]; then + rcs -q -i -c"${comment}" -t${message_file} -m'.' "$file" + fi + ci -q -u1.1 -t${message_file} -m'.' "$file" + if [ $? -ne 0 ]; then + echo "ERROR: Initial check-in of $file failed - aborting" >&2 + exit 1 + fi + fi + else + file="${update_dir}/Attic/${name},v" + echo "WARNING: IGNORED: ${repository}/Attic/${name}" + continue + fi + else # File existed + echo "ERROR: File exists in repository: Ignored: $file" + continue + fi + fi +done + +[ $got_one -eq 1 ] && rm -f $message_file + +exit 0 diff --git a/gnu/usr.bin/cvs/contrib/rcs2log b/gnu/usr.bin/cvs/contrib/rcs2log new file mode 100644 index 000000000000..d7900025b851 --- /dev/null +++ b/gnu/usr.bin/cvs/contrib/rcs2log @@ -0,0 +1,326 @@ +#!/bin/sh + +# RCS to ChangeLog generator + +# Generate a change log prefix from RCS/* and the existing ChangeLog (if any). +# Output the new prefix to standard output. +# You can edit this prefix by hand, and then prepend it to ChangeLog. + +# Ignore log entries that start with `#'. +# Clump together log entries that start with `{topic} ', +# where `topic' contains neither white space nor `}'. + +# Author: Paul Eggert <eggert@twinsun.com> + +# OrigId: rcs2log,v 1.9 1993/01/15 05:33:29 eggert Exp + +# Copyright 1992, 1993 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + +# Parse options. + +# defaults +indent=8 # indent of log line +length=79 # suggested max width of log line +tabwidth=8 # width of horizontal tab + +while : +do + case $1 in + -i) indent=${2?};; + -l) length=${2?};; + -t) tabwidth=${2?};; + -*) echo >&2 "$0: usage: $0 [-i indent] [-l length] [-t tabwidth] [file ...]" + exit 1;; + *) break + esac + shift; shift +done + + +# Log into $rlogout the revisions checked in since the first ChangeLog entry. + +date=1970 +if test -s ChangeLog +then + # Add 1 to seconds to avoid duplicating most recent log. + # It's a good thing `rlog' doesn't mind a time ending in `:60'. + e=' + /^... ... [ 0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]+ /{ + printf "%s%02d %s\n", substr($0,1,17), substr($0,18,2)+1, $5 + exit + } + ' + d=`awk "$e" <ChangeLog` || exit + case $d in + ?*) date=$d + esac +fi +datearg="-d>$date" + +rlogout=/tmp/chg$$ +trap exit 1 2 13 15 +trap 'rm -f $rlogout; exit 1' 0 + +case $# in +0) set RCS/* +esac + +rlog "$datearg" "$@" >$rlogout || exit + + +# Get the full name of each author the logs mention, and set initialize_fullname +# to awk code that initializes the `fullname' awk associative array. +# Warning: foreign authors (i.e. not known in the passwd file) are mishandled; +# you have to fix the resulting output by hand. + +initialize_fullname= +authors=` + sed -n 's|^date: *[0-9]*/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]; *author: *\([^; ]*\).*|\1|p' <$rlogout | + sort -u +` +case $authors in +?*) + initialize_author= + for author in $authors + do + initialize_author="$initialize_author + author[\"$author\"] = 1 + " + done + + awkscript=' + BEGIN { + alphabet = "abcdefghijklmnopqrstuvwxyz" + ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + '"$initialize_author"' + } + { + if (author[$1]) { + fullname = $5 + abbr = index(fullname, "&") + if (abbr) { + a = substr($1, 1, 1) + A = a + i = index(alphabet, a) + if (i) A = substr(ALPHABET, i, 1) + fullname = substr(fullname, 1, abbr-1) A substr($1, 2) substr(fullname, abbr+1) + } + printf "fullname[\"%s\"] = \"%s\"\n", $1, fullname + author[$1] = 0 + } + } + ' + + initialize_fullname=` + (cat /etc/passwd; ypmatch $authors passwd) 2>/dev/null | + awk -F: "$awkscript" + ` +esac + + +# Function to print a single log line. +# We don't use awk functions, to stay compatible with old awk versions. +# `Log' is the log message (with \n replaced by \r). +# `files' contains the affected files. +printlogline='{ + + # Following the GNU coding standards, rewrite + # * file: (function): comment + # to + # * file (function): comment + if (Log ~ /^\([^)]*\): /) { + i = index(Log, ")") + files = files " " substr(Log, 1, i) + Log = substr(Log, i+3) + } + + # If "label: comment" is too long, break the line after the ":". + sep = " " + if ('"$length"' <= '"$indent"' + 1 + length(files) + index(Log, "\r")) sep = "\n" indent_string + + # Print the label. + printf "%s*%s:", indent_string, files + + # Print each line of the log, transliterating \r to \n. + while ((i = index(Log, "\r")) != 0) { + printf "%s%s\n", sep, substr(Log, 1, i-1) + sep = indent_string + Log = substr(Log, i+1) + } +}' + +hostname=`( + hostname || cat /etc/whoami || uuname -l || uname -n +) 2>/dev/null` || { + echo >&2 "$0: cannot deduce hostname" + exit 1 +} + + +# Process the rlog output, generating ChangeLog style entries. + +# First, reformat the rlog output so that each line contains one log entry. +# Transliterate \n to \r so that multiline entries fit on a single line. +# Discard irrelevant rlog output. +awk <$rlogout ' + /^Working file:/ { filename = $3 } + /^date: /, /^(-----------*|===========*)$/ { + if ($0 ~ /^branches: /) { next } + if ($0 ~ /^date: [0-9][ /0-9:]*;/) { + time = substr($3, 1, length($3)-1) + author = substr($5, 1, length($5)-1) + printf "%s %s %s %s \r", filename, $2, time, author + next + } + if ($0 ~ /^(-----------*|===========*)$/) { print ""; next } + printf "%s\r", $0 + } +' | + +# Now each line is of the form +# FILENAME YYYY/MM/DD HH:MM:SS AUTHOR \rLOG +# where \r stands for a carriage return, +# and each line of the log is terminated by \r instead of \n. +# Sort the log entries, first by date+time (in reverse order), +# then by author, then by log entry, and finally by file name (just in case). +sort +1 -3r +3 +0 | + +# Finally, reformat the sorted log entries. +awk ' + BEGIN { + + # Initialize the fullname associative array. + '"$initialize_fullname"' + + # Initialize indent string. + indent_string = "" + i = '"$indent"' + if (0 < '"$tabwidth"') + for (; '"$tabwidth"' <= i; i -= '"$tabwidth"') + indent_string = indent_string "\t" + while (1 <= i--) + indent_string = indent_string " " + + # Set up date conversion tables. + # RCS uses a nice, clean, sortable format, + # but ChangeLog wants the traditional, ugly ctime format. + + # January 1, 0 AD (Gregorian) was Saturday = 6 + EPOCH_WEEKDAY = 6 + # Of course, there was no 0 AD, but the algorithm works anyway. + + w[0]="Sun"; w[1]="Mon"; w[2]="Tue"; w[3]="Wed" + w[4]="Thu"; w[5]="Fri"; w[6]="Sat" + + m[0]="Jan"; m[1]="Feb"; m[2]="Mar" + m[3]="Apr"; m[4]="May"; m[5]="Jun" + m[6]="Jul"; m[7]="Aug"; m[8]="Sep" + m[9]="Oct"; m[10]="Nov"; m[11]="Dec" + + # days in non-leap year thus far, indexed by month (0-12) + mo[0]=0; mo[1]=31; mo[2]=59; mo[3]=90 + mo[4]=120; mo[5]=151; mo[6]=181; mo[7]=212 + mo[8]=243; mo[9]=273; mo[10]=304; mo[11]=334 + mo[12]=365 + } + + { + newlog = substr($0, 1 + index($0, "\r")) + + # Ignore log entries prefixed by "#". + if (newlog ~ /^#/) { next } + + if (Log != newlog || date != $2 || author != $4) { + + # The previous log and this log differ. + + # Print the old log. + if (date != "") '"$printlogline"' + + # Logs that begin with "{clumpname} " should be grouped together, + # and the clumpname should be removed. + # Extract the new clumpname from the log header, + # and use it to decide whether to output a blank line. + newclumpname = "" + sep = "\n" + if (date == "") sep = "" + if (newlog ~ /^{[^ }]*}[ ]/) { + i = index(newlog, "}") + newclumpname = substr(newlog, 1, i) + while (substr(newlog, i+1) ~ /^[ ]/) i++ + newlog = substr(newlog, i+1) + if (clumpname == newclumpname) sep = "" + } + printf sep + clumpname = newclumpname + + # Get ready for the next log. + Log = newlog + if (files != "") + for (i in filesknown) + filesknown[i] = 0 + files = "" + } + if (date != $2 || author != $4) { + # The previous date+author and this date+author differ. + # Print the new one. + date = $2 + author = $4 + + # Convert nice RCS date like "1992/01/03 00:03:44" + # into ugly ctime date like "Fri Jan 3 00:03:44 1992". + # Calculate day of week from Gregorian calendar. + i = index($2, "/") + year = substr($2, 1, i-1) + 0 + monthday = substr($2, i+1) + i = index(monthday, "/") + month = substr(monthday, 1, i-1) + 0 + day = substr(monthday, i+1) + 0 + leap = 0 + if (2 < month && year%4 == 0 && (year%100 != 0 || year%400 == 0)) leap = 1 + days_since_Sunday_before_epoch = EPOCH_WEEKDAY + year * 365 + int((year + 3) / 4) - int((year + 99) / 100) + int((year + 399) / 400) + mo[month-1] + leap + day - 1 + + # Print "date fullname (email address)" if the fullname is known; + # print "date author" otherwise. + # Get the fullname from the associative array. + # The email address is just author@thishostname. + printf "%s %s %2d %s %d ", w[days_since_Sunday_before_epoch%7], m[month-1], day, $3, year + if (fullname[author]) + printf "%s (%s@%s)\n\n", fullname[author], author, "'"$hostname"'" + else + printf "%s\n\n", author + } + if (! filesknown[$1]) { + filesknown[$1] = 1 + if (files == "") files = " " $1 + else files = files ", " $1 + } + } + END { + # Print the last log. + if (date != "") { + '"$printlogline"' + printf "\n" + } + } +' && + + +# Exit successfully. + +exec rm -f $rlogout diff --git a/gnu/usr.bin/cvs/contrib/rcs2sccs b/gnu/usr.bin/cvs/contrib/rcs2sccs new file mode 100644 index 000000000000..054ac6c1eca9 --- /dev/null +++ b/gnu/usr.bin/cvs/contrib/rcs2sccs @@ -0,0 +1,143 @@ +#!/bin/sh +# +# +# OrigId: rcs2sccs,v 1.12 90/10/04 20:52:23 kenc Exp Locker: kenc +# $Id: rcs2sccs,v 1.1 1993/12/06 06:37:14 berliner Exp $ + +############################################################ +# Error checking +# +if [ ! -d SCCS ] ; then + mkdir SCCS +fi + +logfile=/tmp/rcs2sccs_$$_log +rm -f $logfile +tmpfile=/tmp/rcs2sccs_$$_tmp +rm -f $tmpfile +emptyfile=/tmp/rcs2sccs_$$_empty +echo -n "" > $emptyfile +initialfile=/tmp/rcs2sccs_$$_init +echo "Initial revision" > $initialfile +sedfile=/tmp/rcs2sccs_$$_sed +rm -f $sedfile +revfile=/tmp/rcs2sccs_$$_rev +rm -f $revfile +commentfile=/tmp/rcs2sccs_$$_comment +rm -f $commentfile + +# create the sed script +cat > $sedfile << EOF +s,;Id;,%Z%%M% %I% %E%,g +s,;SunId;,%Z%%M% %I% %E%,g +s,;RCSfile;,%M%,g +s,;Revision;,%I%,g +s,;Date;,%E%,g +s,;Id:.*;,%Z%%M% %I% %E%,g +s,;SunId:.*;,%Z%%M% %I% %E%,g +s,;RCSfile:.*;,%M%,g +s,;Revision:.*;,%I%,g +s,;Date:.*;,%E%,g +EOF +sed -e 's/;/\\$/g' $sedfile > $tmpfile +cp $tmpfile $sedfile +############################################################ +# Loop over every RCS file in RCS dir +# +for vfile in *,v; do + # get rid of the ",v" at the end of the name + file=`echo $vfile | sed -e 's/,v$//'` + + # work on each rev of that file in ascending order + firsttime=1 + rlog $file | grep "^revision [0-9][0-9]*\." | awk '{print $2}' | sed -e 's/\./ /g' | sort -n -u +0 +1 +2 +3 +4 +5 +6 +7 +8 | sed -e 's/ /./g' > $revfile + for rev in `cat $revfile`; do + if [ $? != 0 ]; then + echo ERROR - revision + exit + fi + # get file into current dir and get stats + date=`rlog -r$rev $file | grep "^date: " | awk '{print $2; exit}' | sed -e 's/^19//'` + time=`rlog -r$rev $file | grep "^date: " | awk '{print $3; exit}' | sed -e 's/;//'` + author=`rlog -r$rev $file | grep "^date: " | awk '{print $5; exit}' | sed -e 's/;//'` + date="$date $time" + echo "" + rlog -r$rev $file | sed -e '/^branches: /d' -e '1,/^date: /d' -e '/^===========/d' -e 's/$/\\/' | awk '{if ((total += length($0) + 1) < 510) print $0}' > $commentfile + echo "==> file $file, rev=$rev, date=$date, author=$author" + rm -f $file + co -r$rev $file >> $logfile 2>&1 + if [ $? != 0 ]; then + echo ERROR - co + exit + fi + echo checked out of RCS + + # add SCCS keywords in place of RCS keywords + sed -f $sedfile $file > $tmpfile + if [ $? != 0 ]; then + echo ERROR - sed + exit + fi + echo performed keyword substitutions + rm -f $file + cp $tmpfile $file + + # check file into SCCS + if [ "$firsttime" = "1" ]; then + firsttime=0 + echo about to do sccs admin + echo sccs admin -n -i$file $file < $commentfile + sccs admin -n -i$file $file < $commentfile >> $logfile 2>&1 + if [ $? != 0 ]; then + echo ERROR - sccs admin + exit + fi + echo initial rev checked into SCCS + else + case $rev in + *.*.*.*) + brev=`echo $rev | sed -e 's/\.[0-9]*$//'` + sccs admin -fb $file 2>>$logfile + echo sccs get -e -p -r$brev $file + sccs get -e -p -r$brev $file >/dev/null 2>>$logfile + ;; + *) + echo sccs get -e -p $file + sccs get -e -p $file >/dev/null 2>> $logfile + ;; + esac + if [ $? != 0 ]; then + echo ERROR - sccs get + exit + fi + sccs delta $file < $commentfile >> $logfile 2>&1 + if [ $? != 0 ]; then + echo ERROR - sccs delta -r$rev $file + exit + fi + echo checked into SCCS + fi + sed -e "s;^d D $rev ../../.. ..:..:.. [^ ][^ ]*;d D $rev $date $author;" SCCS/s.$file > $tmpfile + rm -f SCCS/s.$file + cp $tmpfile SCCS/s.$file + chmod 444 SCCS/s.$file + sccs admin -z $file + if [ $? != 0 ]; then + echo ERROR - sccs admin -z + exit + fi + done + rm -f $file +done + + +############################################################ +# Clean up +# +echo cleaning up... +rm -f $tmpfile $emptyfile $initialfile $sedfile $commentfile +echo =================================================== +echo " Conversion Completed Successfully" +echo =================================================== + +rm -f *,v diff --git a/gnu/usr.bin/cvs/contrib/sccs2rcs b/gnu/usr.bin/cvs/contrib/sccs2rcs new file mode 100644 index 000000000000..654024bf3fc3 --- /dev/null +++ b/gnu/usr.bin/cvs/contrib/sccs2rcs @@ -0,0 +1,277 @@ +#!/bin/csh -f +# +# Sccs2rcs is a script to convert an existing SCCS +# history into an RCS history without losing any of +# the information contained therein. +# It has been tested under the following OS's: +# SunOS 3.5, 4.0.3, 4.1 +# Ultrix-32 2.0, 3.1 +# +# Things to note: +# + It will NOT delete or alter your ./SCCS history under any circumstances. +# +# + Run in a directory where ./SCCS exists and where you can +# create ./RCS +# +# + /usr/local/bin is put in front of the default path. +# (SCCS under Ultrix is set-uid sccs, bad bad bad, so +# /usr/local/bin/sccs here fixes that) +# +# + Date, time, author, comments, branches, are all preserved. +# +# + If a command fails somewhere in the middle, it bombs with +# a message -- remove what it's done so far and try again. +# "rm -rf RCS; sccs unedit `sccs tell`; sccs clean" +# There is no recovery and exit is far from graceful. +# If a particular module is hanging you up, consider +# doing it separately; move it from the current area so that +# the next run will have a better chance or working. +# Also (for the brave only) you might consider hacking +# the s-file for simpler problems: I've successfully changed +# the date of a delta to be in sync, then run "sccs admin -z" +# on the thing. +# +# + After everything finishes, ./SCCS will be moved to ./old-SCCS. +# +# This file may be copied, processed, hacked, mutilated, and +# even destroyed as long as you don't tell anyone you wrote it. +# +# Ken Cox +# Viewlogic Systems, Inc. +# kenstir@viewlogic.com +# ...!harvard!cg-atla!viewlog!kenstir +# +# Various hacks made by Brian Berliner before inclusion in CVS contrib area. +# +# $Id: sccs2rcs,v 1.1 1992/04/10 03:04:26 berliner Exp $ + + +#we'll assume the user set up the path correctly +# for the Pmax, /usr/ucb/sccs is suid sccs, what a pain +# /usr/local/bin/sccs should override /usr/ucb/sccs there +set path = (/usr/local/bin $path) + + +############################################################ +# Error checking +# +if (! -w .) then + echo "Error: ./ not writeable by you." + exit 1 +endif +if (! -d SCCS) then + echo "Error: ./SCCS directory not found." + exit 1 +endif +set edits = (`sccs tell`) +if ($#edits) then + echo "Error: $#edits file(s) out for edit...clean up before converting." + exit 1 +endif +if (-d RCS) then + echo "Warning: RCS directory exists" + if (`ls -a RCS | wc -l` > 2) then + echo "Error: RCS directory not empty + exit 1 + endif +else + mkdir RCS +endif + +sccs clean + +set logfile = /tmp/sccs2rcs_$$_log +rm -f $logfile +set tmpfile = /tmp/sccs2rcs_$$_tmp +rm -f $tmpfile +set emptyfile = /tmp/sccs2rcs_$$_empty +echo -n "" > $emptyfile +set initialfile = /tmp/sccs2rcs_$$_init +echo "Initial revision" > $initialfile +set sedfile = /tmp/sccs2rcs_$$_sed +rm -f $sedfile +set revfile = /tmp/sccs2rcs_$$_rev +rm -f $revfile + +# the quotes surround the dollar signs to fool RCS when I check in this script +set sccs_keywords = (\ + '%W%[ ]*%G%'\ + '%W%[ ]*%E%'\ + '%W%'\ + '%Z%%M%[ ]*%I%[ ]*%G%'\ + '%Z%%M%[ ]*%I%[ ]*%E%'\ + '%M%[ ]*%I%[ ]*%G%'\ + '%M%[ ]*%I%[ ]*%E%'\ + '%M%'\ + '%I%'\ + '%G%'\ + '%E%'\ + '%U%') +set rcs_keywords = (\ + '$'Id'$'\ + '$'Id'$'\ + '$'Id'$'\ + '$'SunId'$'\ + '$'SunId'$'\ + '$'Id'$'\ + '$'Id'$'\ + '$'RCSfile'$'\ + '$'Revision'$'\ + '$'Date'$'\ + '$'Date'$'\ + '') + + +############################################################ +# Get some answers from user +# +echo "" +echo "Do you want to be prompted for a description of each" +echo "file as it is checked in to RCS initially?" +echo -n "(y=prompt for description, n=null description) [y] ?" +set ans = $< +if ((_$ans == _) || (_$ans == _y) || (_$ans == _Y)) then + set nodesc = 0 +else + set nodesc = 1 +endif +echo "" +echo "The default keyword substitutions are as follows and are" +echo "applied in the order specified:" +set i = 1 +while ($i <= $#sccs_keywords) +# echo ' '\"$sccs_keywords[$i]\"' ==> '\"$rcs_keywords[$i]\" + echo " $sccs_keywords[$i] ==> $rcs_keywords[$i]" + @ i = $i + 1 +end +echo "" +echo -n "Do you want to change them [n] ?" +set ans = $< +if ((_$ans != _) && (_$ans != _n) && (_$ans != _N)) then + echo "You can't always get what you want." + echo "Edit this script file and change the variables:" + echo ' $sccs_keywords' + echo ' $rcs_keywords' +else + echo "good idea." +endif + +# create the sed script +set i = 1 +while ($i <= $#sccs_keywords) + echo "s,$sccs_keywords[$i],$rcs_keywords[$i],g" >> $sedfile + @ i = $i + 1 +end + +onintr ERROR + +############################################################ +# Loop over every s-file in SCCS dir +# +foreach sfile (SCCS/s.*) + # get rid of the "s." at the beginning of the name + set file = `echo $sfile:t | sed -e "s/^..//"` + + # work on each rev of that file in ascending order + set firsttime = 1 + sccs prs $file | grep "^D " | awk '{print $2}' | sed -e 's/\./ /g' | sort -n -u +0 +1 +2 +3 +4 +5 +6 +7 +8 | sed -e 's/ /./g' > $revfile + foreach rev (`cat $revfile`) + if ($status != 0) goto ERROR + + # get file into current dir and get stats + set date = `sccs prs -r$rev $file | grep "^D " | awk '{printf("19%s %s", $3, $4); exit}'` + set author = `sccs prs -r$rev $file | grep "^D " | awk '{print $5; exit}'` + echo "" + echo "==> file $file, rev=$rev, date=$date, author=$author" + sccs edit -r$rev $file >>& $logfile + if ($status != 0) goto ERROR + echo checked out of SCCS + + # add RCS keywords in place of SCCS keywords + sed -f $sedfile $file > $tmpfile + if ($status != 0) goto ERROR + echo performed keyword substitutions + cp $tmpfile $file + + # check file into RCS + if ($firsttime) then + set firsttime = 0 + if ($nodesc) then + echo about to do ci + echo ci -f -r$rev -d"$date" -w$author -t$emptyfile $file + ci -f -r$rev -d"$date" -w$author -t$emptyfile $file < $initialfile >>& $logfile + if ($status != 0) goto ERROR + echo initial rev checked into RCS without description + else + echo "" + echo Enter a brief description of the file $file \(end w/ Ctrl-D\): + cat > $tmpfile + ci -f -r$rev -d"$date" -w$author -t$tmpfile $file < $initialfile >>& $logfile + if ($status != 0) goto ERROR + echo initial rev checked into RCS + endif + else + # get RCS lock + set lckrev = `echo $rev | sed -e 's/\.[0-9]*$//'` + if ("$lckrev" =~ [0-9]*.*) then + # need to lock the brach -- it is OK if the lock fails + rcs -l$lckrev $file >>& $logfile + else + # need to lock the trunk -- must succeed + rcs -l $file >>& $logfile + if ($status != 0) goto ERROR + endif + echo got lock + sccs prs -r$rev $file | grep "." > $tmpfile + # it's OK if grep fails here and gives status == 1 + # put the delta message in $tmpfile + ed $tmpfile >>& $logfile <<EOF +/COMMENTS +1,.d +w +q +EOF + ci -f -r$rev -d"$date" -w$author $file < $tmpfile >>& $logfile + if ($status != 0) goto ERROR + echo checked into RCS + endif + sccs unedit $file >>& $logfile + if ($status != 0) goto ERROR + end + rm -f $file +end + + +############################################################ +# Clean up +# +echo cleaning up... +mv SCCS old-SCCS +rm -f $tmpfile $emptyfile $initialfile $sedfile +echo =================================================== +echo " Conversion Completed Successfully" +echo "" +echo " SCCS history now in old-SCCS/" +echo =================================================== +set exitval = 0 +goto cleanup + +ERROR: +foreach f (`sccs tell`) + sccs unedit $f +end +echo "" +echo "" +echo Danger\! Danger\! +echo Some command exited with a non-zero exit status. +echo Log file exists in $logfile. +echo "" +echo Incomplete history in ./RCS -- remove it +echo Original unchanged history in ./SCCS +set exitval = 1 + +cleanup: +# leave log file +rm -f $tmpfile $emptyfile $initialfile $sedfile $revfile + +exit $exitval diff --git a/gnu/usr.bin/cvs/cvs/cvsbug.sh b/gnu/usr.bin/cvs/cvs/cvsbug.sh new file mode 100644 index 000000000000..8c6a5bbd36b1 --- /dev/null +++ b/gnu/usr.bin/cvs/cvs/cvsbug.sh @@ -0,0 +1,533 @@ +#!/bin/sh +# Submit a problem report to a GNATS site. +# Copyright (C) 1993 Free Software Foundation, Inc. +# Contributed by Brendan Kehoe (brendan@cygnus.com), based on a +# version written by Heinz G. Seidl (hgs@ide.com). +# +# This file is part of GNU GNATS. +# Modified by Berliner for CVS. +# $CVSid: @(#)cvsbug.sh 1.2 94/10/22 $ +# +# GNU GNATS is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# GNU GNATS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU GNATS; see the file COPYING. If not, write to +# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +# The version of this send-pr. +VERSION=3.2 + +# The submitter-id for your site. +SUBMITTER=net + +## # Where the GNATS directory lives, if at all. +## [ -z "$GNATS_ROOT" ] && +## GNATS_ROOT=/usr/local/lib/gnats/gnats-db + +# The default mail address for PR submissions. +GNATS_ADDR=bug-cvs@prep.ai.mit.edu + +## # Where the gnats category tree lives. +## DATADIR=/usr/local/lib + +## # If we've been moved around, try using GCC_EXEC_PREFIX. +## [ ! -d $DATADIR/gnats -a -d "$GCC_EXEC_PREFIX" ] && DATADIR=${GCC_EXEC_PREFIX}.. + +# The default release for this host. +DEFAULT_RELEASE="cvs-1.4A2" + +# The default organization. +DEFAULT_ORGANIZATION="net" + +## # The default site to look for. +## GNATS_SITE=unknown + +## # Newer config information? +## [ -f ${GNATS_ROOT}/gnats-adm/config ] && . ${GNATS_ROOT}/gnats-adm/config + +# What mailer to use. This must come after the config file, since it is +# host-dependent. +MAIL_AGENT="/usr/lib/sendmail -oi -t" +MAILER=`echo $MAIL_AGENT | sed -e 's, .*,,'` +if [ ! -f "$MAILER" ] ; then + echo "$COMMAND: Cannot file mail program \"$MAILER\"." + echo "$COMMAND: Please fix the MAIL_AGENT entry in the $COMMAND file." + exit 1 +fi + +if test "`echo -n foo`" = foo ; then + ECHON=bsd +elif test "`echo 'foo\c'`" = foo ; then + ECHON=sysv +else + ECHON=none +fi + +if [ $ECHON = bsd ] ; then + ECHON1="echo -n" + ECHON2= +elif [ $ECHON = sysv ] ; then + ECHON1=echo + ECHON2='\c' +else + ECHON1=echo + ECHON2= +fi + +# + +[ -z "$TMPDIR" ] && TMPDIR=/tmp + +TEMP=$TMPDIR/p$$ +BAD=$TMPDIR/pbad$$ +REF=$TMPDIR/pf$$ + +if [ -z "$LOGNAME" -a -n "$USER" ]; then + LOGNAME=$USER +fi + +FROM="$LOGNAME" +REPLY_TO="$LOGNAME" + +# Find out the name of the originator of this PR. +if [ -n "$NAME" ]; then + ORIGINATOR="$NAME" +elif [ -f $HOME/.fullname ]; then + ORIGINATOR="`sed -e '1q' $HOME/.fullname`" +elif [ -f /bin/domainname ]; then + if [ "`/bin/domainname`" != "" -a -f /usr/bin/ypcat ]; then + # Must use temp file due to incompatibilities in quoting behavior + # and to protect shell metacharacters in the expansion of $LOGNAME + /usr/bin/ypcat passwd 2>/dev/null | cat - /etc/passwd | grep "^$LOGNAME:" | + cut -f5 -d':' | sed -e 's/,.*//' > $TEMP + ORIGINATOR="`cat $TEMP`" + rm -f $TEMP + fi +fi + +if [ "$ORIGINATOR" = "" ]; then + grep "^$LOGNAME:" /etc/passwd | cut -f5 -d':' | sed -e 's/,.*//' > $TEMP + ORIGINATOR="`cat $TEMP`" + rm -f $TEMP +fi + +if [ -n "$ORGANIZATION" ]; then + if [ -f "$ORGANIZATION" ]; then + ORGANIZATION="`cat $ORGANIZATION`" + fi +else + if [ -n "$DEFAULT_ORGANIZATION" ]; then + ORGANIZATION="$DEFAULT_ORGANIZATION" + elif [ -f $HOME/.organization ]; then + ORGANIZATION="`cat $HOME/.organization`" + elif [ -f $HOME/.signature ]; then + ORGANIZATION="`cat $HOME/.signature`" + fi +fi + +# If they don't have a preferred editor set, then use +if [ -z "$VISUAL" ]; then + if [ -z "$EDITOR" ]; then + EDIT=vi + else + EDIT="$EDITOR" + fi +else + EDIT="$VISUAL" +fi + +# Find out some information. +SYSTEM=`( [ -f /bin/uname ] && /bin/uname -a ) || \ + ( [ -f /usr/bin/uname ] && /usr/bin/uname -a ) || echo ""` +ARCH=`[ -f /bin/arch ] && /bin/arch` +MACHINE=`[ -f /bin/machine ] && /bin/machine` + +COMMAND=`echo $0 | sed -e 's,.*/,,'` +## USAGE="Usage: $COMMAND [-PVL] [-t address] [-f filename] [--request-id] +USAGE="Usage: $COMMAND [-PVL] +[--version]" +REMOVE= +BATCH= + +while [ $# -gt 0 ]; do + case "$1" in + -r) ;; # Ignore for backward compat. +## -t | --to) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi +## shift ; GNATS_ADDR="$1" +## EXPLICIT_GNATS_ADDR=true +## ;; +## -f | --file) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi +## shift ; IN_FILE="$1" +## if [ "$IN_FILE" != "-" -a ! -r "$IN_FILE" ]; then +## echo "$COMMAND: cannot read $IN_FILE" +## exit 1 +## fi +## ;; + -b | --batch) BATCH=true ;; + -p | -P | --print) PRINT=true ;; + -L | --list) FORMAT=norm ;; + -l | -CL | --lisp) FORMAT=lisp ;; +## --request-id) REQUEST_ID=true ;; + -h | --help) echo "$USAGE"; exit 0 ;; + -V | --version) echo "$VERSION"; exit 0 ;; + -*) echo "$USAGE" ; exit 1 ;; + *) echo "$USAGE" ; exit 1 +## if [ -z "$USER_GNATS_SITE" ]; then +## if [ ! -r "$DATADIR/gnats/$1" ]; then +## echo "$COMMAND: the GNATS site $1 does not have a categories list." +## exit 1 +## else +## # The site name is the alias they'll have to have created. +## USER_GNATS_SITE=$1 +## fi +## else +## echo "$USAGE" ; exit 1 +## fi + ;; + esac + shift +done + +if [ -n "$USER_GNATS_SITE" ]; then + GNATS_SITE=$USER_GNATS_SITE + GNATS_ADDR=$USER_GNATS_SITE-gnats +fi + +if [ "$SUBMITTER" = "unknown" -a -z "$REQUEST_ID" -a -z "$IN_FILE" ]; then + cat << '__EOF__' +It seems that send-pr is not installed with your unique submitter-id. +You need to run + + install-sid YOUR-SID + +where YOUR-SID is the identification code you received with `send-pr'. +`send-pr' will automatically insert this value into the template field +`>Submitter-Id'. If you've downloaded `send-pr' from the Net, use `net' +for this value. If you do not know your id, run `send-pr --request-id' to +get one from your support site. +__EOF__ + exit 1 +fi + +## if [ -r "$DATADIR/gnats/$GNATS_SITE" ]; then +## CATEGORIES=`grep -v '^#' $DATADIR/gnats/$GNATS_SITE | sort` +## else +## echo "$COMMAND: could not read $DATADIR/gnats/$GNATS_SITE for categories list." +## exit 1 +## fi +CATEGORIES="contrib cvs doc pcl-cvs portability" + +if [ -z "$CATEGORIES" ]; then + echo "$COMMAND: the categories list for $GNATS_SITE was empty!" + exit 1 +fi + +case "$FORMAT" in + lisp) echo "$CATEGORIES" | \ + awk 'BEGIN {printf "( "} {printf "(\"%s\") ",$0} END {printf ")\n"}' + exit 0 + ;; + norm) l=`echo "$CATEGORIES" | \ + awk 'BEGIN {max = 0; } { if (length($0) > max) { max = length($0); } } + END {print max + 1;}'` + c=`expr 70 / $l` + if [ $c -eq 0 ]; then c=1; fi + echo "$CATEGORIES" | \ + awk 'BEGIN {print "Known categories:"; i = 0 } + { printf ("%-'$l'.'$l's", $0); if ((++i % '$c') == 0) { print "" } } + END { print ""; }' + exit 0 + ;; +esac + +ORIGINATOR_C='<name of the PR author (one line)>' +ORGANIZATION_C='<organization of PR author (multiple lines)>' +CONFIDENTIAL_C='<[ yes | no ] (one line)>' +SYNOPSIS_C='<synopsis of the problem (one line)>' +SEVERITY_C='<[ non-critical | serious | critical ] (one line)>' +PRIORITY_C='<[ low | medium | high ] (one line)>' +CATEGORY_C='<name of the product (one line)>' +CLASS_C='<[ sw-bug | doc-bug | change-request | support ] (one line)>' +RELEASE_C='<release number or tag (one line)>' +ENVIRONMENT_C='<machine, os, target, libraries (multiple lines)>' +DESCRIPTION_C='<precise description of the problem (multiple lines)>' +HOW_TO_REPEAT_C='<code/input/activities to reproduce the problem (multiple lines)>' +FIX_C='<how to correct or work around the problem, if known (multiple lines)>' + +# Catch some signals. ($xs kludge needed by Sun /bin/sh) +xs=0 +trap 'rm -f $REF $TEMP; exit $xs' 0 +trap 'echo "$COMMAND: Aborting ..."; rm -f $REF $TEMP; xs=1; exit' 1 2 3 13 15 + +# If they told us to use a specific file, then do so. +if [ -n "$IN_FILE" ]; then + if [ "$IN_FILE" = "-" ]; then + # The PR is coming from the standard input. + if [ -n "$EXPLICIT_GNATS_ADDR" ]; then + sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" > $TEMP + else + cat > $TEMP + fi + else + # Use the file they named. + if [ -n "$EXPLICIT_GNATS_ADDR" ]; then + sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" $IN_FILE > $TEMP + else + cat $IN_FILE > $TEMP + fi + fi +else + + if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then + # If their PR_FORM points to a bogus entry, then bail. + if [ ! -f "$PR_FORM" -o ! -r "$PR_FORM" -o ! -s "$PR_FORM" ]; then + echo "$COMMAND: can't seem to read your template file (\`$PR_FORM'), ignoring PR_FORM" + sleep 1 + PRINT_INTERN=bad_prform + fi + fi + + if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then + cp $PR_FORM $TEMP || + ( echo "$COMMAND: could not copy $PR_FORM" ; xs=1; exit ) + else + for file in $TEMP $REF ; do + cat > $file << '__EOF__' +SEND-PR: -*- send-pr -*- +SEND-PR: Lines starting with `SEND-PR' will be removed automatically, as +SEND-PR: will all comments (text enclosed in `<' and `>'). +SEND-PR: +SEND-PR: Choose from the following categories: +SEND-PR: +__EOF__ + + # Format the categories so they fit onto lines. + l=`echo "$CATEGORIES" | \ + awk 'BEGIN {max = 0; } { if (length($0) > max) { max = length($0); } } + END {print max + 1;}'` + c=`expr 61 / $l` + if [ $c -eq 0 ]; then c=1; fi + echo "$CATEGORIES" | \ + awk 'BEGIN {printf "SEND-PR: "; i = 0 } + { printf ("%-'$l'.'$l's", $0); + if ((++i % '$c') == 0) { printf "\nSEND-PR: " } } + END { printf "\nSEND-PR:\n"; }' >> $file + + cat >> $file << __EOF__ +To: $GNATS_ADDR +Subject: +From: $FROM +Reply-To: $REPLY_TO +X-send-pr-version: $VERSION + + +>Submitter-Id: $SUBMITTER +>Originator: $ORIGINATOR +>Organization: +` + if [ -n "$ORGANIZATION" ]; then + echo "$ORGANIZATION" + else + echo " $ORGANIZATION_C" ; + fi ; +` +>Confidential: $CONFIDENTIAL_C +>Synopsis: $SYNOPSIS_C +>Severity: $SEVERITY_C +>Priority: $PRIORITY_C +>Category: $CATEGORY_C +>Class: $CLASS_C +>Release: `if [ -n "$DEFAULT_RELEASE" ]; then + echo "$DEFAULT_RELEASE" + else + echo " $RELEASE_C" + fi; ` +>Environment: + $ENVIRONMENT_C +`[ -n "$SYSTEM" ] && echo System: $SYSTEM` +`[ -n "$ARCH" ] && echo Architecture: $ARCH` +`[ -n "$MACHINE" ] && echo Machine: $MACHINE` +>Description: + $DESCRIPTION_C +>How-To-Repeat: + $HOW_TO_REPEAT_C +>Fix: + $FIX_C +__EOF__ + done + fi + + if [ "$PRINT" = true -o "$PRINT_INTERN" = true ]; then + cat $TEMP + xs=0; exit + fi + + chmod u+w $TEMP + if [ -z "$REQUEST_ID" ]; then + eval $EDIT $TEMP + else + ed -s $TEMP << '__EOF__' +/^Subject/s/^Subject:.*/Subject: request for a customer id/ +/^>Category/s/^>Category:.*/>Category: send-pr/ +w +q +__EOF__ + fi + + if cmp -s $REF $TEMP ; then + echo "$COMMAND: problem report not filled out, therefore not sent" + xs=1; exit + fi +fi + +# +# Check the enumeration fields + +# This is a "sed-subroutine" with one keyword parameter +# (with workaround for Sun sed bug) +# +SED_CMD=' +/$PATTERN/{ +s||| +s|<.*>|| +s|^[ ]*|| +s|[ ]*$|| +p +q +}' + + +while [ -z "$REQUEST_ID" ]; do + CNT=0 + + # 1) Confidential + # + PATTERN=">Confidential:" + CONFIDENTIAL=`eval sed -n -e "\"$SED_CMD\"" $TEMP` + case "$CONFIDENTIAL" in + ""|yes|no) CNT=`expr $CNT + 1` ;; + *) echo "$COMMAND: \`$CONFIDENTIAL' is not a valid value for \`Confidential'." ;; + esac + # + # 2) Severity + # + PATTERN=">Severity:" + SEVERITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP` + case "$SEVERITY" in + ""|non-critical|serious|critical) CNT=`expr $CNT + 1` ;; + *) echo "$COMMAND: \`$SEVERITY' is not a valid value for \`Severity'." + esac + # + # 3) Priority + # + PATTERN=">Priority:" + PRIORITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP` + case "$PRIORITY" in + ""|low|medium|high) CNT=`expr $CNT + 1` ;; + *) echo "$COMMAND: \`$PRIORITY' is not a valid value for \`Priority'." + esac + # + # 4) Category + # + PATTERN=">Category:" + CATEGORY=`eval sed -n -e "\"$SED_CMD\"" $TEMP` + FOUND= + for C in $CATEGORIES + do + if [ "$C" = "$CATEGORY" ]; then FOUND=true ; break ; fi + done + if [ -n "$FOUND" ]; then + CNT=`expr $CNT + 1` + else + if [ -z "$CATEGORY" ]; then + echo "$COMMAND: you must include a Category: field in your report." + else + echo "$COMMAND: \`$CATEGORY' is not a known category." + fi + fi + # + # 5) Class + # + PATTERN=">Class:" + CLASS=`eval sed -n -e "\"$SED_CMD\"" $TEMP` + case "$CLASS" in + ""|sw-bug|doc-bug|change-request|support) CNT=`expr $CNT + 1` ;; + *) echo "$COMMAND: \`$CLASS' is not a valid value for \`Class'." + esac + + [ $CNT -lt 5 -a -z "$BATCH" ] && + echo "Errors were found with the problem report." + + while true; do + if [ -z "$BATCH" ]; then + $ECHON1 "a)bort, e)dit or s)end? $ECHON2" + read input + else + if [ $CNT -eq 5 ]; then + input=s + else + input=a + fi + fi + case "$input" in + a*) + if [ -z "$BATCH" ]; then + echo "$COMMAND: the problem report remains in $BAD and is not sent." + mv $TEMP $BAD + else + echo "$COMMAND: the problem report is not sent." + fi + xs=1; exit + ;; + e*) + eval $EDIT $TEMP + continue 2 + ;; + s*) + break 2 + ;; + esac + done +done +# +# Remove comments and send the problem report +# (we have to use patterns, where the comment contains regex chars) +# +# /^>Originator:/s;$ORIGINATOR;; +sed -e " +/^SEND-PR:/d +/^>Organization:/,/^>[A-Za-z-]*:/s;$ORGANIZATION_C;; +/^>Confidential:/s;<.*>;; +/^>Synopsis:/s;$SYNOPSIS_C;; +/^>Severity:/s;<.*>;; +/^>Priority:/s;<.*>;; +/^>Category:/s;$CATEGORY_C;; +/^>Class:/s;<.*>;; +/^>Release:/,/^>[A-Za-z-]*:/s;$RELEASE_C;; +/^>Environment:/,/^>[A-Za-z-]*:/s;$ENVIRONMENT_C;; +/^>Description:/,/^>[A-Za-z-]*:/s;$DESCRIPTION_C;; +/^>How-To-Repeat:/,/^>[A-Za-z-]*:/s;$HOW_TO_REPEAT_C;; +/^>Fix:/,/^>[A-Za-z-]*:/s;$FIX_C;; +" $TEMP > $REF + +if $MAIL_AGENT < $REF; then + echo "$COMMAND: problem report sent" + xs=0; exit +else + echo "$COMMAND: mysterious mail failure." + if [ -z "$BATCH" ]; then + echo "$COMMAND: the problem report remains in $BAD and is not sent." + mv $REF $BAD + else + echo "$COMMAND: the problem report is not sent." + fi + xs=1; exit +fi diff --git a/gnu/usr.bin/cvs/cvs/sanity.el b/gnu/usr.bin/cvs/cvs/sanity.el new file mode 100644 index 000000000000..a1470570a011 --- /dev/null +++ b/gnu/usr.bin/cvs/cvs/sanity.el @@ -0,0 +1,18 @@ +;;;; -*- lisp-interaction -*- +;;;; Time-stamp: <29 Nov 93 14:25:28, by rich@sendai.cygnus.com> + +(defun reset-fail-counter (arg) + (interactive "p") + (setq fail-counter arg) + (message (concat "fail-counter = " (int-to-string arg)))) + + +(defun inc-next-fail-counter nil + (interactive) + (search-forward "failed test ") + (kill-word 1) + (insert-string fail-counter) + (setq fail-counter (+ 1 fail-counter))) + +(global-set-key [f15] 'reset-fail-counter) +(global-set-key [f16] 'inc-next-fail-counter) diff --git a/gnu/usr.bin/cvs/lib/alloca.c b/gnu/usr.bin/cvs/lib/alloca.c new file mode 100644 index 000000000000..948c5263a652 --- /dev/null +++ b/gnu/usr.bin/cvs/lib/alloca.c @@ -0,0 +1,191 @@ +/* + alloca -- (mostly) portable public-domain implementation -- D A Gwyn + + last edit: 86/05/30 rms + include config.h, since on VMS it renames some symbols. + Use xmalloc instead of malloc. + + This implementation of the PWB library alloca() function, + which is used to allocate space off the run-time stack so + that it is automatically reclaimed upon procedure exit, + was inspired by discussions with J. Q. Johnson of Cornell. + + It should work under any C implementation that uses an + actual procedure stack (as opposed to a linked list of + frames). There are some preprocessor constants that can + be defined when compiling for your specific system, for + improved efficiency; however, the defaults should be okay. + + The general concept of this implementation is to keep + track of all alloca()-allocated blocks, and reclaim any + that are found to be deeper in the stack than the current + invocation. This heuristic does not reclaim storage as + soon as it becomes invalid, but it will do so eventually. + + As a special case, alloca(0) reclaims storage without + allocating any. It is a good idea to use alloca(0) in + your main control loop, etc. to force garbage collection. +*/ +#ifndef lint +static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */ +#endif + +#if defined(emacs) || defined(HAVE_CONFIG_H) +#include "config.h" +#ifdef static +/* actually, only want this if static is defined as "" + -- this is for usg, in which emacs must undefine static + in order to make unexec workable + */ +#ifndef STACK_DIRECTION +you +lose +-- must know STACK_DIRECTION at compile-time +#endif /* STACK_DIRECTION undefined */ +#endif /* static */ +#endif /* emacs || HAVE_CONFIG_H*/ + +#if __STDC__ +typedef void *pointer; /* generic pointer type */ +#else +typedef char *pointer; /* generic pointer type */ +#endif + +#define NULL 0 /* null pointer constant */ + +extern void free(); +extern pointer xmalloc(); + +/* + Define STACK_DIRECTION if you know the direction of stack + growth for your system; otherwise it will be automatically + deduced at run-time. + + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown +*/ + +#ifndef STACK_DIRECTION +#define STACK_DIRECTION 0 /* direction unknown */ +#endif + +#if STACK_DIRECTION != 0 + +#define STACK_DIR STACK_DIRECTION /* known at compile-time */ + +#else /* STACK_DIRECTION == 0; need run-time code */ + +static int stack_dir; /* 1 or -1 once known */ +#define STACK_DIR stack_dir + +static void +find_stack_direction (/* void */) +{ + static char *addr = NULL; /* address of first + `dummy', once known */ + auto char dummy; /* to get stack address */ + + if (addr == NULL) + { /* initial entry */ + addr = &dummy; + + find_stack_direction (); /* recurse once */ + } + else /* second entry */ + if (&dummy > addr) + stack_dir = 1; /* stack grew upward */ + else + stack_dir = -1; /* stack grew downward */ +} + +#endif /* STACK_DIRECTION == 0 */ + +/* + An "alloca header" is used to: + (a) chain together all alloca()ed blocks; + (b) keep track of stack depth. + + It is very important that sizeof(header) agree with malloc() + alignment chunk size. The following default should work okay. +*/ + +#ifndef ALIGN_SIZE +#define ALIGN_SIZE sizeof(double) +#endif + +typedef union hdr +{ + char align[ALIGN_SIZE]; /* to force sizeof(header) */ + struct + { + union hdr *next; /* for chaining headers */ + char *deep; /* for stack depth measure */ + } h; +} header; + +/* + alloca( size ) returns a pointer to at least `size' bytes of + storage which will be automatically reclaimed upon exit from + the procedure that called alloca(). Originally, this space + was supposed to be taken from the current stack frame of the + caller, but that method cannot be made to work for some + implementations of C, for example under Gould's UTX/32. +*/ + +static header *last_alloca_header = NULL; /* -> last alloca header */ + +pointer +alloca (size) /* returns pointer to storage */ + unsigned size; /* # bytes to allocate */ +{ + auto char probe; /* probes stack depth: */ + register char *depth = &probe; + +#if STACK_DIRECTION == 0 + if (STACK_DIR == 0) /* unknown growth direction */ + find_stack_direction (); +#endif + + /* Reclaim garbage, defined as all alloca()ed storage that + was allocated from deeper in the stack than currently. */ + + { + register header *hp; /* traverses linked list */ + + for (hp = last_alloca_header; hp != NULL;) + if (STACK_DIR > 0 && hp->h.deep > depth + || STACK_DIR < 0 && hp->h.deep < depth) + { + register header *np = hp->h.next; + + free ((pointer) hp); /* collect garbage */ + + hp = np; /* -> next header */ + } + else + break; /* rest are not deeper */ + + last_alloca_header = hp; /* -> last valid storage */ + } + + if (size == 0) + return NULL; /* no allocation required */ + + /* Allocate combined header + user data storage. */ + + { + register pointer new = xmalloc (sizeof (header) + size); + /* address of header */ + + ((header *)new)->h.next = last_alloca_header; + ((header *)new)->h.deep = depth; + + last_alloca_header = (header *)new; + + /* User storage begins just after header. */ + + return (pointer)((char *)new + sizeof(header)); + } +} + diff --git a/gnu/usr.bin/cvs/lib/dup2.c b/gnu/usr.bin/cvs/lib/dup2.c new file mode 100644 index 000000000000..19743830ca6e --- /dev/null +++ b/gnu/usr.bin/cvs/lib/dup2.c @@ -0,0 +1,40 @@ +/* + dup2 -- 7th Edition UNIX system call emulation for UNIX System V + + last edit: 11-Feb-1987 D A Gwyn +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <fcntl.h> + +extern int close(), fcntl(); + +int +dup2( oldfd, newfd ) + int oldfd; /* already-open file descriptor */ + int newfd; /* desired duplicate descriptor */ +{ + register int ret; /* for fcntl() return value */ + register int save; /* for saving entry errno */ + + if ( oldfd == newfd ) + return oldfd; /* be careful not to close() */ + + save = errno; /* save entry errno */ + (void) close( newfd ); /* in case newfd is open */ + /* (may have just clobbered the original errno value) */ + + ret = fcntl( oldfd, F_DUPFD, newfd ); /* dupe it */ + + if ( ret >= 0 ) + errno = save; /* restore entry errno */ + else /* fcntl() returned error */ + if ( errno == EINVAL ) + errno = EBADF; /* we think of everything */ + + return ret; /* return file descriptor */ +} diff --git a/gnu/usr.bin/cvs/lib/fnmatch.c b/gnu/usr.bin/cvs/lib/fnmatch.c new file mode 100644 index 000000000000..34a0f890aaa4 --- /dev/null +++ b/gnu/usr.bin/cvs/lib/fnmatch.c @@ -0,0 +1,183 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Modified slightly by Brian Berliner <berliner@sun.com> for CVS use */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* IGNORE(@ */ +/* #include <ansidecl.h> */ +/* @) */ +#include <errno.h> +#include <fnmatch.h> + +#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS) +extern int errno; +#endif + +/* Match STRING against the filename pattern PATTERN, returning zero if + it matches, nonzero if not. */ +int +#if __STDC__ +fnmatch (const char *pattern, const char *string, int flags) +#else +fnmatch (pattern, string, flags) + char *pattern; + char *string; + int flags; +#endif +{ + register const char *p = pattern, *n = string; + register char c; + + if ((flags & ~__FNM_FLAGS) != 0) + { + errno = EINVAL; + return -1; + } + + while ((c = *p++) != '\0') + { + switch (c) + { + case '?': + if (*n == '\0') + return FNM_NOMATCH; + else if ((flags & FNM_PATHNAME) && *n == '/') + return FNM_NOMATCH; + else if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) + return FNM_NOMATCH; + break; + + case '\\': + if (!(flags & FNM_NOESCAPE)) + c = *p++; + if (*n != c) + return FNM_NOMATCH; + break; + + case '*': + if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) + if (((flags & FNM_PATHNAME) && *n == '/') || + (c == '?' && *n == '\0')) + return FNM_NOMATCH; + + if (c == '\0') + return 0; + + { + char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; + for (--p; *n != '\0'; ++n) + if ((c == '[' || *n == c1) && + fnmatch(p, n, flags & ~FNM_PERIOD) == 0) + return 0; + return FNM_NOMATCH; + } + + case '[': + { + /* Nonzero if the sense of the character class is inverted. */ + register int not; + + if (*n == '\0') + return FNM_NOMATCH; + + if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + not = (*p == '!' || *p == '^'); + if (not) + ++p; + + c = *p++; + for (;;) + { + register char cstart = c, cend = c; + + if (!(flags & FNM_NOESCAPE) && c == '\\') + cstart = cend = *p++; + + if (c == '\0') + /* [ (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + + if ((flags & FNM_PATHNAME) && c == '/') + /* [/] can never match. */ + return FNM_NOMATCH; + + if (c == '-' && *p != ']') + { + cend = *p++; + if (!(flags & FNM_NOESCAPE) && cend == '\\') + cend = *p++; + if (cend == '\0') + return FNM_NOMATCH; + c = *p++; + } + + if (*n >= cstart && *n <= cend) + goto matched; + + if (c == ']') + break; + } + if (!not) + return FNM_NOMATCH; + break; + + matched:; + /* Skip the rest of the [...] that already matched. */ + while (c != ']') + { + if (c == '\0') + /* [... (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + if (!(flags & FNM_NOESCAPE) && c == '\\') + /* 1003.2d11 is unclear if this is right. %%% */ + ++p; + } + if (not) + return FNM_NOMATCH; + } + break; + + default: + if (c != *n) + return FNM_NOMATCH; + } + + ++n; + } + + if (*n == '\0') + return 0; + + return FNM_NOMATCH; +} diff --git a/gnu/usr.bin/cvs/lib/fnmatch.h b/gnu/usr.bin/cvs/lib/fnmatch.h new file mode 100644 index 000000000000..a1e4f8702185 --- /dev/null +++ b/gnu/usr.bin/cvs/lib/fnmatch.h @@ -0,0 +1,45 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _FNMATCH_H + +#define _FNMATCH_H 1 + +/* Bits set in the FLAGS argument to `fnmatch'. */ +#undef FNM_PATHNAME +#define FNM_PATHNAME (1 << 0)/* No wildcard can ever match `/'. */ +#undef FNM_NOESCAPE +#define FNM_NOESCAPE (1 << 1)/* Backslashes don't quote special chars. */ +#undef FNM_PERIOD +#define FNM_PERIOD (1 << 2)/* Leading `.' is matched only explicitly. */ +#undef __FNM_FLAGS +#define __FNM_FLAGS (FNM_PATHNAME|FNM_NOESCAPE|FNM_PERIOD) + +/* Value returned by `fnmatch' if STRING does not match PATTERN. */ +#undef FNM_NOMATCH +#define FNM_NOMATCH 1 + +/* Match STRING against the filename pattern PATTERN, + returning zero if it matches, FNM_NOMATCH if not. */ +#if __STDC__ +extern int fnmatch (const char *pattern, const char *string, int flags); +#else +extern int fnmatch (); +#endif + +#endif /* fnmatch.h */ diff --git a/gnu/usr.bin/cvs/lib/ftruncate.c b/gnu/usr.bin/cvs/lib/ftruncate.c new file mode 100644 index 000000000000..13f20a382849 --- /dev/null +++ b/gnu/usr.bin/cvs/lib/ftruncate.c @@ -0,0 +1,76 @@ +/* ftruncate emulations that work on some System V's. + This file is in the public domain. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <fcntl.h> + +#ifdef F_CHSIZE +int +ftruncate (fd, length) + int fd; + off_t length; +{ + return fcntl (fd, F_CHSIZE, length); +} +#else +#ifdef F_FREESP +/* The following function was written by + kucharsk@Solbourne.com (William Kucharski) */ + +#include <sys/stat.h> +#include <errno.h> +#include <unistd.h> + +int +ftruncate (fd, length) + int fd; + off_t length; +{ + struct flock fl; + struct stat filebuf; + + if (fstat (fd, &filebuf) < 0) + return -1; + + if (filebuf.st_size < length) + { + /* Extend file length. */ + if (lseek (fd, (length - 1), SEEK_SET) < 0) + return -1; + + /* Write a "0" byte. */ + if (write (fd, "", 1) != 1) + return -1; + } + else + { + /* Truncate length. */ + fl.l_whence = 0; + fl.l_len = 0; + fl.l_start = length; + fl.l_type = F_WRLCK; /* Write lock on file space. */ + + /* This relies on the UNDOCUMENTED F_FREESP argument to + fcntl, which truncates the file so that it ends at the + position indicated by fl.l_start. + Will minor miracles never cease? */ + if (fcntl (fd, F_FREESP, &fl) < 0) + return -1; + } + + return 0; +} +#else +int +ftruncate (fd, length) + int fd; + off_t length; +{ + return chsize (fd, length); +} +#endif +#endif diff --git a/gnu/usr.bin/cvs/lib/getwd.c b/gnu/usr.bin/cvs/lib/getwd.c new file mode 100644 index 000000000000..573a7889244d --- /dev/null +++ b/gnu/usr.bin/cvs/lib/getwd.c @@ -0,0 +1,35 @@ +/* getwd.c -- get current working directory pathname + Copyright (C) 1992 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Some systems which include both getwd() and getcwd() have an implementation + of getwd() which is much faster than getcwd(). As a result, we use the + system's getwd() if it is available */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" + +/* Get the current working directory into PATHNAME */ + +char * +getwd (pathname) + char *pathname; +{ + return (getcwd(pathname, PATH_MAX)); +} diff --git a/gnu/usr.bin/cvs/lib/hostname.c b/gnu/usr.bin/cvs/lib/hostname.c new file mode 100644 index 000000000000..34be15e8b619 --- /dev/null +++ b/gnu/usr.bin/cvs/lib/hostname.c @@ -0,0 +1,49 @@ +/* hostname.c -- use uname() to get the name of the host + Copyright (C) 1992 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(STDC_HEADERS) || defined(USG) +#include <string.h> +#ifndef index +#define index strchr +#endif +#else +#include <strings.h> +#endif + +#include <sys/utsname.h> + +/* Put this host's name into NAME, using at most NAMELEN characters */ + +int +gethostname(name, namelen) + char *name; + int namelen; +{ + struct utsname ugnm; + + if (uname(&ugnm) < 0) + return (-1); + + (void) strncpy(name, ugnm.nodename, namelen-1); + name[namelen-1] = '\0'; + + return (0); +} diff --git a/gnu/usr.bin/cvs/lib/memmove.c b/gnu/usr.bin/cvs/lib/memmove.c new file mode 100644 index 000000000000..8818d46544c0 --- /dev/null +++ b/gnu/usr.bin/cvs/lib/memmove.c @@ -0,0 +1,57 @@ +/* memmove -- copy memory regions of arbitary length + Copyright (C) 1991 Free Software Foundation, Inc. + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +Libiberty is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + + +/* + +NAME + + memmove -- copy memory regions of arbitary length + +SYNOPSIS + + void memmove (void *out, const void *in, size_t n); + +DESCRIPTION + + Copy LENGTH bytes from memory region pointed to by IN to memory + region pointed to by OUT. + + Regions can be overlapping. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef __STDC__ +#include <stddef.h> +#else +#define size_t unsigned long +#endif + +void * +memmove (out, in, length) + void *out; + const void* in; + size_t length; +{ + bcopy(in, out, length); + return out; +} diff --git a/gnu/usr.bin/cvs/lib/mkdir.c b/gnu/usr.bin/cvs/lib/mkdir.c new file mode 100644 index 000000000000..a70c1d866199 --- /dev/null +++ b/gnu/usr.bin/cvs/lib/mkdir.c @@ -0,0 +1,129 @@ +/* mkrmdir.c -- BSD compatible directory functions for System V + Copyright (C) 1988, 1990 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#ifndef STDC_HEADERS +extern int errno; +#endif + +/* mkdir and rmdir adapted from GNU tar. */ + +/* Make directory DPATH, with permission mode DMODE. + + Written by Robert Rother, Mariah Corporation, August 1985 + (sdcsvax!rmr or rmr@uscd). If you want it, it's yours. + + Severely hacked over by John Gilmore to make a 4.2BSD compatible + subroutine. 11Mar86; hoptoad!gnu + + Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir, + subroutine didn't return EEXIST. It does now. */ + +int +mkdir (dpath, dmode) + char *dpath; + int dmode; +{ + int cpid, status; + struct stat statbuf; + + if (stat (dpath, &statbuf) == 0) + { + errno = EEXIST; /* stat worked, so it already exists. */ + return -1; + } + + /* If stat fails for a reason other than non-existence, return error. */ + if (errno != ENOENT) + return -1; + + cpid = fork (); + switch (cpid) + { + case -1: /* Cannot fork. */ + return -1; /* errno is set already. */ + + case 0: /* Child process. */ + /* Cheap hack to set mode of new directory. Since this child + process is going away anyway, we zap its umask. + This won't suffice to set SUID, SGID, etc. on this + directory, so the parent process calls chmod afterward. */ + status = umask (0); /* Get current umask. */ + umask (status | (0777 & ~dmode)); /* Set for mkdir. */ + execl ("/bin/mkdir", "mkdir", dpath, (char *) 0); + _exit (1); + + default: /* Parent process. */ + while (wait (&status) != cpid) /* Wait for kid to finish. */ + /* Do nothing. */ ; + + if (status & 0xFFFF) + { + errno = EIO; /* /bin/mkdir failed. */ + return -1; + } + return chmod (dpath, dmode); + } +} + +/* Remove directory DPATH. + Return 0 if successful, -1 if not. */ + +int +rmdir (dpath) + char *dpath; +{ + int cpid, status; + struct stat statbuf; + + if (stat (dpath, &statbuf) != 0) + return -1; /* stat set errno. */ + + if ((statbuf.st_mode & S_IFMT) != S_IFDIR) + { + errno = ENOTDIR; + return -1; + } + + cpid = fork (); + switch (cpid) + { + case -1: /* Cannot fork. */ + return -1; /* errno is set already. */ + + case 0: /* Child process. */ + execl ("/bin/rmdir", "rmdir", dpath, (char *) 0); + _exit (1); + + default: /* Parent process. */ + while (wait (&status) != cpid) /* Wait for kid to finish. */ + /* Do nothing. */ ; + + if (status & 0xFFFF) + { + errno = EIO; /* /bin/rmdir failed. */ + return -1; + } + return 0; + } +} diff --git a/gnu/usr.bin/cvs/lib/rename.c b/gnu/usr.bin/cvs/lib/rename.c new file mode 100644 index 000000000000..6c43cf6f698c --- /dev/null +++ b/gnu/usr.bin/cvs/lib/rename.c @@ -0,0 +1,72 @@ +/* rename.c -- BSD compatible directory function for System V + Copyright (C) 1988, 1990 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#ifndef STDC_HEADERS +extern int errno; +#endif + +/* Rename file FROM to file TO. + Return 0 if successful, -1 if not. */ + +int +rename (from, to) + char *from; + char *to; +{ + struct stat from_stats; + int pid, status; + + if (stat (from, &from_stats) == 0) + { + if (unlink (to) && errno != ENOENT) + return -1; + if ((from_stats.st_mode & S_IFMT) == S_IFDIR) + { + /* Need a setuid root process to link and unlink directories. */ + pid = fork (); + switch (pid) + { + case -1: /* Error. */ + error (1, errno, "cannot fork"); + + case 0: /* Child. */ + execl (MVDIR, "mvdir", from, to, (char *) 0); + error (255, errno, "cannot run `%s'", MVDIR); + + default: /* Parent. */ + while (wait (&status) != pid) + /* Do nothing. */ ; + + errno = 0; /* mvdir printed the system error message. */ + return status != 0 ? -1 : 0; + } + } + else + { + if (link (from, to) == 0 && (unlink (from) == 0 || errno == ENOENT)) + return 0; + } + } + return -1; +} diff --git a/gnu/usr.bin/cvs/lib/strdup.c b/gnu/usr.bin/cvs/lib/strdup.c new file mode 100644 index 000000000000..46fc8a0d6dbc --- /dev/null +++ b/gnu/usr.bin/cvs/lib/strdup.c @@ -0,0 +1,43 @@ +/* strdup.c -- return a newly allocated copy of a string + Copyright (C) 1990 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef STDC_HEADERS +#include <string.h> +#include <stdlib.h> +#else +char *malloc (); +char *strcpy (); +#endif + +/* Return a newly allocated copy of STR, + or 0 if out of memory. */ + +char * +strdup (str) + char *str; +{ + char *newstr; + + newstr = (char *) malloc (strlen (str) + 1); + if (newstr) + strcpy (newstr, str); + return newstr; +} diff --git a/gnu/usr.bin/cvs/lib/strerror.c b/gnu/usr.bin/cvs/lib/strerror.c new file mode 100644 index 000000000000..d4a3679b4ffc --- /dev/null +++ b/gnu/usr.bin/cvs/lib/strerror.c @@ -0,0 +1,813 @@ +/* Extended support for using errno values. + Copyright (C) 1992 Free Software Foundation, Inc. + Written by Fred Fish. fnf@cygnus.com + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +Libiberty is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "config.h" + +#ifndef NEED_sys_errlist +/* Note that errno.h (not sure what OS) or stdio.h (BSD 4.4, at least) + might declare sys_errlist in a way that the compiler might consider + incompatible with our later declaration, perhaps by using const + attributes. So we hide the declaration in errno.h (if any) using a + macro. */ +#define sys_errlist sys_errlist__ +#endif + +#include <stdio.h> +#include <errno.h> + +#ifndef NEED_sys_errlist +#undef sys_errlist +#endif + +/* Routines imported from standard C runtime libraries. */ + +#ifdef __STDC__ +#include <stddef.h> +extern void *malloc (size_t size); /* 4.10.3.3 */ +extern void *memset (void *s, int c, size_t n); /* 4.11.6.1 */ +#else /* !__STDC__ */ +extern char *malloc (); /* Standard memory allocater */ +extern char *memset (); +#endif /* __STDC__ */ + +#ifndef MAX +# define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +/* Translation table for errno values. See intro(2) in most UNIX systems + Programmers Reference Manuals. + + Note that this table is generally only accessed when it is used at runtime + to initialize errno name and message tables that are indexed by errno + value. + + Not all of these errnos will exist on all systems. This table is the only + thing that should have to be updated as new error numbers are introduced. + It's sort of ugly, but at least its portable. */ + +struct error_info +{ + int value; /* The numeric value from <errno.h> */ + char *name; /* The equivalent symbolic value */ +#ifdef NEED_sys_errlist + char *msg; /* Short message about this value */ +#endif +}; + +#ifdef NEED_sys_errlist +# define ENTRY(value, name, msg) {value, name, msg} +#else +# define ENTRY(value, name, msg) {value, name} +#endif + +static const struct error_info error_table[] = +{ +#if defined (EPERM) + ENTRY(EPERM, "EPERM", "Not owner"), +#endif +#if defined (ENOENT) + ENTRY(ENOENT, "ENOENT", "No such file or directory"), +#endif +#if defined (ESRCH) + ENTRY(ESRCH, "ESRCH", "No such process"), +#endif +#if defined (EINTR) + ENTRY(EINTR, "EINTR", "Interrupted system call"), +#endif +#if defined (EIO) + ENTRY(EIO, "EIO", "I/O error"), +#endif +#if defined (ENXIO) + ENTRY(ENXIO, "ENXIO", "No such device or address"), +#endif +#if defined (E2BIG) + ENTRY(E2BIG, "E2BIG", "Arg list too long"), +#endif +#if defined (ENOEXEC) + ENTRY(ENOEXEC, "ENOEXEC", "Exec format error"), +#endif +#if defined (EBADF) + ENTRY(EBADF, "EBADF", "Bad file number"), +#endif +#if defined (ECHILD) + ENTRY(ECHILD, "ECHILD", "No child processes"), +#endif +#if defined (EWOULDBLOCK) /* Put before EAGAIN, sometimes aliased */ + ENTRY(EWOULDBLOCK, "EWOULDBLOCK", "Operation would block"), +#endif +#if defined (EAGAIN) + ENTRY(EAGAIN, "EAGAIN", "No more processes"), +#endif +#if defined (ENOMEM) + ENTRY(ENOMEM, "ENOMEM", "Not enough space"), +#endif +#if defined (EACCES) + ENTRY(EACCES, "EACCES", "Permission denied"), +#endif +#if defined (EFAULT) + ENTRY(EFAULT, "EFAULT", "Bad address"), +#endif +#if defined (ENOTBLK) + ENTRY(ENOTBLK, "ENOTBLK", "Block device required"), +#endif +#if defined (EBUSY) + ENTRY(EBUSY, "EBUSY", "Device busy"), +#endif +#if defined (EEXIST) + ENTRY(EEXIST, "EEXIST", "File exists"), +#endif +#if defined (EXDEV) + ENTRY(EXDEV, "EXDEV", "Cross-device link"), +#endif +#if defined (ENODEV) + ENTRY(ENODEV, "ENODEV", "No such device"), +#endif +#if defined (ENOTDIR) + ENTRY(ENOTDIR, "ENOTDIR", "Not a directory"), +#endif +#if defined (EISDIR) + ENTRY(EISDIR, "EISDIR", "Is a directory"), +#endif +#if defined (EINVAL) + ENTRY(EINVAL, "EINVAL", "Invalid argument"), +#endif +#if defined (ENFILE) + ENTRY(ENFILE, "ENFILE", "File table overflow"), +#endif +#if defined (EMFILE) + ENTRY(EMFILE, "EMFILE", "Too many open files"), +#endif +#if defined (ENOTTY) + ENTRY(ENOTTY, "ENOTTY", "Not a typewriter"), +#endif +#if defined (ETXTBSY) + ENTRY(ETXTBSY, "ETXTBSY", "Text file busy"), +#endif +#if defined (EFBIG) + ENTRY(EFBIG, "EFBIG", "File too large"), +#endif +#if defined (ENOSPC) + ENTRY(ENOSPC, "ENOSPC", "No space left on device"), +#endif +#if defined (ESPIPE) + ENTRY(ESPIPE, "ESPIPE", "Illegal seek"), +#endif +#if defined (EROFS) + ENTRY(EROFS, "EROFS", "Read-only file system"), +#endif +#if defined (EMLINK) + ENTRY(EMLINK, "EMLINK", "Too many links"), +#endif +#if defined (EPIPE) + ENTRY(EPIPE, "EPIPE", "Broken pipe"), +#endif +#if defined (EDOM) + ENTRY(EDOM, "EDOM", "Math argument out of domain of func"), +#endif +#if defined (ERANGE) + ENTRY(ERANGE, "ERANGE", "Math result not representable"), +#endif +#if defined (ENOMSG) + ENTRY(ENOMSG, "ENOMSG", "No message of desired type"), +#endif +#if defined (EIDRM) + ENTRY(EIDRM, "EIDRM", "Identifier removed"), +#endif +#if defined (ECHRNG) + ENTRY(ECHRNG, "ECHRNG", "Channel number out of range"), +#endif +#if defined (EL2NSYNC) + ENTRY(EL2NSYNC, "EL2NSYNC", "Level 2 not synchronized"), +#endif +#if defined (EL3HLT) + ENTRY(EL3HLT, "EL3HLT", "Level 3 halted"), +#endif +#if defined (EL3RST) + ENTRY(EL3RST, "EL3RST", "Level 3 reset"), +#endif +#if defined (ELNRNG) + ENTRY(ELNRNG, "ELNRNG", "Link number out of range"), +#endif +#if defined (EUNATCH) + ENTRY(EUNATCH, "EUNATCH", "Protocol driver not attached"), +#endif +#if defined (ENOCSI) + ENTRY(ENOCSI, "ENOCSI", "No CSI structure available"), +#endif +#if defined (EL2HLT) + ENTRY(EL2HLT, "EL2HLT", "Level 2 halted"), +#endif +#if defined (EDEADLK) + ENTRY(EDEADLK, "EDEADLK", "Deadlock condition"), +#endif +#if defined (ENOLCK) + ENTRY(ENOLCK, "ENOLCK", "No record locks available"), +#endif +#if defined (EBADE) + ENTRY(EBADE, "EBADE", "Invalid exchange"), +#endif +#if defined (EBADR) + ENTRY(EBADR, "EBADR", "Invalid request descriptor"), +#endif +#if defined (EXFULL) + ENTRY(EXFULL, "EXFULL", "Exchange full"), +#endif +#if defined (ENOANO) + ENTRY(ENOANO, "ENOANO", "No anode"), +#endif +#if defined (EBADRQC) + ENTRY(EBADRQC, "EBADRQC", "Invalid request code"), +#endif +#if defined (EBADSLT) + ENTRY(EBADSLT, "EBADSLT", "Invalid slot"), +#endif +#if defined (EDEADLOCK) + ENTRY(EDEADLOCK, "EDEADLOCK", "File locking deadlock error"), +#endif +#if defined (EBFONT) + ENTRY(EBFONT, "EBFONT", "Bad font file format"), +#endif +#if defined (ENOSTR) + ENTRY(ENOSTR, "ENOSTR", "Device not a stream"), +#endif +#if defined (ENODATA) + ENTRY(ENODATA, "ENODATA", "No data available"), +#endif +#if defined (ETIME) + ENTRY(ETIME, "ETIME", "Timer expired"), +#endif +#if defined (ENOSR) + ENTRY(ENOSR, "ENOSR", "Out of streams resources"), +#endif +#if defined (ENONET) + ENTRY(ENONET, "ENONET", "Machine is not on the network"), +#endif +#if defined (ENOPKG) + ENTRY(ENOPKG, "ENOPKG", "Package not installed"), +#endif +#if defined (EREMOTE) + ENTRY(EREMOTE, "EREMOTE", "Object is remote"), +#endif +#if defined (ENOLINK) + ENTRY(ENOLINK, "ENOLINK", "Link has been severed"), +#endif +#if defined (EADV) + ENTRY(EADV, "EADV", "Advertise error"), +#endif +#if defined (ESRMNT) + ENTRY(ESRMNT, "ESRMNT", "Srmount error"), +#endif +#if defined (ECOMM) + ENTRY(ECOMM, "ECOMM", "Communication error on send"), +#endif +#if defined (EPROTO) + ENTRY(EPROTO, "EPROTO", "Protocol error"), +#endif +#if defined (EMULTIHOP) + ENTRY(EMULTIHOP, "EMULTIHOP", "Multihop attempted"), +#endif +#if defined (EDOTDOT) + ENTRY(EDOTDOT, "EDOTDOT", "RFS specific error"), +#endif +#if defined (EBADMSG) + ENTRY(EBADMSG, "EBADMSG", "Not a data message"), +#endif +#if defined (ENAMETOOLONG) + ENTRY(ENAMETOOLONG, "ENAMETOOLONG", "File name too long"), +#endif +#if defined (EOVERFLOW) + ENTRY(EOVERFLOW, "EOVERFLOW", "Value too large for defined data type"), +#endif +#if defined (ENOTUNIQ) + ENTRY(ENOTUNIQ, "ENOTUNIQ", "Name not unique on network"), +#endif +#if defined (EBADFD) + ENTRY(EBADFD, "EBADFD", "File descriptor in bad state"), +#endif +#if defined (EREMCHG) + ENTRY(EREMCHG, "EREMCHG", "Remote address changed"), +#endif +#if defined (ELIBACC) + ENTRY(ELIBACC, "ELIBACC", "Can not access a needed shared library"), +#endif +#if defined (ELIBBAD) + ENTRY(ELIBBAD, "ELIBBAD", "Accessing a corrupted shared library"), +#endif +#if defined (ELIBSCN) + ENTRY(ELIBSCN, "ELIBSCN", ".lib section in a.out corrupted"), +#endif +#if defined (ELIBMAX) + ENTRY(ELIBMAX, "ELIBMAX", "Attempting to link in too many shared libraries"), +#endif +#if defined (ELIBEXEC) + ENTRY(ELIBEXEC, "ELIBEXEC", "Cannot exec a shared library directly"), +#endif +#if defined (EILSEQ) + ENTRY(EILSEQ, "EILSEQ", "Illegal byte sequence"), +#endif +#if defined (ENOSYS) + ENTRY(ENOSYS, "ENOSYS", "Operation not applicable"), +#endif +#if defined (ELOOP) + ENTRY(ELOOP, "ELOOP", "Too many symbolic links encountered"), +#endif +#if defined (ERESTART) + ENTRY(ERESTART, "ERESTART", "Interrupted system call should be restarted"), +#endif +#if defined (ESTRPIPE) + ENTRY(ESTRPIPE, "ESTRPIPE", "Streams pipe error"), +#endif +#if defined (ENOTEMPTY) + ENTRY(ENOTEMPTY, "ENOTEMPTY", "Directory not empty"), +#endif +#if defined (EUSERS) + ENTRY(EUSERS, "EUSERS", "Too many users"), +#endif +#if defined (ENOTSOCK) + ENTRY(ENOTSOCK, "ENOTSOCK", "Socket operation on non-socket"), +#endif +#if defined (EDESTADDRREQ) + ENTRY(EDESTADDRREQ, "EDESTADDRREQ", "Destination address required"), +#endif +#if defined (EMSGSIZE) + ENTRY(EMSGSIZE, "EMSGSIZE", "Message too long"), +#endif +#if defined (EPROTOTYPE) + ENTRY(EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket"), +#endif +#if defined (ENOPROTOOPT) + ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol not available"), +#endif +#if defined (EPROTONOSUPPORT) + ENTRY(EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported"), +#endif +#if defined (ESOCKTNOSUPPORT) + ENTRY(ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "Socket type not supported"), +#endif +#if defined (EOPNOTSUPP) + ENTRY(EOPNOTSUPP, "EOPNOTSUPP", "Operation not supported on transport endpoint"), +#endif +#if defined (EPFNOSUPPORT) + ENTRY(EPFNOSUPPORT, "EPFNOSUPPORT", "Protocol family not supported"), +#endif +#if defined (EAFNOSUPPORT) + ENTRY(EAFNOSUPPORT, "EAFNOSUPPORT", "Address family not supported by protocol"), +#endif +#if defined (EADDRINUSE) + ENTRY(EADDRINUSE, "EADDRINUSE", "Address already in use"), +#endif +#if defined (EADDRNOTAVAIL) + ENTRY(EADDRNOTAVAIL, "EADDRNOTAVAIL","Cannot assign requested address"), +#endif +#if defined (ENETDOWN) + ENTRY(ENETDOWN, "ENETDOWN", "Network is down"), +#endif +#if defined (ENETUNREACH) + ENTRY(ENETUNREACH, "ENETUNREACH", "Network is unreachable"), +#endif +#if defined (ENETRESET) + ENTRY(ENETRESET, "ENETRESET", "Network dropped connection because of reset"), +#endif +#if defined (ECONNABORTED) + ENTRY(ECONNABORTED, "ECONNABORTED", "Software caused connection abort"), +#endif +#if defined (ECONNRESET) + ENTRY(ECONNRESET, "ECONNRESET", "Connection reset by peer"), +#endif +#if defined (ENOBUFS) + ENTRY(ENOBUFS, "ENOBUFS", "No buffer space available"), +#endif +#if defined (EISCONN) + ENTRY(EISCONN, "EISCONN", "Transport endpoint is already connected"), +#endif +#if defined (ENOTCONN) + ENTRY(ENOTCONN, "ENOTCONN", "Transport endpoint is not connected"), +#endif +#if defined (ESHUTDOWN) + ENTRY(ESHUTDOWN, "ESHUTDOWN", "Cannot send after transport endpoint shutdown"), +#endif +#if defined (ETOOMANYREFS) + ENTRY(ETOOMANYREFS, "ETOOMANYREFS", "Too many references: cannot splice"), +#endif +#if defined (ETIMEDOUT) + ENTRY(ETIMEDOUT, "ETIMEDOUT", "Connection timed out"), +#endif +#if defined (ECONNREFUSED) + ENTRY(ECONNREFUSED, "ECONNREFUSED", "Connection refused"), +#endif +#if defined (EHOSTDOWN) + ENTRY(EHOSTDOWN, "EHOSTDOWN", "Host is down"), +#endif +#if defined (EHOSTUNREACH) + ENTRY(EHOSTUNREACH, "EHOSTUNREACH", "No route to host"), +#endif +#if defined (EALREADY) + ENTRY(EALREADY, "EALREADY", "Operation already in progress"), +#endif +#if defined (EINPROGRESS) + ENTRY(EINPROGRESS, "EINPROGRESS", "Operation now in progress"), +#endif +#if defined (ESTALE) + ENTRY(ESTALE, "ESTALE", "Stale NFS file handle"), +#endif +#if defined (EUCLEAN) + ENTRY(EUCLEAN, "EUCLEAN", "Structure needs cleaning"), +#endif +#if defined (ENOTNAM) + ENTRY(ENOTNAM, "ENOTNAM", "Not a XENIX named type file"), +#endif +#if defined (ENAVAIL) + ENTRY(ENAVAIL, "ENAVAIL", "No XENIX semaphores available"), +#endif +#if defined (EISNAM) + ENTRY(EISNAM, "EISNAM", "Is a named type file"), +#endif +#if defined (EREMOTEIO) + ENTRY(EREMOTEIO, "EREMOTEIO", "Remote I/O error"), +#endif + ENTRY(0, NULL, NULL) +}; + +/* Translation table allocated and initialized at runtime. Indexed by the + errno value to find the equivalent symbolic value. */ + +static char **error_names; +static int num_error_names = 0; + +/* Translation table allocated and initialized at runtime, if it does not + already exist in the host environment. Indexed by the errno value to find + the descriptive string. + + We don't export it for use in other modules because even though it has the + same name, it differs from other implementations in that it is dynamically + initialized rather than statically initialized. */ + +#ifdef NEED_sys_errlist + +static int sys_nerr; +static char **sys_errlist; + +#else + +extern int sys_nerr; +extern char *sys_errlist[]; + +#endif + + +/* + +NAME + + init_error_tables -- initialize the name and message tables + +SYNOPSIS + + static void init_error_tables (); + +DESCRIPTION + + Using the error_table, which is initialized at compile time, generate + the error_names and the sys_errlist (if needed) tables, which are + indexed at runtime by a specific errno value. + +BUGS + + The initialization of the tables may fail under low memory conditions, + in which case we don't do anything particularly useful, but we don't + bomb either. Who knows, it might succeed at a later point if we free + some memory in the meantime. In any case, the other routines know + how to deal with lack of a table after trying to initialize it. This + may or may not be considered to be a bug, that we don't specifically + warn about this particular failure mode. + +*/ + +static void +init_error_tables () +{ + const struct error_info *eip; + int nbytes; + + /* If we haven't already scanned the error_table once to find the maximum + errno value, then go find it now. */ + + if (num_error_names == 0) + { + for (eip = error_table; eip -> name != NULL; eip++) + { + if (eip -> value >= num_error_names) + { + num_error_names = eip -> value + 1; + } + } + } + + /* Now attempt to allocate the error_names table, zero it out, and then + initialize it from the statically initialized error_table. */ + + if (error_names == NULL) + { + nbytes = num_error_names * sizeof (char *); + if ((error_names = (char **) malloc (nbytes)) != NULL) + { + memset (error_names, 0, nbytes); + for (eip = error_table; eip -> name != NULL; eip++) + { + error_names[eip -> value] = eip -> name; + } + } + } + +#ifdef NEED_sys_errlist + + /* Now attempt to allocate the sys_errlist table, zero it out, and then + initialize it from the statically initialized error_table. */ + + if (sys_errlist == NULL) + { + nbytes = num_error_names * sizeof (char *); + if ((sys_errlist = (char **) malloc (nbytes)) != NULL) + { + memset (sys_errlist, 0, nbytes); + sys_nerr = num_error_names; + for (eip = error_table; eip -> name != NULL; eip++) + { + sys_errlist[eip -> value] = eip -> msg; + } + } + } + +#endif + +} + +/* + +NAME + + errno_max -- return the max errno value + +SYNOPSIS + + int errno_max (); + +DESCRIPTION + + Returns the maximum errno value for which a corresponding symbolic + name or message is available. Note that in the case where + we use the sys_errlist supplied by the system, it is possible for + there to be more symbolic names than messages, or vice versa. + In fact, the manual page for perror(3C) explicitly warns that one + should check the size of the table (sys_nerr) before indexing it, + since new error codes may be added to the system before they are + added to the table. Thus sys_nerr might be smaller than value + implied by the largest errno value defined in <errno.h>. + + We return the maximum value that can be used to obtain a meaningful + symbolic name or message. + +*/ + +int +errno_max () +{ + int maxsize; + + if (error_names == NULL) + { + init_error_tables (); + } + maxsize = MAX (sys_nerr, num_error_names); + return (maxsize - 1); +} + +/* + +NAME + + strerror -- map an error number to an error message string + +SYNOPSIS + + char *strerror (int errnoval) + +DESCRIPTION + + Maps an errno number to an error message string, the contents of + which are implementation defined. On systems which have the external + variables sys_nerr and sys_errlist, these strings will be the same + as the ones used by perror(). + + If the supplied error number is within the valid range of indices + for the sys_errlist, but no message is available for the particular + error number, then returns the string "Error NUM", where NUM is the + error number. + + If the supplied error number is not a valid index into sys_errlist, + returns NULL. + + The returned string is only guaranteed to be valid only until the + next call to strerror. + +*/ + +char * +strerror (errnoval) + int errnoval; +{ + char *msg; + static char buf[32]; + +#ifdef NEED_sys_errlist + + if (error_names == NULL) + { + init_error_tables (); + } + +#endif + + if ((errnoval < 0) || (errnoval >= sys_nerr)) + { + /* Out of range, just return NULL */ + msg = NULL; + } + else if ((sys_errlist == NULL) || (sys_errlist[errnoval] == NULL)) + { + /* In range, but no sys_errlist or no entry at this index. */ + sprintf (buf, "Error %d", errnoval); + msg = buf; + } + else + { + /* In range, and a valid message. Just return the message. */ + msg = sys_errlist[errnoval]; + } + + return (msg); +} + + + +/* + +NAME + + strerrno -- map an error number to a symbolic name string + +SYNOPSIS + + char *strerrno (int errnoval) + +DESCRIPTION + + Given an error number returned from a system call (typically + returned in errno), returns a pointer to a string containing the + symbolic name of that error number, as found in <errno.h>. + + If the supplied error number is within the valid range of indices + for symbolic names, but no name is available for the particular + error number, then returns the string "Error NUM", where NUM is + the error number. + + If the supplied error number is not within the range of valid + indices, then returns NULL. + +BUGS + + The contents of the location pointed to are only guaranteed to be + valid until the next call to strerrno. + +*/ + +char * +strerrno (errnoval) + int errnoval; +{ + char *name; + static char buf[32]; + + if (error_names == NULL) + { + init_error_tables (); + } + + if ((errnoval < 0) || (errnoval >= num_error_names)) + { + /* Out of range, just return NULL */ + name = NULL; + } + else if ((error_names == NULL) || (error_names[errnoval] == NULL)) + { + /* In range, but no error_names or no entry at this index. */ + sprintf (buf, "Error %d", errnoval); + name = buf; + } + else + { + /* In range, and a valid name. Just return the name. */ + name = error_names[errnoval]; + } + + return (name); +} + +/* + +NAME + + strtoerrno -- map a symbolic errno name to a numeric value + +SYNOPSIS + + int strtoerrno (char *name) + +DESCRIPTION + + Given the symbolic name of a error number, map it to an errno value. + If no translation is found, returns 0. + +*/ + +int +strtoerrno (name) + char *name; +{ + int errnoval = 0; + + if (name != NULL) + { + if (error_names == NULL) + { + init_error_tables (); + } + for (errnoval = 0; errnoval < num_error_names; errnoval++) + { + if ((error_names[errnoval] != NULL) && + (strcmp (name, error_names[errnoval]) == 0)) + { + break; + } + } + if (errnoval == num_error_names) + { + errnoval = 0; + } + } + return (errnoval); +} + + +/* A simple little main that does nothing but print all the errno translations + if MAIN is defined and this file is compiled and linked. */ + +#ifdef MAIN + +main () +{ + int errn; + int errnmax; + char *name; + char *msg; + char *strerrno (); + char *strerror (); + + errnmax = errno_max (); + printf ("%d entries in names table.\n", num_error_names); + printf ("%d entries in messages table.\n", sys_nerr); + printf ("%d is max useful index.\n", errnmax); + + /* Keep printing values until we get to the end of *both* tables, not + *either* table. Note that knowing the maximum useful index does *not* + relieve us of the responsibility of testing the return pointer for + NULL. */ + + for (errn = 0; errn <= errnmax; errn++) + { + name = strerrno (errn); + name = (name == NULL) ? "<NULL>" : name; + msg = strerror (errn); + msg = (msg == NULL) ? "<NULL>" : msg; + printf ("%-4d%-18s%s\n", errn, name, msg); + } +} + +#endif diff --git a/gnu/usr.bin/man/Makefile.shprog b/gnu/usr.bin/man/Makefile.shprog deleted file mode 100644 index 665a194917ff..000000000000 --- a/gnu/usr.bin/man/Makefile.shprog +++ /dev/null @@ -1,30 +0,0 @@ -# $Id$ - -# This may become bsd.shprog.mk. The general version would have to handle: -# - arbitrary sed substitutions. -# - programs without man pages. -# - programs with man pages in sections other than section 1. - -MAN1= ${SHPROG:S/$/.1/g} - -CLEANFILES+= ${SHPROG} ${MAN1} - -all: ${SHPROG} - -.sh: - sed -e 's,%libdir%,${libdir},' -e 's,%bindir%,${bindir},' \ - -e 's,%pager%,${pager},' \ - ${.ALLSRC} > ${.TARGET} - -.SUFFIXES: .man .1 -.man.1: - sed -e 's,%libdir%,${libdir},' -e 's,%bindir%,${bindir},' \ - -e 's,%pager%,${pager},' -e 's,%troff%,${troff},' \ - -e 's,%manpath_config_file%,${manpath_config_file},' \ - ${.ALLSRC} > ${.TARGET} - -beforeinstall: - ${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \ - ${SHPROG} ${DESTDIR}${BINDIR} - -.include <bsd.prog.mk> diff --git a/lib/libc/locale/setlocale.c b/lib/libc/locale/setlocale.c new file mode 100644 index 000000000000..dc8157af0c64 --- /dev/null +++ b/lib/libc/locale/setlocale.c @@ -0,0 +1,201 @@ +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)setlocale.c 8.1 (Berkeley) 7/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <limits.h> +#include <locale.h> +#include <rune.h> +#include <stdlib.h> +#include <string.h> +#include "common_setlocale.h" +#include "common_rune.h" + +char *_PathLocale; + +static char *loadlocale __P((int)); + +char * +setlocale(category, locale) + int category; + const char *locale; +{ + int found, i, len; + char *env, *r; + + if (!PathLocale && !(PathLocale = getenv("PATH_LOCALE"))) + PathLocale = _PATH_LOCALE; + + if (category < 0 || category >= _LC_LAST) + return (NULL); + + if (!locale) + return (category ? + current_categories[category] : currentlocale()); + + /* + * Default to the current locale for everything. + */ + for (i = 1; i < _LC_LAST; ++i) + (void)strcpy(new_categories[i], current_categories[i]); + + /* + * Now go fill up new_categories from the locale argument + */ + if (!*locale) { + env = getenv(categories[category]); + + if (!env) + env = getenv(categories[0]); + + if (!env) + env = getenv("LANG"); + + if (!env) + env = "C"; + + (void) strncpy(new_categories[category], env, 31); + new_categories[category][31] = 0; + if (!category) { + for (i = 1; i < _LC_LAST; ++i) { + if (!(env = getenv(categories[i]))) + env = new_categories[0]; + (void)strncpy(new_categories[i], env, 31); + new_categories[i][31] = 0; + } + } + } else if (category) { + (void)strncpy(new_categories[category], locale, 31); + new_categories[category][31] = 0; + } else { + if ((r = strchr(locale, '/')) == 0) { + for (i = 1; i < _LC_LAST; ++i) { + (void)strncpy(new_categories[i], locale, 31); + new_categories[i][31] = 0; + } + } else { + for (i = 1; r[1] == '/'; ++r); + if (!r[1]) + return (NULL); /* Hmm, just slashes... */ + do { + len = r - locale > 31 ? 31 : r - locale; + (void)strncpy(new_categories[i++], locale, len); + new_categories[i++][len] = 0; + locale = r; + while (*locale == '/') + ++locale; + while (*++r && *r != '/'); + } while (*locale); + while (i < _LC_LAST) + (void)strcpy(new_categories[i], + new_categories[i-1]); + } + } + + if (category) + return (loadlocale(category)); + + found = 0; + for (i = 1; i < _LC_LAST; ++i) + if (loadlocale(i) != NULL) + found = 1; + if (found) + return (currentlocale()); + return (NULL); +} + +static char * +loadlocale(category) + int category; +{ +#if 0 + char name[PATH_MAX]; +#endif + if (strcmp(new_categories[category], + current_categories[category]) == 0) + return (current_categories[category]); + + if (category == LC_CTYPE) { + if (setrunelocale(new_categories[LC_CTYPE])) + return (NULL); + (void)strcpy(current_categories[LC_CTYPE], + new_categories[LC_CTYPE]); + return (current_categories[LC_CTYPE]); + } + + if (category == LC_COLLATE) { + if (__collate_load_tables(new_categories[LC_COLLATE]) < 0) + return (NULL); + (void)strcpy(current_categories[LC_COLLATE], + new_categories[LC_COLLATE]); + return (current_categories[LC_COLLATE]); + } + + if (category == LC_TIME) { + if (__time_load_locale(new_categories[LC_TIME]) < 0) + return (NULL); + (void)strcpy(current_categories[LC_TIME], + new_categories[LC_TIME]); + return (current_categories[LC_TIME]); + } + + if (!strcmp(new_categories[category], "C") || + !strcmp(new_categories[category], "POSIX")) { + + /* + * Some day this will need to reset the locale to the default + * C locale. Since we have no way to change them as of yet, + * there is no need to reset them. + */ + (void)strcpy(current_categories[category], + new_categories[category]); + return (current_categories[category]); + } +#if 0 + /* + * Some day we will actually look at this file. + */ + (void)snprintf(name, sizeof(name), "%s/%s/%s", + PathLocale, new_categories[category], categories[category]); +#endif + switch (category) { + case LC_MONETARY: + case LC_NUMERIC: + return (NULL); + } +} diff --git a/lib/libdisk/Makefile b/lib/libdisk/Makefile deleted file mode 100644 index 3d58dfa11c00..000000000000 --- a/lib/libdisk/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -LIB= disk -SRCS= blocks.c disklabel.c dkcksum.c chunk.c disk.c change.c \ - create_chunk.c rules.c write_disk.c data.c - -CFLAGS+= -Wall -g -CLEANFILES+= tmp.c tst01 tst01.o data.c -VPATH= ${.CURDIR}/../../sbin/disklabel -NOPROFILE= yes -NOSHARED= yes - -.include <bsd.lib.mk> - -BOOTS=/usr/mdec - -data.c: libdisk.h ${BOOTS}/boot1 ${BOOTS}/boot2 - file2c 'const unsigned char boot1[] = {' '};' \ - < ${BOOTS}/boot1 > tmp.c - file2c 'const unsigned char boot2[] = {' '};' \ - < ${BOOTS}/boot2 >> tmp.c - mv tmp.c data.c - -tst01: tst01.o libdisk.a - cc ${CFLAGS} -static tst01.o -o tst01 libdisk.a diff --git a/lib/libdisk/blocks.c b/lib/libdisk/blocks.c deleted file mode 100644 index 85a9c44cf707..000000000000 --- a/lib/libdisk/blocks.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * $Id: blocks.c,v 1.2 1995/04/29 01:55:17 phk Exp $ - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <err.h> -#include "libdisk.h" - -void * -read_block(int fd, daddr_t block) -{ - void *foo; - - foo = malloc(512); - if (!foo) - err(1,"malloc"); - if (-1 == lseek(fd,block * 512,SEEK_SET)) - err(1,"lseek"); - if (512 != read(fd,foo, 512)) - err(1,"read"); - return foo; -} - -void -write_block(int fd, daddr_t block, void *foo) -{ - if (-1 == lseek(fd,block * 512,SEEK_SET)) - err(1,"lseek"); - if (512 != write(fd,foo, 512)) - err(1,"write"); -} diff --git a/lib/libdisk/change.c b/lib/libdisk/change.c deleted file mode 100644 index 1ecd22056983..000000000000 --- a/lib/libdisk/change.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * $Id: change.c,v 1.9 1995/06/11 19:29:31 rgrimes Exp $ - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <err.h> -#include <sys/types.h> -#include "libdisk.h" - -#if 0 -struct disk * -Set_Phys_Geom(struct disk *disk, u_long cyl, u_long hd, u_long sect) -{ - struct disk *d = Int_Open_Disk(disk->name,cyl*hd*sect); - d->real_cyl = cyl; - d->real_hd = hd; - d->real_sect = sect; - d->bios_cyl = disk->bios_cyl; - d->bios_hd = disk->bios_hd; - d->bios_sect = disk->bios_sect; - d->flags = disk->flags; - Free_Disk(disk); - return d; -} -#endif - -void -Set_Bios_Geom(struct disk *disk, u_long cyl, u_long hd, u_long sect) -{ - disk->bios_cyl = cyl; - disk->bios_hd = hd; - disk->bios_sect = sect; - Bios_Limit_Chunk(disk->chunks,1024*hd*sect); -} - -void -All_FreeBSD(struct disk *d, int force_all) -{ - struct chunk *c; - - again: - for (c=d->chunks->part;c;c=c->next) - if (c->type != unused) { - Delete_Chunk(d,c); - goto again; - } - c=d->chunks; - Create_Chunk(d,c->offset,c->size,freebsd,0xa5, - force_all? CHUNK_FORCE_ALL: 0); -} diff --git a/lib/libdisk/chunk.c b/lib/libdisk/chunk.c deleted file mode 100644 index 906911aa8023..000000000000 --- a/lib/libdisk/chunk.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * $Id: chunk.c,v 1.14.2.2 1995/06/05 02:24:25 jkh Exp $ - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/types.h> -#include <err.h> -#include "libdisk.h" - -#define new_chunk() memset(malloc(sizeof(struct chunk)), 0, sizeof(struct chunk)) - -/* Is c2 completely inside c1 ? */ - -static int -Chunk_Inside(struct chunk *c1, struct chunk *c2) -{ - /* if c1 ends before c2 do */ - if (c1->end < c2->end) - return 0; - /* if c1 starts after c2 do */ - if (c1->offset > c2->offset) - return 0; - return 1; -} - -struct chunk * -Find_Mother_Chunk(struct chunk *chunks, u_long offset, u_long end, chunk_e type) -{ - struct chunk *c1,*c2,ct; - ct.offset = offset; - ct.end = end; - switch (type) { - case whole: - if (Chunk_Inside(chunks,&ct)) - return chunks; - case extended: - for(c1=chunks->part;c1;c1=c1->next) { - if (c1->type != type) - continue; - if (Chunk_Inside(c1,&ct)) - return c1; - } - return 0; - case freebsd: - for(c1=chunks->part;c1;c1=c1->next) { - if (c1->type == type) - if (Chunk_Inside(c1,&ct)) - return c1; - if (c1->type != extended) - continue; - for(c2=c1->part;c2;c2=c2->next) - if (c2->type == type - && Chunk_Inside(c2,&ct)) - return c2; - } - return 0; - default: - warn("Unsupported mother (0x%x) in Find_Mother_Chunk"); - return 0; - } -} - -void -Free_Chunk(struct chunk *c1) -{ - if(!c1) return; - if(c1->private && c1->private_free) - (*c1->private_free)(c1->private); - if(c1->part) - Free_Chunk(c1->part); - if(c1->next) - Free_Chunk(c1->next); - free(c1->name); - free(c1); -} - -struct chunk * -Clone_Chunk(struct chunk *c1) -{ - struct chunk *c2; - if(!c1) - return 0; - c2 = new_chunk(); - if (!c2) err(1,"malloc failed"); - *c2 = *c1; - if (c1->private && c1->private_clone) - c2->private = c2->private_clone(c2->private); - c2->name = strdup(c2->name); - c2->next = Clone_Chunk(c2->next); - c2->part = Clone_Chunk(c2->part); - return c2; -} - -int -Insert_Chunk(struct chunk *c2, u_long offset, u_long size, char *name, chunk_e type, int subtype, u_long flags) -{ - struct chunk *ct,*cs; - - /* We will only insert into empty spaces */ - if (c2->type != unused) - return __LINE__; - - ct = new_chunk(); - if (!ct) err(1,"malloc failed"); - memset(ct,0,sizeof *ct); - ct->disk = c2->disk; - ct->offset = offset; - ct->size = size; - ct->end = offset + size - 1; - ct->type = type; - ct->name = strdup(name); - ct->subtype = subtype; - ct->flags = flags; - - if (!Chunk_Inside(c2,ct)) { - Free_Chunk(ct); - return __LINE__; - } - - if(type==freebsd || type==extended) { - cs = new_chunk(); - if (!cs) err(1,"malloc failed"); - memset(cs,0,sizeof *cs); - cs->disk = c2->disk; - cs->offset = offset; - cs->size = size; - cs->end = offset + size - 1; - cs->type = unused; - cs->name = strdup("-"); - ct->part = cs; - } - - /* Make a new chunk for any trailing unused space */ - if (c2->end > ct->end) { - cs = new_chunk(); - if (!cs) err(1,"malloc failed"); - *cs = *c2; - cs->disk = c2->disk; - cs->offset = ct->end + 1; - cs->size = c2->end - ct->end; - if(c2->name) - cs->name = strdup(c2->name); - c2->next = cs; - c2->size -= c2->end - ct->end; - c2->end = ct->end; - } - /* If no leading unused space just occupy the old chunk */ - if (c2->offset == ct->offset) { - c2->name = ct->name; - c2->type = ct->type; - c2->part = ct->part; - c2->subtype = ct->subtype; - c2->flags = ct->flags; - ct->name = 0; - ct->part = 0; - Free_Chunk(ct); - return 0; - } - /* else insert new chunk and adjust old one */ - c2->end = ct->offset - 1; - c2->size -= ct->size; - ct->next = c2->next; - c2->next = ct; - return 0; -} - -int -Add_Chunk(struct disk *d, long offset, u_long size, char *name, chunk_e type, - int subtype, u_long flags) -{ - struct chunk *c1,*c2,ct; - u_long end = offset + size - 1; - ct.offset = offset; - ct.end = end; - ct.size = size; - - if (type == whole) { - d->chunks = c1 = new_chunk(); - if (!c1) err(1,"malloc failed"); - memset(c1,0,sizeof *c1); - c2 = c1->part = new_chunk(); - if (!c2) err(1,"malloc failed"); - memset(c2,0,sizeof *c2); - c2->disk = c1->disk = d; - c2->offset = c1->offset = offset; - c2->size = c1->size = size; - c2->end = c1->end = end; - c1->name = strdup(name); - c2->name = strdup("-"); - c1->type = type; - c2->type = unused; - c1->flags = flags; - c1->subtype = subtype; - return 0; - } - if (type == freebsd) - subtype = 0xa5; - c1 = 0; - if(!c1 && (type == freebsd || type == fat || type == unknown)) - c1 = Find_Mother_Chunk(d->chunks,offset,end,extended); - if(!c1 && (type == freebsd || type == fat || type == unknown)) - c1 = Find_Mother_Chunk(d->chunks,offset,end,whole); - if(!c1 && type == extended) - c1 = Find_Mother_Chunk(d->chunks,offset,end,whole); - if(!c1 && type == part) - c1 = Find_Mother_Chunk(d->chunks,offset,end,freebsd); - if(!c1) - return __LINE__; - for(c2=c1->part;c2;c2=c2->next) { - if (c2->type != unused) - continue; - if(Chunk_Inside(c2,&ct)) { - if (type != freebsd) - goto doit; - if (!(flags & CHUNK_ALIGN)) - goto doit; - if (offset == d->chunks->offset - && end == d->chunks->end) - goto doit; - - /* Round down to prev cylinder */ - offset = Prev_Cyl_Aligned(d,offset); - /* Stay inside the parent */ - if (offset < c2->offset) - offset = c2->offset; - /* Round up to next cylinder */ - offset = Next_Cyl_Aligned(d,offset); - /* Keep one track clear in front of parent */ - if (offset == c1->offset) - offset = Next_Track_Aligned(d,offset+1); - - /* Work on the (end+1) */ - size += offset; - /* Round up to cylinder */ - size = Next_Cyl_Aligned(d,size); - /* Stay inside parent */ - if ((size-1) > c2->end) - size = c2->end+1; - /* Round down to cylinder */ - size = Prev_Cyl_Aligned(d,size); - - /* Convert back to size */ - size -= offset; - - doit: - return Insert_Chunk(c2,offset,size,name, - type,subtype,flags); - } - } - return __LINE__; -} - -char * -ShowChunkFlags(struct chunk *c) -{ - static char ret[10]; - - int i=0; - if (c->flags & CHUNK_BSD_COMPAT) ret[i++] = 'C'; - if (c->flags & CHUNK_ACTIVE) ret[i++] = 'A'; - if (c->flags & CHUNK_ALIGN) ret[i++] = '='; - if (c->flags & CHUNK_PAST_1024) ret[i++] = '>'; - if (c->flags & CHUNK_IS_ROOT) ret[i++] = 'R'; - if (c->flags & CHUNK_BAD144) ret[i++] = 'B'; - ret[i++] = '\0'; - return ret; -} - -void -Print_Chunk(struct chunk *c1,int offset) -{ - int i; - if(!c1) return; - for(i=0;i<offset-2;i++) putchar(' '); - for(;i<offset;i++) putchar('-'); - putchar('>'); - for(;i<10;i++) putchar(' '); - printf("%p %8ld %8lu %8lu %-8s %-8s 0x%02x %s", - c1, c1->offset, c1->size, c1->end, c1->name, - chunk_n[c1->type],c1->subtype, - ShowChunkFlags(c1)); - putchar('\n'); - Print_Chunk(c1->part,offset + 2); - Print_Chunk(c1->next,offset); -} - -void -Debug_Chunk(struct chunk *c1) -{ - Print_Chunk(c1,2); -} - -void -Bios_Limit_Chunk(struct chunk *c1, u_long limit) -{ - if (c1->part) - Bios_Limit_Chunk(c1->part,limit); - if (c1->next) - Bios_Limit_Chunk(c1->next,limit); - if (c1->end >= limit) { - c1->flags |= CHUNK_PAST_1024; - } else { - c1->flags &= ~CHUNK_PAST_1024; - } -} - -int -Delete_Chunk(struct disk *d, struct chunk *c) -{ - struct chunk *c1=0,*c2,*c3; - chunk_e type = c->type; - - if(type == whole) - return 1; - if(!c1 && (type == freebsd || type == fat || type == unknown)) - c1 = Find_Mother_Chunk(d->chunks,c->offset,c->end,extended); - if(!c1 && (type == freebsd || type == fat || type == unknown)) - c1 = Find_Mother_Chunk(d->chunks,c->offset,c->end,whole); - if(!c1 && type == extended) - c1 = Find_Mother_Chunk(d->chunks,c->offset,c->end,whole); - if(!c1 && type == part) - c1 = Find_Mother_Chunk(d->chunks,c->offset,c->end,freebsd); - if(!c1) - return 1; - for(c2=c1->part;c2;c2=c2->next) { - if (c2 == c) { - c2->type = unused; - c2->subtype = 0; - c2->flags = 0; - free(c2->name); - c2->name = strdup("-"); - Free_Chunk(c2->part); - c2->part =0; - goto scan; - } - } - return 1; - scan: - for(c2=c1->part;c2;c2=c2->next) { - if (c2->type != unused) - continue; - if (!c2->next) - continue; - if (c2->next->type != unused) - continue; - c3 = c2->next; - c2->size += c3->size; - c2->end = c3->end; - c2->next = c3->next; - c3->next = 0; - Free_Chunk(c3); - goto scan; - } - Fixup_Names(d); - return 0; -} - -#if 0 -int -Collapse_Chunk(struct disk *d, struct chunk *c1) -{ - struct chunk *c2, *c3; - - if(c1->next && Collapse_Chunk(d,c1->next)) - return 1; - - if(c1->type == unused && c1->next && c1->next->type == unused) { - c3 = c1->next; - c1->size += c3->size; - c1->end = c3->end; - c1->next = c3->next; - c3->next = 0; - Free_Chunk(c3); - return 1; - } - c3 = c1->part; - if(!c3) - return 0; - if (Collapse_Chunk(d,c1->part)) - return 1; - - if (c1->type == whole) - return 0; - - if(c3->type == unused && c3->size == c1->size) { - Delete_Chunk(d,c1); - return 1; - } - if(c3->type == unused) { - c2 = new_chunk(); - if (!c2) err(1,"malloc failed"); - *c2 = *c1; - c1->next = c2; - c1->disk = d; - c1->name = strdup("-"); - c1->part = 0; - c1->type = unused; - c1->flags = 0; - c1->subtype = 0; - c1->size = c3->size; - c1->end = c3->end; - c2->offset += c1->size; - c2->size -= c1->size; - c2->part = c3->next; - c3->next = 0; - Free_Chunk(c3); - return 1; - } - for(c2=c3;c2->next;c2 = c2->next) - c3 = c2; - if (c2 && c2->type == unused) { - c3->next = 0; - c2->next = c1->next; - c1->next = c2; - c1->size -= c2->size; - c1->end -= c2->size; - return 1; - } - - return 0; -} -#endif diff --git a/lib/libdisk/create_chunk.c b/lib/libdisk/create_chunk.c deleted file mode 100644 index 5981ac15e54c..000000000000 --- a/lib/libdisk/create_chunk.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * $Id: create_chunk.c,v 1.21.2.5 1995/11/17 23:04:04 jkh Exp $ - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <ctype.h> -#include <fcntl.h> -#include <stdarg.h> -#include <sys/types.h> -#include <sys/disklabel.h> -#include <sys/diskslice.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <err.h> -#include "libdisk.h" - -/* Clone these two from sysinstall because we need our own copies - * due to link order problems with `crunch'. Feh! - */ -static int -isDebug() -{ - static int debug = 0; /* Allow debugger to tweak it */ - - return debug; -} - -/* Write something to the debugging port */ -static void -msgDebug(char *fmt, ...) -{ - va_list args; - char *dbg; - static int DebugFD = -1; - - if (DebugFD == -1) - DebugFD = open("/dev/ttyv1", O_RDWR); - dbg = (char *)alloca(FILENAME_MAX); - strcpy(dbg, "DEBUG: "); - va_start(args, fmt); - vsnprintf((char *)(dbg + strlen(dbg)), FILENAME_MAX, fmt, args); - va_end(args); - write(DebugFD, dbg, strlen(dbg)); -} - -void -Fixup_FreeBSD_Names(struct disk *d, struct chunk *c) -{ - struct chunk *c1, *c3; - int j; - - if (!strcmp(c->name, "X")) return; - - /* reset all names to "X" */ - for (c1 = c->part; c1 ; c1 = c1->next) { - c1->oname = c1->name; - c1->name = malloc(12); - if(!c1->name) err(1,"Malloc failed"); - strcpy(c1->name,"X"); - } - - /* Allocate the first swap-partition we find */ - for (c1 = c->part; c1 ; c1 = c1->next) { - if (c1->type == unused) continue; - if (c1->subtype != FS_SWAP) continue; - sprintf(c1->name,"%s%c",c->name,SWAP_PART+'a'); - break; - } - - /* Allocate the first root-partition we find */ - for (c1 = c->part; c1 ; c1 = c1->next) { - if (c1->type == unused) continue; - if (!(c1->flags & CHUNK_IS_ROOT)) continue; - sprintf(c1->name,"%s%c",c->name,0+'a'); - break; - } - - /* Try to give them the same as they had before */ - for (c1 = c->part; c1 ; c1 = c1->next) { - if (strcmp(c1->name,"X")) continue; - for(c3 = c->part; c3 ; c3 = c3->next) - if (c1 != c3 && !strcmp(c3->name, c1->oname)) { - goto newname; - } - strcpy(c1->name,c1->oname); - newname: - } - - - /* Allocate the rest sequentially */ - for (c1 = c->part; c1 ; c1 = c1->next) { - const char order[] = "efghabd"; - if (c1->type == unused) continue; - if (strcmp("X",c1->name)) continue; - - for(j=0;j<strlen(order);j++) { - sprintf(c1->name,"%s%c",c->name,order[j]); - for(c3 = c->part; c3 ; c3 = c3->next) - if (c1 != c3 && !strcmp(c3->name, c1->name)) - goto match; - break; - match: - strcpy(c1->name,"X"); - continue; - } - } - for (c1 = c->part; c1 ; c1 = c1->next) { - free(c1->oname); - c1->oname = 0; - } -} - -void -Fixup_Extended_Names(struct disk *d, struct chunk *c) -{ - struct chunk *c1; - int j=5; - - for (c1 = c->part; c1 ; c1 = c1->next) { - if (c1->type == unused) continue; - free(c1->name); - c1->name = malloc(12); - if(!c1->name) err(1,"malloc failed"); - sprintf(c1->name,"%ss%d",d->chunks->name,j++); - if (c1->type == freebsd) - Fixup_FreeBSD_Names(d,c1); - } -} - -void -Fixup_Names(struct disk *d) -{ - struct chunk *c1, *c2, *c3; - int i,j; - - c1 = d->chunks; - for(i=1,c2 = c1->part; c2 ; c2 = c2->next) { - c2->flags &= ~CHUNK_BSD_COMPAT; - if (c2->type == unused) - continue; - if (strcmp(c2->name,"X")) - continue; - c2->oname = malloc(12); - if(!c2->oname) err(1,"malloc failed"); - for(j=1;j<=NDOSPART;j++) { - sprintf(c2->oname,"%ss%d",c1->name,j); - for(c3 = c1->part; c3 ; c3 = c3->next) - if (c3 != c2 && !strcmp(c3->name, c2->oname)) - goto match; - free(c2->name); - c2->name = c2->oname; - c2->oname = 0; - break; - match: - continue; - } - if (c2->oname) - free(c2->oname); - } - for(c2 = c1->part; c2 ; c2 = c2->next) { - if (c2->type == freebsd) { - c2->flags |= CHUNK_BSD_COMPAT; - break; - } - } - for(c2 = c1->part; c2 ; c2 = c2->next) { - if (c2->type == freebsd) - Fixup_FreeBSD_Names(d,c2); - if (c2->type == extended) - Fixup_Extended_Names(d,c2); - } -} - -int -Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type, int subtype, u_long flags) -{ - int i; - u_long l; - - if(!(flags & CHUNK_FORCE_ALL)) - { - /* Never use the first track */ - if (!offset) { - offset += d->bios_sect; - size -= d->bios_sect; - } - - /* Always end on cylinder boundary */ - l = (offset+size) % (d->bios_sect * d->bios_hd); - size -= l; - } - - i = Add_Chunk(d,offset,size,"X",type,subtype,flags); - Fixup_Names(d); - return i; -} - -struct chunk * -Create_Chunk_DWIM(struct disk *d, struct chunk *parent , u_long size, chunk_e type, int subtype, u_long flags) -{ - int i; - struct chunk *c1; - u_long offset,edge; - - if (!parent) - parent = d->chunks; - for (c1=parent->part; c1 ; c1 = c1->next) { - if (c1->type != unused) continue; - if (c1->size < size) continue; - offset = c1->offset; - goto found; - } - warn("Not enough unused space"); - return 0; - found: - if (parent->flags & CHUNK_BAD144) { - edge = c1->end - d->bios_sect - 127; - if (offset > edge) - return 0; - if (offset + size > edge) - size = edge - offset + 1; - } - i = Add_Chunk(d,offset,size,"X",type,subtype,flags); - if (i) { - warn("Didn't cut it"); - return 0; - } - Fixup_Names(d); - for (c1=parent->part; c1 ; c1 = c1->next) - if (c1->offset == offset) - return c1; - err(1,"Serious internal trouble"); -} - -int -MakeDev(struct chunk *c1, char *path) -{ - char *p = c1->name; - u_long cmaj, bmaj, min, unit, part, slice; - char buf[BUFSIZ], buf2[BUFSIZ]; - - *buf2 = '\0'; - if (isDebug()) - msgDebug("MakeDev: Called with %s on path %s\n", p, path); - if (!strcmp(p, "X")) - return 0; - - if (!strncmp(p, "wd", 2)) - bmaj = 0, cmaj = 3; - else if (!strncmp(p, "sd", 2)) - bmaj = 4, cmaj = 13; - else { - return 0; - } - p += 2; - if (!isdigit(*p)) { - msgDebug("MakeDev: Invalid disk unit passed: %s\n", p); - return 0; - } - unit = *p - '0'; - p++; - if (!*p) { - slice = 1; - part = 2; - goto done; - } - else if (isdigit(*p)) { - unit *= 10; - unit += (*p - '0'); - p++; - } - if (*p != 's') { - msgDebug("MakeDev: `%s' is not a valid slice delimiter\n", p); - return 0; - } - p++; - if (!isdigit(*p)) { - msgDebug("MakeDev: `%s' is an invalid slice number\n", p); - return 0; - } - slice = *p - '0'; - p++; - if (isdigit(*p)) { - slice *= 10; - slice += (*p - '0'); - p++; - } - slice = slice + 1; - if (!*p) { - part = 2; - if(c1->type == freebsd) - sprintf(buf2, "%sc", c1->name); - goto done; - } - if (*p < 'a' || *p > 'h') { - msgDebug("MakeDev: `%s' is not a valid partition name.\n", p); - return 0; - } - part = *p - 'a'; - done: - if (isDebug()) - msgDebug("MakeDev: Unit %d, Slice %d, Part %d\n", unit, slice, part); - if (unit > 32) - return 0; - if (slice > 32) - return 0; - min = unit * 8 + 65536 * slice + part; - sprintf(buf, "%s/r%s", path, c1->name); - unlink(buf); - if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) { - msgDebug("mknod of %s returned failure status!\n", buf); - return 0; - } - if (*buf2) { - sprintf(buf, "%s/r%s", path, buf2); - unlink(buf); - if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) { - msgDebug("mknod of %s returned failure status!\n", buf); - return 0; - } - } - sprintf(buf, "%s/%s", path, c1->name); - unlink(buf); - if (mknod(buf, S_IFBLK|0640, makedev(bmaj,min)) == -1) { - msgDebug("mknod of %s returned failure status!\n", buf); - return 0; - } - return 1; -} - -int -MakeDevChunk(struct chunk *c1, char *path) -{ - int i; - - i = MakeDev(c1, path); - if (c1->next) - MakeDevChunk(c1->next, path); - if (c1->part) - MakeDevChunk(c1->part, path); - return i; -} - -int -MakeDevDisk(struct disk *d, char *path) -{ - return MakeDevChunk(d->chunks, path); -} diff --git a/lib/libdisk/disk.c b/lib/libdisk/disk.c deleted file mode 100644 index cfac7b528b2c..000000000000 --- a/lib/libdisk/disk.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * $Id: disk.c,v 1.19.2.2 1995/06/05 02:24:27 jkh Exp $ - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <err.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/disklabel.h> -#include <sys/diskslice.h> -#include "libdisk.h" - -#define DOSPTYP_EXTENDED 5 -#define DOSPTYP_ONTRACK 84 - -char *chunk_n[] = { - "whole", - "unknown", - "fat", - "freebsd", - "extended", - "part", - "unused", - NULL -}; - -struct disk * -Open_Disk(char *name) -{ - return Int_Open_Disk(name,0); -} - -struct disk * -Int_Open_Disk(char *name, u_long size) -{ - int i,fd; - struct diskslices ds; - struct disklabel dl; - char device[64]; - struct disk *d; - struct dos_partition *dp; - void *p; - u_long offset = 0; - - strcpy(device,"/dev/r"); - strcat(device,name); - - d = (struct disk *)malloc(sizeof *d); - if(!d) err(1,"malloc failed"); - memset(d,0,sizeof *d); - - fd = open(device,O_RDONLY); - if (fd < 0) { - warn("open(%s) failed",device); - return 0; - } - - memset(&dl,0,sizeof dl); - ioctl(fd,DIOCGDINFO,&dl); - i = ioctl(fd,DIOCGSLICEINFO,&ds); - if (i < 0) { - warn("DIOCGSLICEINFO(%s) failed",device); - close(fd); - return 0; - } - -#ifdef DEBUG - for(i=0;i<ds.dss_nslices;i++) - if(ds.dss_slices[i].ds_openmask) - printf(" open(%d)=0x%2x", - i,ds.dss_slices[i].ds_openmask); - printf("\n"); -#endif - - if (!size) - size = ds.dss_slices[WHOLE_DISK_SLICE].ds_size; - - p = read_block(fd,0); - dp = (struct dos_partition*)(p+DOSPARTOFF); - for(i=0;i<NDOSPART;i++) { - if (dp->dp_start >= size) continue; - if (dp->dp_start+dp->dp_size >= size) continue; - if (!dp->dp_size) continue; - - if (dp->dp_typ == DOSPTYP_ONTRACK) { - d->flags |= DISK_ON_TRACK; - offset = 63; - } - - } - free(p); - - d->bios_sect = dl.d_nsectors; - d->bios_hd = dl.d_ntracks; - - d->name = strdup(name); - - - if (dl.d_ntracks && dl.d_nsectors) - d->bios_cyl = size/(dl.d_ntracks*dl.d_nsectors); - - if (Add_Chunk(d, -offset, size, name,whole,0,0)) - warn("Failed to add 'whole' chunk"); - - for(i=BASE_SLICE;i<ds.dss_nslices;i++) { - char sname[20]; - chunk_e ce; - u_long flags=0; - int subtype=0; - if (! ds.dss_slices[i].ds_size) - continue; - ds.dss_slices[i].ds_offset -= offset; - sprintf(sname,"%ss%d",name,i-1); - subtype = ds.dss_slices[i].ds_type; - switch (ds.dss_slices[i].ds_type) { - case 0xa5: - ce = freebsd; - break; - case 0x1: - case 0x6: - case 0x4: - ce = fat; - break; - case DOSPTYP_EXTENDED: - ce = extended; - break; - default: - ce = unknown; - break; - } - if (Add_Chunk(d,ds.dss_slices[i].ds_offset, - ds.dss_slices[i].ds_size, sname,ce,subtype,flags)) - warn("failed to add chunk for slice %d",i - 1); - - if (ds.dss_slices[i].ds_type != 0xa5) - continue; - { - struct disklabel dl; - char pname[20]; - int j,k; - - strcpy(pname,"/dev/r"); - strcat(pname,sname); - j = open(pname,O_RDONLY); - if (j < 0) { - warn("open(%s)",pname); - continue; - } - k = ioctl(j,DIOCGDINFO,&dl); - if (k < 0) { - warn("ioctl(%s,DIOCGDINFO)",pname); - close(j); - continue; - } - close(j); - - for(j=0; j <= dl.d_npartitions; j++) { - if (j == RAW_PART) - continue; - if (j == 3) - continue; - if (j == dl.d_npartitions) { - j = 3; - dl.d_npartitions=0; - } - if (!dl.d_partitions[j].p_size) - continue; - if (dl.d_partitions[j].p_size + - dl.d_partitions[j].p_offset > - ds.dss_slices[i].ds_size) - continue; - sprintf(pname,"%s%c",sname,j+'a'); - if (Add_Chunk(d, - dl.d_partitions[j].p_offset + - ds.dss_slices[i].ds_offset, - dl.d_partitions[j].p_size, - pname,part, - dl.d_partitions[j].p_fstype, - 0) && j != 3) - warn( - "Failed to add chunk for partition %c [%lu,%lu]", - j + 'a',dl.d_partitions[j].p_offset, - dl.d_partitions[j].p_size); - } - } - } - close(fd); - Fixup_Names(d); - Bios_Limit_Chunk(d->chunks,1024*d->bios_hd*d->bios_sect); - return d; -} - -void -Debug_Disk(struct disk *d) -{ - printf("Debug_Disk(%s)",d->name); - printf(" flags=%lx",d->flags); -#if 0 - printf(" real_geom=%lu/%lu/%lu",d->real_cyl,d->real_hd,d->real_sect); -#endif - printf(" bios_geom=%lu/%lu/%lu\n",d->bios_cyl,d->bios_hd,d->bios_sect); - printf(" boot1=%p, boot2=%p, bootmgr=%p\n", - d->boot1,d->boot2,d->bootmgr); - Debug_Chunk(d->chunks); -} - -void -Free_Disk(struct disk *d) -{ - if(d->chunks) Free_Chunk(d->chunks); - if(d->name) free(d->name); - if(d->bootmgr) free(d->bootmgr); - if(d->boot1) free(d->boot1); - if(d->boot2) free(d->boot2); - free(d); -} - -struct disk * -Clone_Disk(struct disk *d) -{ - struct disk *d2; - - d2 = (struct disk*) malloc(sizeof *d2); - if(!d2) err(1,"malloc failed"); - *d2 = *d; - d2->name = strdup(d2->name); - d2->chunks = Clone_Chunk(d2->chunks); - if(d2->bootmgr) { - d2->bootmgr = malloc(DOSPARTOFF); - memcpy(d2->bootmgr,d->bootmgr,DOSPARTOFF); - } - if(d2->boot1) { - d2->boot1 = malloc(512); - memcpy(d2->boot1,d->boot1,512); - } - if(d2->boot2) { - d2->boot2 = malloc(512*15); - memcpy(d2->boot2,d->boot2,512*15); - } - return d2; -} - -#if 0 -void -Collapse_Disk(struct disk *d) -{ - - while(Collapse_Chunk(d,d->chunks)) - ; -} -#endif - -static char * device_list[] = {"wd","sd",0}; - -char ** -Disk_Names() -{ - int i,j,k; - char disk[25]; - char diskname[25]; - struct stat st; - struct diskslices ds; - int fd; - static char **disks; - - disks = malloc(sizeof *disks * (1 + MAX_NO_DISKS)); - memset(disks,0,sizeof *disks * (1 + MAX_NO_DISKS)); - k = 0; - for (j = 0; device_list[j]; j++) { - for (i = 0; i < 10; i++) { - sprintf(diskname, "%s%d", device_list[j], i); - sprintf(disk, "/dev/r%s", diskname); - if (stat(disk, &st) || !(st.st_mode & S_IFCHR)) - continue; - if ((fd = open(disk, O_RDWR)) == -1) - continue; - if (ioctl(fd, DIOCGSLICEINFO, &ds) == -1) { - close(fd); - continue; - } - disks[k++] = strdup(diskname); - if(k == MAX_NO_DISKS) - return disks; - } - } - return disks; -} - -void -Set_Boot_Mgr(struct disk *d, u_char *b) -{ - if (d->bootmgr) - free(d->bootmgr); - if (!b) { - d->bootmgr = 0; - } else { - d->bootmgr = malloc(DOSPARTOFF); - if(!d->bootmgr) err(1,"malloc failed"); - memcpy(d->bootmgr,b,DOSPARTOFF); - } -} - -void -Set_Boot_Blocks(struct disk *d, u_char *b1, u_char *b2) -{ - if (d->boot1) free(d->boot1); - d->boot1 = malloc(512); - if(!d->boot1) err(1,"malloc failed"); - memcpy(d->boot1,b1,512); - if (d->boot2) free(d->boot2); - d->boot2 = malloc(15*512); - if(!d->boot2) err(1,"malloc failed"); - memcpy(d->boot2,b2,15*512); -} diff --git a/lib/libdisk/disklabel.c b/lib/libdisk/disklabel.c deleted file mode 100644 index 9714e6c28f2e..000000000000 --- a/lib/libdisk/disklabel.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * $Id$ - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <err.h> -#include <sys/disklabel.h> -#include "libdisk.h" - -struct disklabel * -read_disklabel(int fd, daddr_t block) -{ - struct disklabel *dp; - - dp = (struct disklabel *) read_block(fd,block); - if (dp->d_magic != DISKMAGIC) - return 0; - if (dp->d_magic2 != DISKMAGIC) - return 0; - if (dkcksum(dp) != 0) - return 0; - return dp; -} diff --git a/lib/libdisk/libdisk.h b/lib/libdisk/libdisk.h deleted file mode 100644 index 48326347180a..000000000000 --- a/lib/libdisk/libdisk.h +++ /dev/null @@ -1,324 +0,0 @@ -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * $Id: libdisk.h,v 1.19.2.1 1995/09/20 10:43:03 jkh Exp $ - * - */ - -#define MAX_NO_DISKS 20 - /* Max # of disks Disk_Names() will return */ - -typedef enum { - whole, - unknown, - fat, - freebsd, - extended, - part, - unused, - } chunk_e; - -extern char *chunk_n[]; - -struct disk { - char *name; - u_long flags; -# define DISK_ON_TRACK 1 -#if 0 - u_long real_cyl; - u_long real_hd; - u_long real_sect; -#endif - u_long bios_cyl; - u_long bios_hd; - u_long bios_sect; - u_char *bootmgr; - u_char *boot1; - u_char *boot2; - struct chunk *chunks; -}; - -struct chunk { - struct chunk *next; - struct chunk *part; - struct disk *disk; - long offset; - u_long size; - u_long end; - char *name; - char *oname; - /* Used during Fixup_Names() to avoid renaming more than - * absolutely needed. - */ - chunk_e type; - int subtype; - u_long flags; -# define CHUNK_PAST_1024 1 - /* this chunk cannot be booted from because it - * extends past cylinder 1024 - */ -# define CHUNK_BSD_COMPAT 2 - /* this chunk is in the BSD-compatibility, and has a - * short name too, ie wd0s4f -> wd0f - */ -# define CHUNK_BAD144 4 - /* this chunk has bad144 mapping */ -# define CHUNK_ALIGN 8 - /* This chunk should be aligned */ -# define CHUNK_IS_ROOT 16 - /* This 'part' is a rootfs, allocate 'a' */ -# define CHUNK_ACTIVE 32 - /* This is the active slice in the MBR */ -# define CHUNK_FORCE_ALL 64 - /* Force a dedicated disk for FreeBSD, bypassing - * all BIOS geometry considerations - */ - - void (*private_free)(void*); - void *(*private_clone)(void*); - void *private; - /* For data private to the application, and the management - * thereof. If the functions are not provided, no storage - * management is done, Cloning will just copy the pointer - * and freeing will just forget it. - */ -}; - -struct disk * -Open_Disk(char *devname); - /* Will open the named disk, and return populated tree. - */ - -struct disk * -Clone_Disk(struct disk *disk); - /* Clone a copy of a tree. Useful for "Undo" functionality - */ - -void -Free_Disk(struct disk *disk); - /* Free a tree made with Open_Disk() or Clone_Disk() - */ - -void -Debug_Disk(struct disk *disk); - /* Print the content of the tree to stdout - */ - -#if 0 -struct disk * -Set_Phys_Geom(struct disk *disk, u_long cyl, u_long heads, u_long sects); - /* Use a different physical geometry. Makes sense for ST506 disks only. - * The tree returned is read from the disk, using this geometry. - */ -#endif - -void -Set_Bios_Geom(struct disk *disk, u_long cyl, u_long heads, u_long sects); - /* Set the geometry the bios uses. - */ - -int -Delete_Chunk(struct disk *disk, struct chunk *); - /* Free a chunk of disk_space - */ - -void -Collapse_Disk(struct disk *disk); - /* Experimental, do not use. - */ -int -Collapse_Chunk(struct disk *disk, struct chunk *chunk); - /* Experimental, do not use. - */ - -int -Create_Chunk(struct disk *disk, u_long offset, u_long size, chunk_e type, int subtype, u_long flags); - /* Create a chunk with the specified paramters - */ - -void -All_FreeBSD(struct disk *d, int force_all); - /* Make one FreeBSD chunk covering the entire disk; - * if force_all is set, bypass all BIOS geometry - * considerations. - */ - -char * -CheckRules(struct disk *); - /* Return char* to warnings about broken design rules in this disklayout - */ - -char ** -Disk_Names(); - /* Return char** with all disk's names (wd0, wd1 ...). You must free - * each pointer, as well as the array by hand - */ - -void -Set_Boot_Mgr(struct disk *d, u_char *bootmgr); - /* Use this boot-manager on this disk. Gets written when Write_Disk() - * is called - */ - -void -Set_Boot_Blocks(struct disk *d, u_char *boot1, u_char *boot2); - /* Use these boot-blocks on this disk. Gets written when Write_Disk() - * is called - */ - -int -Write_Disk(struct disk *d); - /* Write all the MBRs, disklabels, bootblocks and boot managers - */ - -int -Cyl_Aligned(struct disk *d, u_long offset); - /* Check if offset is aligned on a cylinder according to the - * bios geometry - */ - -u_long -Next_Cyl_Aligned(struct disk *d, u_long offset); - /* Round offset up to next cylinder according to the bios-geometry - */ - -u_long -Prev_Cyl_Aligned(struct disk *d, u_long offset); - /* Round offset down to previous cylinder according to the bios- - * geometry - */ - -int -Track_Aligned(struct disk *d, u_long offset); - /* Check if offset is aligned on a track according to the - * bios geometry - */ - -u_long -Next_Track_Aligned(struct disk *d, u_long offset); - /* Round offset up to next track according to the bios-geometry - */ - -u_long -Prev_Track_Aligned(struct disk *d, u_long offset); - /* Check if offset is aligned on a track according to the - * bios geometry - */ - -struct chunk * -Create_Chunk_DWIM(struct disk *d, struct chunk *parent , u_long size, chunk_e type, int subtype, u_long flags); - /* This one creates a partition inside the given parent of the given - * size, and returns a pointer to it. The first unused chunk big - * enough is used. - */ - -int -MakeDev(struct chunk *c, char *path); - -int -MakeDevDisk(struct disk *d,char *path); - /* Make device nodes for all chunks on this disk */ - -char * -ShowChunkFlags(struct chunk *c); - /* Return string to show flags. */ - -char * -ChunkCanBeRoot(struct chunk *c); - /* Return NULL if chunk can be /, explanation otherwise */ - -/* - * Implementation details >>> DO NOT USE <<< - */ - -void Debug_Chunk(struct chunk *); -void Free_Chunk(struct chunk *); -struct chunk * Clone_Chunk(struct chunk *); -int Add_Chunk(struct disk *, long , u_long , char *, chunk_e, int , u_long); -void Bios_Limit_Chunk(struct chunk *, u_long); -void * read_block(int, daddr_t ); -void write_block(int fd, daddr_t block, void *foo); -struct disklabel * read_disklabel(int, daddr_t); -u_short dkcksum(struct disklabel *); -struct chunk * Find_Mother_Chunk(struct chunk *, u_long , u_long , chunk_e); -struct disk * Int_Open_Disk(char *name, u_long size); -void Fixup_Names(struct disk *); - -#define dprintf printf - -/* TODO - * - * Need a error string mechanism from the functions instead of warn() - * - * Make sure only FreeBSD start at offset==0 - * - * Collapse must align. - * - * Make Write_Disk(struct disk*) - * - * Consider booting from OnTrack'ed disks. - * - * Get Bios-geom, ST506 & OnTrack from driver (or otherwise) - * - * Make Create_DWIM(). - * - * Make Is_Unchanged(struct disk *d1, struct chunk *c1) - * - * don't rename slices unless we have to - * - *Sample output from tst01: - * - * Debug_Disk(wd0) flags=0 real_geom=0/0/0 bios_geom=0/0/0 - * >> 0x3d040 0 1411200 1411199 wd0 0 whole 0 0 - * >>>> 0x3d080 0 960120 960119 wd0s1 3 freebsd 0 8 - * >>>>>> 0x3d100 0 40960 40959 wd0s1a 5 part 0 0 - * >>>>>> 0x3d180 40960 131072 172031 wd0s1b 5 part 0 0 - * >>>>>> 0x3d1c0 172032 409600 581631 wd0s1e 5 part 0 0 - * >>>>>> 0x3d200 581632 378488 960119 wd0s1f 5 part 0 0 - * >>>> 0x3d140 960120 5670 965789 wd0s2 4 extended 0 8 - * >>>>>> 0x3d2c0 960120 63 960182 - 6 unused 0 0 - * >>>>>> 0x3d0c0 960183 5607 965789 wd0s5 2 fat 0 8 - * >>>> 0x3d280 965790 1890 967679 wd0s3 1 foo -2 8 - * >>>> 0x3d300 967680 443520 1411199 wd0s4 3 freebsd 0 8 - * >>>>>> 0x3d340 967680 443520 1411199 wd0s4a 5 part 0 0 - * - * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ - * level chunkptr start size end name type subtype flags - * - * Underlying data structure: - * - * Legend: - * <struct chunk> --> part - * | - * v next - * - * <wd0> --> <wd0s1> --> <wd0s1a> - * | | - * | v - * | <wd0s1b> - * | | - * | v - * | <wd0s1e> - * | | - * | v - * | <wd0s1f> - * | - * v - * <wd0s2> --> <unused> - * | | - * | v - * | <wd0s5> - * | - * v - * <wd0s3> - * | - * v - * <wd0s4> --> <wd0s4a> - * - * - */ diff --git a/lib/libdisk/rules.c b/lib/libdisk/rules.c deleted file mode 100644 index 1ea9ca85b162..000000000000 --- a/lib/libdisk/rules.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * $Id: rules.c,v 1.10.2.1 1995/06/03 08:40:33 jkh Exp $ - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/types.h> -#include <sys/diskslice.h> -#include <sys/disklabel.h> -#include <err.h> -#include "libdisk.h" - -int -Track_Aligned(struct disk *d, u_long offset) -{ - if (!d->bios_sect) - return 1; - if (offset % d->bios_sect) - return 0; - return 1; -} - -u_long -Prev_Track_Aligned(struct disk *d, u_long offset) -{ - if (!d->bios_sect) - return offset; - return (offset / d->bios_sect) * d->bios_sect; -} - -u_long -Next_Track_Aligned(struct disk *d, u_long offset) -{ - if (!d->bios_sect) - return offset; - return Prev_Track_Aligned(d,offset + d->bios_sect-1); -} - -int -Cyl_Aligned(struct disk *d, u_long offset) -{ - if (!d->bios_sect || !d->bios_hd) - return 1; - if (offset % (d->bios_sect * d->bios_hd)) - return 0; - return 1; -} - -u_long -Prev_Cyl_Aligned(struct disk *d, u_long offset) -{ - if (!d->bios_sect || !d->bios_hd) - return offset; - return (offset / (d->bios_sect*d->bios_hd)) * d->bios_sect * d->bios_hd; -} - -u_long -Next_Cyl_Aligned(struct disk *d, u_long offset) -{ - if (!d->bios_sect || !d->bios_hd) - return offset; - return Prev_Cyl_Aligned(d,offset + (d->bios_sect * d->bios_hd)-1); -} - -/* - * Rule#0: - * Chunks of type 'whole' can have max NDOSPART children. - * Only one of them can have the "active" flag - */ -void -Rule_000(struct disk *d, struct chunk *c, char *msg) -{ - int i=0,j=0; - struct chunk *c1; - - if (c->type != whole) - return; - for (c1=c->part; c1; c1=c1->next) { - if (c1->type != unused) continue; - if (c1->flags & CHUNK_ACTIVE) - j++; - i++; - } - if (i > NDOSPART) - sprintf(msg+strlen(msg), - "%d is too many children of the 'whole' chunk. Max is %d\n", - i, NDOSPART); - if (j > 1) - sprintf(msg+strlen(msg), - "Too many active children of 'whole'"); -} - -/* - * Rule#1: - * All children of 'whole' and 'extended' must be track-aligned. - * Exception: the end can be unaligned if it matches the end of 'whole' - */ -void -Rule_001(struct disk *d, struct chunk *c, char *msg) -{ - int i; - struct chunk *c1; - - if (c->type != whole && c->type != extended) - return; - for (i=0, c1=c->part; c1; c1=c1->next) { - if (c1->type == unused) continue; - c1->flags |= CHUNK_ALIGN; - if (!Track_Aligned(d,c1->offset)) - sprintf(msg+strlen(msg), - "chunk '%s' [%ld..%ld] does not start on a track boundary\n", - c1->name,c1->offset,c1->end); - if ((c->type == whole || c->end == c1->end) - || Cyl_Aligned(d,c1->end+1)) - ; - else - sprintf(msg+strlen(msg), - "chunk '%s' [%ld..%ld] does not end on a cylinder boundary\n", - c1->name,c1->offset,c1->end); - } -} - -/* - * Rule#2: - * Max one 'fat' as child of 'whole' - */ -void -Rule_002(struct disk *d, struct chunk *c, char *msg) -{ - int i; - struct chunk *c1; - - if (c->type != whole) - return; - for (i=0, c1=c->part; c1; c1=c1->next) { - if (c1->type != fat) - continue; - i++; - } - if (i > 1) { - sprintf(msg+strlen(msg), - "Max one 'fat' allowed as child of 'whole'\n"); - } -} - -/* - * Rule#3: - * Max one extended as child of 'whole' - */ -void -Rule_003(struct disk *d, struct chunk *c, char *msg) -{ - int i; - struct chunk *c1; - - if (c->type != whole) - return; - for (i=0, c1=c->part; c1; c1=c1->next) { - if (c1->type != extended) - continue; - i++; - } - if (i > 1) { - sprintf(msg+strlen(msg), - "Max one 'extended' allowed as child of 'whole'\n"); - } -} - -/* - * Rule#4: - * Max seven 'part' as children of 'freebsd' - * Max one CHUNK_IS_ROOT child per 'freebsd' - * If Bad144, space for table must exist. - * If Bad144 & root, bad144 table must be inside 1024 - */ -void -Rule_004(struct disk *d, struct chunk *c, char *msg) -{ - int i=0,k=0; - struct chunk *c1; - u_long l; - - if (c->type != freebsd) - return; - - if (c->flags & CHUNK_BAD144) { - l = c->end - 127 - d->bios_sect + 1; - for (c1=c->part; c1; c1=c1->next) { - if (c1->end < l || c1->type == unused) - continue; - sprintf(msg+strlen(msg), - "Blocks %lu to %lu are needed for bad144 information, but isn't unused.\n", - l, c->end); - break; - } - if (c->flags & CHUNK_PAST_1024) { - for (c1=c->part; c1; c1=c1->next) { - if (c1->flags & CHUNK_IS_ROOT) { - sprintf(msg+strlen(msg), - "You have assigned root to a slice which uses bad144, and\n extends past the first 1023 cylinders, and thus cannot be booted from.\n"); - break; - } - } - } - } - - for (c1=c->part; c1; c1=c1->next) { - if (c1->type != part) - continue; - if (c1->flags & CHUNK_IS_ROOT) { - k++; - if (c1->flags & CHUNK_PAST_1024) - sprintf(msg+strlen(msg), - "Root filesystem extends past cylinder 1024, and cannot be booted from\n"); - } - i++; - } - if (i > 7) { - sprintf(msg+strlen(msg), - "Max seven partitions per freebsd slice\n"); - } - if (k > 1) { - sprintf(msg+strlen(msg), - "Max one root partition child per freebsd slice\n"); - } -} - -void -Check_Chunk(struct disk *d, struct chunk *c, char *msg) -{ - Rule_000(d,c,msg); - Rule_001(d,c,msg); - Rule_002(d,c,msg); - Rule_003(d,c,msg); - Rule_004(d,c,msg); - if (c->part) - Check_Chunk(d,c->part,msg); - if (c->next) - Check_Chunk(d,c->next,msg); - - if (c->end >= 1024*d->bios_hd*d->bios_sect) - c->flags |= CHUNK_PAST_1024; - else - c->flags &= ~CHUNK_PAST_1024; -} - -char * -CheckRules(struct disk *d) -{ - char msg[BUFSIZ]; - - *msg = '\0'; - Check_Chunk(d,d->chunks,msg); - if (*msg) - return strdup(msg); - return 0; -} - -char * -ChunkCanBeRoot(struct chunk *c) -{ - struct chunk *c1; - struct disk *d = c->disk; - char msg[BUFSIZ]; - - *msg = '\0'; - if (c->flags & CHUNK_PAST_1024) { - strcat(msg, -"The root partition must end before cylinder 1024 seen from\n"); - strcat(msg, -"the BIOS' point of view, or it cannot be booted from.\n"); - return strdup(msg); - } - for (c1=d->chunks->part;;) { - for (; c1; c1=c1->next) - if (c1->offset <= c->offset && c1->end >= c->end) - break; - if (!c1) { - strcat(msg, -"Internal trouble, cannot find this chunk in the chunk-tree\n"); - return strdup(msg); - } - if (c1->type == freebsd) - break; - c1 = c1->part; - } - - if (c1->type != freebsd) { - strcat(msg, -"The root partition must be in a FreeBSD slice, otherwise\n"); - strcat(msg, -"the kernel cannot be booted from it\n"); - return strdup(msg); - } - - if ((c1->flags & CHUNK_BAD144) && (c1->flags & CHUNK_PAST_1024)) { - strcat(msg, -"This partition is unsuitable for root, because the FreeBSD slice\n"); - strcat(msg, -"it is inside has bad144 enabled, but the badblock data lives past\n"); - strcat(msg, -"the 1024th cylinder, and the bootblocks cannot get to it there.\n"); - return strdup(msg); - } - return NULL; -} diff --git a/lib/libdisk/tst01.c b/lib/libdisk/tst01.c deleted file mode 100644 index 93286c7c1065..000000000000 --- a/lib/libdisk/tst01.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * $Id: tst01.c,v 1.15 1995/06/11 19:29:37 rgrimes Exp $ - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <err.h> -#ifdef READLINE -#include <readline/readline.h> -#include <readline/history.h> -#endif -#include <sys/types.h> -#include "libdisk.h" - -u_char mbr[] = { -250,51,192,142,208,188,0,124,139,244,80,7,80,31,251,252,191,0,6,185,0,1, -242,165,234,29,6,0,0,190,190,7,179,4,128,60,128,116,14,128,60,0,117,28, -131,198,16,254,203,117,239,205,24,139,20,139,76,2,139,238,131,198,16,254, -203,116,26,128,60,0,116,244,190,139,6,172,60,0,116,11,86,187,7,0,180,14, -205,16,94,235,240,235,254,191,5,0,187,0,124,184,1,2,87,205,19,95,115,12, -51,192,205,19,79,117,237,190,163,6,235,211,190,194,6,191,254,125,129,61, -85,170,117,199,139,245,234,0,124,0,0,73,110,118,97,108,105,100,32,112,97, -114,116,105,116,105,111,110,32,116,97,98,108,101,0,69,114,114,111,114,32, -108,111,97,100,105,110,103,32,111,112,101,114,97,116,105,110,103,32,115, -121,115,116,101,109,0,77,105,115,115,105,110,103,32,111,112,101,114,97, -116,105,110,103,32,115,121,115,116,101,109,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, -1,1,0,4,15,63,60,63,0,0,0,241,239,0,0,0,0,1,61,5,15,63,243,48,240,0,0,144, -208,2,0,0,0,1,244,165,15,63,170,192,192,3,0,144,208,2,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,85,170 -}; - -u_char bteasy17[] = { -51,192,142,192,142,216,142,208,188,0,124,252,139,244,191,0,6,185,0,1,242, -165,234,96,6,0,0,139,213,88,162,72,7,60,53,116,28,180,16,246,228,5,174, -4,150,246,68,4,255,116,62,198,4,128,232,218,0,138,116,1,139,76,2,235,8, -232,207,0,185,1,0,50,209,187,0,124,184,1,2,205,19,114,30,129,191,254,1, -85,170,117,22,234,0,124,0,0,128,250,129,116,2,178,128,139,234,66,128,242, -179,136,22,58,7,191,190,7,185,4,0,198,6,45,7,49,50,246,136,45,138,69,4, -60,0,116,35,60,5,116,31,254,198,190,42,7,232,113,0,190,72,7,70,70,139,28, -10,255,116,5,50,125,4,117,243,141,183,114,7,232,90,0,131,199,16,254,6,45, -7,226,203,128,62,117,4,2,116,11,190,59,7,10,246,117,10,205,24,235,172,190, -42,7,232,57,0,232,54,0,50,228,205,26,139,218,131,195,96,180,1,205,22,180, -0,117,11,205,26,59,211,114,242,160,72,7,235,10,205,22,138,196,60,28,116, -243,4,246,60,49,114,214,60,53,119,210,80,190,40,7,187,27,6,83,252,172,80, -36,127,180,14,205,16,88,168,128,116,242,195,86,184,1,3,187,0,6,185,1,0, -50,246,205,19,94,198,6,72,7,63,195,13,138,13,10,70,48,32,46,32,46,32,46, -160,100,105,115,107,32,49,13,10,10,68,101,102,97,117,108,116,58,32,70,63, -160,0,1,0,4,0,6,3,7,7,10,10,99,14,100,14,101,20,128,20,129,25,130,30,147, -36,165,39,159,43,117,47,82,47,219,50,64,55,242,61,0,100,111,243,72,80,70, -211,79,115,178,85,110,105,248,78,111,118,101,108,236,77,105,110,105,248, -76,105,110,117,248,65,109,111,101,98,225,66,83,196,66,83,68,233,80,67,73, -216,67,80,205,86,101,110,105,248,68,111,115,115,101,227,63,191,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,85,170 -}; - -int -scan_block(int fd, daddr_t block) -{ - u_char foo[512]; - - if (-1 == lseek(fd,block * 512,SEEK_SET)) - err(1,"lseek"); - if (512 != read(fd,foo, 512)) - return 1; - return 0; -} - -void -Scan_Disk(struct disk *d) -{ - char device[64]; - u_long l; - int i,j,fd; - - strcpy(device,"/dev/r"); - strcat(device,d->name); - - fd = open(device,O_RDWR); - if (fd < 0) { - warn("open(%s) failed",device); - return; - } - for(i=-1,l=0;;l++) { - j = scan_block(fd,l); - if (j != i) { - if (i == -1) { - printf("%c: %lu.",j ? 'B' : 'G', l); - fflush(stdout); - } else if (i == 0) { - printf(".%lu\nB: %lu.",l-1,l); - fflush(stdout); - } else { - printf(".%lu\nG: %lu.",l-1,l); - fflush(stdout); - } - i = j; - } - } - close(fd); -} - -int -main(int argc, char **argv) -{ - struct disk *d,*db; - char myprompt[BUFSIZ]; -#ifndef READLINE - char input[BUFSIZ]; -#endif - char *p,*q=0; - char **cp,*cmds[200]; - int ncmd,i; - - if (argc < 2) { - fprintf(stderr,"Usage:\n\t%s diskname\n",argv[0]); - exit(1); - } - d = Open_Disk(argv[1]); - if (!d) - err(1,"Couldn't open disk %s",argv[1]); - - sprintf(myprompt,"%s %s> ",argv[0],argv[1]); - while(1) { - printf("--==##==--\n"); - p = CheckRules(d); - Debug_Disk(d); - if (p) { - printf("%s",p); - free(p); - } -#ifdef READLINE - if (q) - free(q); - q = p = readline(myprompt); -#else - printf(myprompt); - fflush(stdout); - q = p = fgets(input,sizeof(input),stdin); -#endif - if(!p) - break; - for(cp = cmds; (*cp = strsep(&p, " \t\n")) != NULL;) - if (**cp != '\0') - cp++; - ncmd = cp - cmds; - if(!ncmd) - continue; - if (!strcasecmp(*cmds,"quit")) { break; } - if (!strcasecmp(*cmds,"exit")) { break; } - if (!strcasecmp(*cmds,"q")) { break; } - if (!strcasecmp(*cmds,"x")) { break; } - if (!strcasecmp(*cmds,"dwim") && ncmd == 6) { - printf("dwim = %p\n", - Create_Chunk_DWIM(d, - (struct chunk *)strtol(cmds[1],0,0), - strtol(cmds[2],0,0), - strtol(cmds[3],0,0), - strtol(cmds[4],0,0), - strtol(cmds[5],0,0))); - continue; - } - if (!strcasecmp(*cmds,"mknod")) { - MakeDevDisk(d,"/tmp"); - continue; - } - if (!strcasecmp(*cmds,"delete") && ncmd == 2) { - printf("delete = %d\n", - Delete_Chunk(d, - (struct chunk *)strtol(cmds[1],0,0))); - continue; - } - if (!strcasecmp(*cmds,"allfreebsd")) { - All_FreeBSD(d, 0); - continue; - } - if (!strcasecmp(*cmds,"dedicate")) { - All_FreeBSD(d, 1); - continue; - } - if (!strcasecmp(*cmds,"bios") && ncmd == 4) { - Set_Bios_Geom(d, - strtol(cmds[1],0,0), - strtol(cmds[2],0,0), - strtol(cmds[3],0,0)); - continue; - } -#if 0 - if (!strcasecmp(*cmds,"phys") && ncmd == 4) { - d = Set_Phys_Geom(d, - strtol(cmds[1],0,0), - strtol(cmds[2],0,0), - strtol(cmds[3],0,0)); - continue; - } -#endif -#if 0 - if (!strcasecmp(*cmds,"collapse")) { - if (cmds[1]) - while (Collapse_Chunk(d, - (struct chunk *)strtol(cmds[1],0,0))) - ; - else - Collapse_Disk(d); - continue; - } -#endif - if (!strcasecmp(*cmds,"list")) { - cp = Disk_Names(); - printf("Disks:"); - for(i=0;cp[i];i++) { - printf(" %s",cp[i]); - free(cp[i]); - } - free(cp); - continue; - } - if (!strcasecmp(*cmds,"create") && ncmd == 6) { - - printf("Create=%d\n", - Create_Chunk(d, - strtol(cmds[1],0,0), - strtol(cmds[2],0,0), - strtol(cmds[3],0,0), - strtol(cmds[4],0,0), - strtol(cmds[5],0,0))); - continue; - } - if (!strcasecmp(*cmds,"read")) { - db = d; - if (ncmd > 1) - d = Open_Disk(cmds[1]); - else - d = Open_Disk(argv[1]); - if (d) - Free_Disk(db); - else - d = db; - continue; - } - if (!strcasecmp(*cmds,"scan")) { - Scan_Disk(d); - continue; - } - if (!strcasecmp(*cmds,"bteasy")) { - Set_Boot_Mgr(d,bteasy17); - continue; - } - if (!strcasecmp(*cmds,"mbr")) { - Set_Boot_Mgr(d,mbr); - continue; - } - if (!strcasecmp(*cmds,"boot")) { - extern u_char boot1[],boot2[]; - Set_Boot_Blocks(d,boot1,boot2); - continue; - } - if (!strcasecmp(*cmds,"write")) { - printf("Write=%d\n", - Write_Disk(d)); - Free_Disk(d); - d = Open_Disk(d->name); - continue; - } - if (strcasecmp(*cmds,"help")) - printf("\007ERROR\n"); - printf("CMDS:\n"); - printf("\tallfreebsd\n"); - printf("\tdedicate\n"); - printf("\tbios cyl hd sect\n"); - printf("\tboot\n"); - printf("\tbteasy17\n"); -#if 0 - printf("\tcollapse [pointer]\n"); -#endif - printf("\tcreate offset size enum subtype flags\n"); - printf("\t\tsubtype(part): swap=1, ffs=7\n"); - printf("\tdelete pointer\n"); - printf("\tlist\n"); - printf("\tmbr\n"); -#if 0 - printf("\tphys cyl hd sect\n"); -#endif - printf("\tquit\n"); - printf("\tread [disk]\n"); - printf("\tscan\n"); - printf("\twrite\n"); - printf("\nENUM:\n\t"); - for(i=0;chunk_n[i];i++) - printf("%d = %s%s",i,chunk_n[i],i == 4 ? "\n\t" : " "); - printf("\n"); - - } - exit (0); -} diff --git a/lib/libdisk/write_disk.c b/lib/libdisk/write_disk.c deleted file mode 100644 index f592dafae397..000000000000 --- a/lib/libdisk/write_disk.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * $Id: write_disk.c,v 1.14.2.1 1995/07/21 11:22:38 rgrimes Exp $ - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <err.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/disklabel.h> -#include <sys/diskslice.h> -#include "libdisk.h" - -#define DOSPTYP_EXTENDED 5 -#define BBSIZE 8192 -#define SBSIZE 8192 -#define DEF_RPM 3600 -#define DEF_INTERLEAVE 1 - -#define WHERE(offset,disk) (disk->flags & DISK_ON_TRACK ? offset + 63 : offset) -int -Write_FreeBSD(int fd, struct disk *new, struct disk *old, struct chunk *c1) -{ - struct disklabel *dl; - struct chunk *c2; - int i,j; - void *p; - u_char buf[BBSIZE]; - - for(i=0;i<BBSIZE/512;i++) { - p = read_block(fd,WHERE(i + c1->offset,new)); - memcpy(buf+512*i,p,512); - free(p); - } - if(new->boot1) - memcpy(buf,new->boot1,512); - - if(new->boot2) - memcpy(buf+512,new->boot2,BBSIZE-512); - - dl = (struct disklabel *) (buf+512*LABELSECTOR+LABELOFFSET); - memset(dl,0,sizeof *dl); - - for(c2=c1->part;c2;c2=c2->next) { - if (c2->type == unused) continue; - if (!strcmp(c2->name,"X")) continue; - j = c2->name[5] - 'a'; - if (j < 0 || j >= MAXPARTITIONS || j == RAW_PART) { - warn("Weird parititon letter %c",c2->name[5]); - continue; - } - dl->d_partitions[j].p_size = c2->size; - dl->d_partitions[j].p_offset = c2->offset; - dl->d_partitions[j].p_fstype = c2->subtype; - } - - dl->d_bbsize = BBSIZE; - /* - * Add in defaults for superblock size, interleave, and rpms - */ - dl->d_sbsize = SBSIZE; - dl->d_interleave = DEF_INTERLEAVE; - dl->d_rpm = DEF_RPM; - - strcpy(dl->d_typename,c1->name); - - dl->d_secsize = 512; - dl->d_secperunit = new->chunks->size; -#if 0 - dl->d_ncylinders = new->real_cyl ? new->real_cyl : new->bios_cyl; - dl->d_ntracks = new->real_hd ? new->real_hd : new->bios_hd; - dl->d_nsectors = new->real_sect ? new->real_sect : new->bios_sect; -#else - dl->d_ncylinders = new->bios_cyl; - dl->d_ntracks = new->bios_hd; - dl->d_nsectors = new->bios_sect; -#endif - dl->d_secpercyl = dl->d_ntracks * dl->d_nsectors; - - dl->d_npartitions = MAXPARTITIONS; - - dl->d_type = new->name[0] == 's' ? DTYPE_SCSI : DTYPE_ESDI; - dl->d_partitions[RAW_PART].p_size = c1->size; - dl->d_partitions[RAW_PART].p_offset = c1->offset; - - if(new->flags & DISK_ON_TRACK) - for(i=0;i<MAXPARTITIONS;i++) - if (dl->d_partitions[i].p_size) - dl->d_partitions[i].p_offset += 63; - dl->d_magic = DISKMAGIC; - dl->d_magic2 = DISKMAGIC; - dl->d_checksum = dkcksum(dl); - - for(i=0;i<BBSIZE/512;i++) { - write_block(fd,WHERE(i + c1->offset,new),buf+512*i); - } - - return 0; -} - -int -Write_Extended(int fd, struct disk *new, struct disk *old, struct chunk *c1) -{ - return 0; -} - -int -Write_Disk(struct disk *d1) -{ - int fd,i,j; - struct disk *old = 0; - struct chunk *c1; - int ret = 0; - char device[64]; - u_char *mbr; - struct dos_partition *dp,work[NDOSPART]; - int s[4]; - - strcpy(device,"/dev/r"); - strcat(device,d1->name); - - fd = open(device,O_RDWR); - if (fd < 0) { - warn("open(%s) failed",device); - return 1; - } - - memset(s,0,sizeof s); - mbr = read_block(fd,WHERE(0,d1)); - dp = (struct dos_partition*) (mbr + DOSPARTOFF); - memcpy(work,dp,sizeof work); - dp = work; - free(mbr); - for (c1=d1->chunks->part; c1 ; c1 = c1->next) { - if (c1->type == unused) continue; - if (!strcmp(c1->name,"X")) continue; - j = c1->name[4] - '1'; - if (j < 0 || j > 3) - continue; - s[j]++; - if (c1->type == extended) - ret += Write_Extended(fd, d1,old,c1); - if (c1->type == freebsd) - ret += Write_FreeBSD(fd, d1,old,c1); - - dp[j].dp_start = c1->offset; - dp[j].dp_size = c1->size; - - i = c1->offset; - if (i >= 1024*d1->bios_sect*d1->bios_hd) { - dp[j].dp_ssect = 0xff; - dp[j].dp_shd = 0xff; - dp[j].dp_scyl = 0xff; - } else { - dp[j].dp_ssect = i % d1->bios_sect; - i -= dp[j].dp_ssect++; - i /= d1->bios_sect; - dp[j].dp_shd = i % d1->bios_hd; - i -= dp[j].dp_shd; - i /= d1->bios_hd; - dp[j].dp_scyl = i; - i -= dp[j].dp_scyl; - dp[j].dp_ssect |= i >> 2; - } - -#ifdef DEBUG - printf("S:%lu = (%x/%x/%x)", - c1->offset,dp[j].dp_scyl,dp[j].dp_shd,dp[j].dp_ssect); -#endif - - i = c1->end; - dp[j].dp_esect = i % d1->bios_sect; - i -= dp[j].dp_esect++; - i /= d1->bios_sect; - dp[j].dp_ehd = i % d1->bios_hd; - i -= dp[j].dp_ehd; - i /= d1->bios_hd; - if (i>1023) i = 1023; - dp[j].dp_ecyl = i; - i -= dp[j].dp_ecyl; - dp[j].dp_esect |= i >> 2; - -#ifdef DEBUG - printf(" E:%lu = (%x/%x/%x)\n", - c1->end,dp[j].dp_ecyl,dp[j].dp_ehd,dp[j].dp_esect); -#endif - - dp[j].dp_typ = c1->subtype; - if (c1->flags & CHUNK_ACTIVE) - dp[j].dp_flag = 0x80; - else - dp[j].dp_flag = 0; - } - j = 0; - for(i=0;i<NDOSPART;i++) { - if (!s[i]) - memset(dp+i,0,sizeof *dp); - if (dp[i].dp_flag) - j++; - } - if (!j) - for(i=0;i<NDOSPART;i++) - if (dp[i].dp_typ == 0xa5) - dp[i].dp_flag = 0x80; - - mbr = read_block(fd,WHERE(0,d1)); - if (d1->bootmgr) - memcpy(mbr,d1->bootmgr,DOSPARTOFF); - memcpy(mbr+DOSPARTOFF,dp,sizeof *dp * NDOSPART); - mbr[512-2] = 0x55; - mbr[512-1] = 0xaa; - write_block(fd,WHERE(0,d1),mbr); - - i = 1; - i = ioctl(fd,DIOCSYNCSLICEINFO,&i); - if (i != 0) - warn("ioctl(DIOCSYNCSLICEINFO)"); - close(fd); - return 0; -} - diff --git a/release/sysinstall/anonFTP.c b/release/sysinstall/anonFTP.c new file mode 100644 index 000000000000..389f48b569fa --- /dev/null +++ b/release/sysinstall/anonFTP.c @@ -0,0 +1,487 @@ +/* + * The new sysinstall program. + * + * This is probably the last program in the `sysinstall' line - the next + * generation being essentially a complete rewrite. + * + * $Id: anonFTP.c,v 1.5 1995/11/11 11:56:40 jkh Exp $ + * + * Copyright (c) 1995 + * Coranth Gryphon. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * verbatim and that no modifications are made prior to this + * point in the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Coranth Gryphon + * for the FreeBSD Project. + * 4. The name of Coranth Gryphon or the FreeBSD project may not be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CORANTH GRYPHON ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CORANTH GRYPHON OR HIS PETS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/param.h> +#include <string.h> +#include <dialog.h> +#include <sys/types.h> +#include <pwd.h> +#include <grp.h> +#include "ui_objects.h" +#include "dir.h" +#include "dialog.priv.h" +#include "colors.h" +#include "sysinstall.h" + +/* This doesn't change until FTP itself changes */ + +#define FTP_NAME "ftp" +#define MOTD_FILE "ftpmotd" + +/* These change if we want to use different defaults */ + +#define FTP_UID 14 +#define FTP_GID 5 +#define FTP_GROUP "operator" +#define FTP_UPLOAD "incoming" +#define FTP_COMMENT "Anonymous FTP Admin" +#define FTP_HOMEDIR "/usr/ftp" + +#define ANONFTP_HELPFILE "anonftp" + +/* Set up the structure to hold configuration information */ +/* Note that this is only what we could fit onto the one screen */ + +typedef struct +{ + char homedir[64]; /* Home Dir for Anon FTP */ + char group[32]; /* Group */ + char uid[8]; /* UID */ + char comment[64]; /* PWD Comment */ + char upload[32]; /* Upload Dir */ +} FTPConf; + +static FTPConf tconf; + +#define ANONFTP_HOMEDIR_LEN 64 +#define ANONFTP_COMMENT_LEN 64 +#define ANONFTP_UPLOAD_LEN 32 +#define ANONFTP_GROUP_LEN 32 +#define ANONFTP_UID_LEN 8 + +static int okbutton, cancelbutton; + +/* What the screen size is meant to be */ +#define ANONFTP_DIALOG_Y 0 +#define ANONFTP_DIALOG_X 8 +#define ANONFTP_DIALOG_WIDTH COLS - 16 +#define ANONFTP_DIALOG_HEIGHT LINES - 2 + +/* The screen layout structure */ +typedef struct _layout { + int y; /* x & Y co-ordinates */ + int x; + int len; /* The size of the dialog on the screen */ + int maxlen; /* How much the user can type in ... */ + char *prompt; /* The string for the prompt */ + char *help; /* The display for the help line */ + void *var; /* The var to set when this changes */ + int type; /* The type of the dialog to create */ + void *obj; /* The obj pointer returned by libdialog */ +} Layout; + +static Layout layout[] = { +{ 2, 3, 8, ANONFTP_UID_LEN - 1, + "UID:", "What user ID to assign to FTP Admin", + tconf.uid, STRINGOBJ, NULL }, +#define LAYOUT_UID 1 + +{ 2, 15, 15, ANONFTP_GROUP_LEN - 1, + "Group:", "Group name that ftp process belongs to", + tconf.group, STRINGOBJ, NULL }, +#define LAYOUT_GROUP 2 + +{ 2, 35, 24, ANONFTP_COMMENT_LEN - 1, + "Comment:", "Password file comment for FTP Admin", + tconf.comment, STRINGOBJ, NULL }, +#define LAYOUT_COMMENT 3 + +{ 9, 10, 43, ANONFTP_HOMEDIR_LEN - 1, + "FTP Root Directory:", + "The top directory to chroot to when doing anonymous ftp", + tconf.homedir, STRINGOBJ, NULL }, +#define LAYOUT_HOMEDIR 4 + +{ 14, 20, 22, ANONFTP_UPLOAD_LEN - 1, + "Upload Subdirectory:", "Designated sub-directory that holds uploads", + tconf.upload, STRINGOBJ, NULL }, +#define LAYOUT_UPLOAD 5 + +{ 19, 15, 0, 0, + "OK", "Select this if you are happy with these settings", + &okbutton, BUTTONOBJ, NULL }, +#define LAYOUT_OKBUTTON 6 + +{ 19, 35, 0, 0, + "CANCEL", "Select this if you wish to cancel this screen", + &cancelbutton, BUTTONOBJ, NULL }, +#define LAYOUT_CANCELBUTTON 7 +{ NULL }, +}; + +int createFtpUser() +{ + struct passwd *tpw; + struct group *tgrp; + char pwline[256]; + char *tptr; + int gid; + FILE *fptr; + + if ((gid = atoi(tconf.group)) <= 0) { + if (!(tgrp = getgrnam(tconf.group))) { + /* group does not exist, create it by name */ + + tptr = msgGetInput("14", "What group ID to use for group %s ?", tconf.group); + if (tptr && *tptr && ((gid = atoi(tptr)) > 0)) { + if ((fptr = fopen(_PATH_GROUP,"a"))) { + fprintf(fptr,"%s:*:%d:%s\n",tconf.group,gid,FTP_NAME); + fclose(fptr); + } + } + else + gid = FTP_GID; + } + else + gid = tgrp->gr_gid; + } + else if (!getgrgid(gid)) { + /* group does not exist, create it by number */ + + tptr = msgGetInput("14", "What group name to use for gid %d ?", gid); + if (tptr && *tptr) { + strcpy(tconf.group, tptr); + if ((tgrp = getgrnam(tconf.group))) { + gid = tgrp->gr_gid; + } + else if ((fptr = fopen(_PATH_GROUP,"a"))) { + fprintf(fptr,"%s:*:%d:%s\n",tconf.group,gid,FTP_NAME); + fclose(fptr); + } + } + } + + if ((tpw = getpwnam(FTP_NAME))) { + if (tpw->pw_uid != FTP_UID) + msgConfirm("FTP user already exists with a different uid."); + + return (RET_SUCCESS); /* succeeds if already exists */ + } + + sprintf(pwline, "%s::%s:%d::0:0:%s:%s:/bin/date\n", FTP_NAME, tconf.uid, gid, tconf.comment, tconf.homedir); + + fptr = fopen(_PATH_MASTERPASSWD,"a"); + if (! fptr) { + msgConfirm("Could not open master password file."); + return (RET_FAIL); + } + fprintf(fptr, pwline); + fclose(fptr); + msgNotify("Remaking password file: %s", _PATH_MASTERPASSWD); + vsystem("pwd_mkdb -p %s", _PATH_MASTERPASSWD); + + return (RET_SUCCESS); +} + +/* This is it - how to get the setup values */ +int +anonftpOpenDialog() +{ + WINDOW *ds_win; + ComposeObj *obj = NULL; + ComposeObj *first, *last; + int n=0, quit=FALSE, cancel=FALSE, ret; + int max; + char help[FILENAME_MAX]; + char title[80]; + + /* We need a curses window */ + ds_win = newwin(LINES, COLS, 0, 0); + if (ds_win == 0) + { + beep(); + msgConfirm("Cannot open anonymous ftp dialog window!!"); + return(RET_SUCCESS); + } + + /* Say where our help comes from */ + systemHelpFile(ANONFTP_HELPFILE, help); + use_helpfile(help); + + /* Setup a nice screen for us to splat stuff onto */ + draw_box(ds_win, ANONFTP_DIALOG_Y, ANONFTP_DIALOG_X, ANONFTP_DIALOG_HEIGHT, ANONFTP_DIALOG_WIDTH, dialog_attr, border_attr); + wattrset(ds_win, dialog_attr); + mvwaddstr(ds_win, ANONFTP_DIALOG_Y, ANONFTP_DIALOG_X + 20, " Anonymous FTP Configuration "); + + draw_box(ds_win, ANONFTP_DIALOG_Y + 7, ANONFTP_DIALOG_X + 8, ANONFTP_DIALOG_HEIGHT - 11, ANONFTP_DIALOG_WIDTH - 17, + dialog_attr, border_attr); + wattrset(ds_win, dialog_attr); + sprintf(title, " Path Configuration "); + mvwaddstr(ds_win, ANONFTP_DIALOG_Y + 7, ANONFTP_DIALOG_X + 22, title); + + /** Initialize the config Data Structure **/ + + bzero(&tconf, sizeof(tconf)); + + strcpy(tconf.group, FTP_GROUP); + strcpy(tconf.upload, FTP_UPLOAD); + strcpy(tconf.comment, FTP_COMMENT); + strcpy(tconf.homedir, FTP_HOMEDIR); + sprintf(tconf.uid, "%d", FTP_UID); + + /* Loop over the layout list, create the objects, and add them + onto the chain of objects that dialog uses for traversal*/ + + n = 0; +#define lt layout[n] + + while (lt.help != NULL) { + switch (lt.type) { + case STRINGOBJ: + lt.obj = NewStringObj(ds_win, lt.prompt, lt.var, + lt.y + ANONFTP_DIALOG_Y, lt.x + ANONFTP_DIALOG_X, + lt.len, lt.maxlen); + break; + + case BUTTONOBJ: + lt.obj = NewButtonObj(ds_win, lt.prompt, lt.var, + lt.y + ANONFTP_DIALOG_Y, lt.x + ANONFTP_DIALOG_X); + break; + + default: + msgFatal("Don't support this object yet!"); + } + AddObj(&obj, lt.type, (void *) lt.obj); + n++; + } + max = n - 1; + + /* Find the last object we can traverse to */ + last = obj; + while (last->next) + last = last->next; + + /* Find the first object in the list */ + first = obj; + while (first->prev) + first = first->prev; + + /* Some more initialisation before we go into the main input loop */ + n = 0; + cancelbutton = 0; + cancel = FALSE; + okbutton = 0; + + /* Incoming user data - DUCK! */ + while (!quit) { + char help_line[80]; + int i, len = strlen(lt.help); + + /* Display the help line at the bottom of the screen */ + for (i = 0; i < 79; i++) + help_line[i] = (i < len) ? lt.help[i] : ' '; + help_line[i] = '\0'; + use_helpline(help_line); + display_helpline(ds_win, LINES - 1, COLS - 1); + + /* Ask for libdialog to do its stuff */ + ret = PollObj(&obj); + + /* Handle special case stuff that libdialog misses. Sigh */ + switch (ret) { + /* Bail out */ + case SEL_ESC: + quit = TRUE, cancel=TRUE; + break; + + /* This doesn't work for list dialogs. Oh well. Perhaps + should special case the move from the OK button ``up'' + to make it go to the interface list, but then it gets + awkward for the user to go back and correct screw up's + in the per-interface section */ + + case KEY_UP: + if (obj->prev !=NULL ) { + obj = obj->prev; + --n; + } else { + obj = last; + n = max; + } + break; + + case KEY_DOWN: + if (obj->next != NULL) { + obj = obj->next; + ++n; + } else { + obj = first; + n = 0; + } + break; + + case SEL_TAB: + if (n < max) + ++n; + else + n = 0; + break; + + /* The user has pressed enter over a button object */ + case SEL_BUTTON: + quit = TRUE; + if (cancelbutton) + cancel = TRUE; + break; + + /* Generic CR handler */ + case SEL_CR: + if (n < max) + ++n; + else + n = 0; + break; + + case SEL_BACKTAB: + if (n) + --n; + else + n = max; + break; + + case KEY_F(1): + display_helpfile(); + + /* They tried some key combination we don't support - tell them! */ + default: + beep(); + } + + } + + /* Clear this crap off the screen */ + dialog_clear(); + refresh(); + use_helpfile(NULL); + + if (cancel) + return RET_FAIL; + return RET_SUCCESS; +} + +int +configAnonFTP(char *unused) +{ + int i; + + /* Be optimistic */ + i = RET_SUCCESS; + + dialog_clear(); + i = anonftpOpenDialog(); + if (i != RET_SUCCESS) { + dialog_clear(); + msgConfirm("Configuration of Anonymous FTP cancelled per user request."); + return i; + } + + /*** Use defaults for any invalid values ***/ + if (atoi(tconf.uid) <= 0) + sprintf(tconf.uid, "%d", FTP_UID); + + if (!tconf.group[0]) + strcpy(tconf.group, FTP_GROUP); + + if (!tconf.upload[0]) + strcpy(tconf.upload, FTP_UPLOAD); + + /*** If the user did not specify a directory, use default ***/ + + if (tconf.homedir[strlen(tconf.homedir)-1] == '/') + tconf.homedir[strlen(tconf.homedir)-1] = '\0'; + + if (!tconf.homedir[0]) + strcpy(tconf.homedir, FTP_HOMEDIR); + + /*** If HomeDir does not exist, create it ***/ + + if (!directoryExists(tconf.homedir)) { + vsystem("mkdir -p %s" ,tconf.homedir); + } + + if (directoryExists(tconf.homedir)) { + msgNotify("Configuring %s for use by anon FTP.", tconf.homedir); + vsystem("chmod 555 %s && chown root.%s %s", tconf.homedir, tconf.group, tconf.homedir); + vsystem("mkdir %s/bin && chmod 555 %s/bin", tconf.homedir, tconf.homedir); + vsystem("cp /bin/ls %s/bin && chmod 111 %s/bin/ls", tconf.homedir, tconf.homedir); + vsystem("cp /bin/date %s/bin && chmod 111 %s/bin/date", tconf.homedir, tconf.homedir); + vsystem("mkdir %s/etc && chmod 555 %s/etc", tconf.homedir, tconf.homedir); + vsystem("mkdir -p %s/pub", tconf.homedir); + vsystem("mkdir -p %s/%s", tconf.homedir, tconf.upload); + vsystem("chmod 1777 %s/%s", tconf.homedir, tconf.upload); + + if (createFtpUser() == RET_SUCCESS) { + msgNotify("Copying password information for anon FTP."); + vsystem("cp /etc/pwd.db %s/etc && chmod 444 %s/etc/pwd.db", tconf.homedir, tconf.homedir); + vsystem("cp /etc/passwd %s/etc && chmod 444 %s/etc/passwd",tconf.homedir, tconf.homedir); + vsystem("cp /etc/group %s/etc && chmod 444 %s/etc/group", tconf.homedir, tconf.homedir); + vsystem("chown -R %s.%s %s/pub", FTP_NAME, tconf.group, tconf.homedir); + } + else { + dialog_clear(); + msgConfirm("Unable to create FTP user! Anonymous FTP setup failed."); + i = RET_FAIL; + } + + dialog_clear(); + if (!msgYesNo("Create a welcome message file for anonymous FTP users?")) { + char cmd[256]; + + dialog_clear(); + msgNotify("Uncompressing the editor - please wait.."); + vsystem("echo Your welcome message here. > %s/etc/%s", tconf.homedir, MOTD_FILE); + sprintf(cmd, "/stand/ee %s/etc/%s", tconf.homedir, MOTD_FILE); + systemExecute(cmd); + } + } + else { + dialog_clear(); + msgConfirm("Invalid Directory: %s\n" + "Anonymous FTP will not be set up.", tconf.homedir); + i = RET_FAIL; + } + return i; +} diff --git a/release/sysinstall/apache.c b/release/sysinstall/apache.c new file mode 100644 index 000000000000..9e2c80b1f3c2 --- /dev/null +++ b/release/sysinstall/apache.c @@ -0,0 +1,604 @@ +/* + * The new sysinstall program. + * + * This is probably the last program in the `sysinstall' line - the next + * generation being essentially a complete rewrite. + * + * $Id: apache.c,v 1.11 1995/11/05 01:00:27 jkh Exp $ + * + * Copyright (c) 1995 + * Coranth Gryphon. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * verbatim and that no modifications are made prior to this + * point in the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Coranth Gryphon + * for the FreeBSD Project. + * 4. The name of Coranth Gryphon or the FreeBSD project may not be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CORANTH GRYPHON ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CORANTH GRYPHON OR HIS PETS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/param.h> +#include <string.h> +#include <dialog.h> +#include "ui_objects.h" +#include "dir.h" +#include "dialog.priv.h" +#include "colors.h" +#include "sysinstall.h" + +#define APACHE_HELPFILE "apache" +#define APACHE_PACKAGE "apache-0.8.14" +#define FREEBSD_GIF "/stand/power.gif" + +/* These change if the package uses different defaults */ + +#define APACHE_BASE "/usr/local/www" +#define DATA_SUBDIR "data" +#define CONFIG_SUBDIR "config" + +/* Set up the structure to hold configuration information */ +/* Note that this is only what we could fit onto the one screen */ + +typedef struct +{ + char docroot[128]; /* DocumentRoot */ + char userdir[128]; /* UserDir */ + char welcome[32]; /* Welcome Doc */ + char email[64]; /* ServerAdmin */ + char hostname[64]; /* ServerName */ + char user[32]; /* User */ + char group[32]; /* Group */ + char maxcon[8]; /* Max Connections */ +} ApacheConf; + +static ApacheConf tconf; + +#define APACHE_DOCROOT_LEN 128 +#define APACHE_USERDIR_LEN 128 +#define APACHE_WELCOME_LEN 32 +#define APACHE_EMAIL_LEN 64 +#define APACHE_HOSTNAME_LEN 64 +#define APACHE_USER_LEN 32 +#define APACHE_GROUP_LEN 32 +#define APACHE_MAXCON_LEN 8 + +static int okbutton, cancelbutton; + +/* What the screen size is meant to be */ +#define APACHE_DIALOG_Y 0 +#define APACHE_DIALOG_X 8 +#define APACHE_DIALOG_WIDTH COLS - 16 +#define APACHE_DIALOG_HEIGHT LINES - 2 + +/* The screen layout structure */ +typedef struct _layout { + int y; /* x & Y co-ordinates */ + int x; + int len; /* The size of the dialog on the screen */ + int maxlen; /* How much the user can type in ... */ + char *prompt; /* The string for the prompt */ + char *help; /* The display for the help line */ + void *var; /* The var to set when this changes */ + int type; /* The type of the dialog to create */ + void *obj; /* The obj pointer returned by libdialog */ +} Layout; + +static Layout layout[] = { +{ 1, 2, 24, HOSTNAME_FIELD_LEN - 1, + "Host Name:", + "What name to report this host as to client browsers", + tconf.hostname, STRINGOBJ, NULL }, +#define LAYOUT_HOSTNAME 0 + +{ 1, 30, 30, APACHE_EMAIL_LEN - 1, + "Email Address:", + "The email address of the site maintainer, e.g. webmaster@bar.com", + tconf.email, STRINGOBJ, NULL }, +#define LAYOUT_EMAIL 1 + +{ 5, 3, 15, APACHE_USER_LEN - 1, + "Default User:", "Default username for access to web pages", + tconf.user, STRINGOBJ, NULL }, +#define LAYOUT_USER 2 + +{ 5, 22, 15, APACHE_GROUP_LEN - 1, + "Default Group:", "Default group name for access to web pages", + tconf.group, STRINGOBJ, NULL }, +#define LAYOUT_GROUP 3 + +{ 5, 46, 13, APACHE_MAXCON_LEN - 1, + "Max Connect:", "Maximum number of concurrent http connections", + tconf.maxcon, STRINGOBJ, NULL }, +#define LAYOUT_MAXCON 4 + +{ 10, 10, 43, APACHE_DOCROOT_LEN - 1, + "Root Document Path:", + "The top directory that holds the system web pages", + tconf.docroot, STRINGOBJ, NULL }, +#define LAYOUT_DOCROOT 5 + +{ 14, 10, 18, APACHE_USERDIR_LEN - 1, + "User Directory:", + "Personal sub-directory that holds users' web pages (eg. ~/Web)", + tconf.userdir, STRINGOBJ, NULL }, +#define LAYOUT_USERDIR 6 + +{ 14, 35, 18, APACHE_WELCOME_LEN - 1, + "Default Document:", + "The name of the default document found in each directory", + tconf.welcome, STRINGOBJ, NULL }, +#define LAYOUT_WELCOME 7 + +{ 19, 15, 0, 0, + "OK", "Select this if you are happy with these settings", + &okbutton, BUTTONOBJ, NULL }, +#define LAYOUT_OKBUTTON 8 + +{ 19, 35, 0, 0, + "CANCEL", "Select this if you wish to cancel this screen", + &cancelbutton, BUTTONOBJ, NULL }, +#define LAYOUT_CANCELBUTTON 9 +{ NULL }, +}; + +DMenu MenuApacheLanguages = { +DMENU_MULTIPLE_TYPE | DMENU_SELECTION_RETURNS, +"Apache Languages Menu", +"This allows you to specify which languages are known by your httpd server.", +NULL, +NULL, +{ +{ "English", "English", + DMENU_SET_VARIABLE, "APACHE_English=en", 0, 0 }, +{ "French", "French", + DMENU_SET_VARIABLE, "APACHE_French=fr", 0, 0 }, +{ "German", "German", + DMENU_SET_VARIABLE, "APACHE_German=de", 0, 0 }, +{ "Italian", "Italian", + DMENU_SET_VARIABLE, "APACHE_Italian=it", 0, 0 }, +{ "Japanese", "Japanese", + DMENU_SET_VARIABLE, "APACHE_Japanese=jp", 0, 0 }, +{ NULL } }, +}; + +/* This is it - how to get Apache setup values */ +int +apacheOpenDialog() +{ + WINDOW *ds_win; + ComposeObj *obj = NULL; + ComposeObj *first, *last; + int n=0, quit=FALSE, cancel=FALSE, ret; + int max; + char *tmp; + char help[FILENAME_MAX]; + char title[80]; + + /* We need a curses window */ + ds_win = newwin(LINES, COLS, 0, 0); + if (ds_win == 0) + { + beep(); + msgConfirm("Cannot open apache dialog window!!"); + return(RET_SUCCESS); + } + + /* Say where our help comes from */ + systemHelpFile(APACHE_HELPFILE, help); + use_helpfile(help); + + /* Setup a nice screen for us to splat stuff onto */ + draw_box(ds_win, APACHE_DIALOG_Y, APACHE_DIALOG_X, APACHE_DIALOG_HEIGHT, APACHE_DIALOG_WIDTH, dialog_attr, border_attr); + wattrset(ds_win, dialog_attr); + mvwaddstr(ds_win, APACHE_DIALOG_Y, APACHE_DIALOG_X + 20, " Apache HTTPD Configuration "); + + draw_box(ds_win, APACHE_DIALOG_Y + 9, APACHE_DIALOG_X + 8, APACHE_DIALOG_HEIGHT - 13, APACHE_DIALOG_WIDTH - 17, + dialog_attr, border_attr); + wattrset(ds_win, dialog_attr); + sprintf(title, " Path Configuration "); + mvwaddstr(ds_win, APACHE_DIALOG_Y + 9, APACHE_DIALOG_X + 22, title); + + /** Initialize the config Data Structure **/ + + bzero(&tconf, sizeof(tconf)); + + tmp = variable_get(VAR_DOMAINNAME); + if (tmp) + { + sprintf(tconf.email, "webmaster@%s", tmp); + sprintf(tconf.hostname, "www.%s", tmp); + } + + strcpy(tconf.user, "guest"); + strcpy(tconf.group, "guest"); + strcpy(tconf.userdir, "public_html"); + strcpy(tconf.welcome, "index.html"); + strcpy(tconf.maxcon, "150"); + sprintf(tconf.docroot, "%s/%s", APACHE_BASE, DATA_SUBDIR); + + /* Loop over the layout list, create the objects, and add them + onto the chain of objects that dialog uses for traversal*/ + + n = 0; +#define lt layout[n] + + while (lt.help != NULL) { + switch (lt.type) { + case STRINGOBJ: + lt.obj = NewStringObj(ds_win, lt.prompt, lt.var, + lt.y + APACHE_DIALOG_Y, lt.x + APACHE_DIALOG_X, + lt.len, lt.maxlen); + break; + + case BUTTONOBJ: + lt.obj = NewButtonObj(ds_win, lt.prompt, lt.var, + lt.y + APACHE_DIALOG_Y, lt.x + APACHE_DIALOG_X); + break; + + default: + msgFatal("Don't support this object yet!"); + } + AddObj(&obj, lt.type, (void *) lt.obj); + n++; + } + max = n - 1; + + /* Find the last object we can traverse to */ + last = obj; + while (last->next) + last = last->next; + + /* Find the first object in the list */ + first = obj; + while (first->prev) + first = first->prev; + + /* Some more initialisation before we go into the main input loop */ + n = 0; + cancelbutton = 0; + cancel = FALSE; + okbutton = 0; + + /* Incoming user data - DUCK! */ + while (!quit) { + char help_line[80]; + int i, len = strlen(lt.help); + + /* Display the help line at the bottom of the screen */ + for (i = 0; i < 79; i++) + help_line[i] = (i < len) ? lt.help[i] : ' '; + help_line[i] = '\0'; + use_helpline(help_line); + display_helpline(ds_win, LINES - 1, COLS - 1); + + /* Ask for libdialog to do its stuff */ + ret = PollObj(&obj); + + + /* We are in the Hostname field - calculate the e-mail addr */ + + if (n == LAYOUT_HOSTNAME) { + if ((tmp = index(tconf.hostname, '.')) != NULL) { + sprintf(tconf.email,"webmaster@%s",tmp+1); + RefreshStringObj(layout[LAYOUT_EMAIL].obj); + } + } + + /* Handle special case stuff that libdialog misses. Sigh */ + switch (ret) { + /* Bail out */ + case SEL_ESC: + quit = TRUE, cancel=TRUE; + break; + + /* This doesn't work for list dialogs. Oh well. Perhaps + should special case the move from the OK button ``up'' + to make it go to the interface list, but then it gets + awkward for the user to go back and correct screw up's + in the per-interface section */ + + case KEY_UP: + if (obj->prev !=NULL ) { + obj = obj->prev; + --n; + } else { + obj = last; + n = max; + } + break; + + case KEY_DOWN: + if (obj->next != NULL) { + obj = obj->next; + ++n; + } else { + obj = first; + n = 0; + } + break; + + case SEL_TAB: + if (n < max) + ++n; + else + n = 0; + break; + + /* The user has pressed enter over a button object */ + case SEL_BUTTON: + quit = TRUE; + if (cancelbutton) + cancel = TRUE; + break; + + /* Generic CR handler */ + case SEL_CR: + if (n < max) + ++n; + else + n = 0; + break; + + case SEL_BACKTAB: + if (n) + --n; + else + n = max; + break; + + case KEY_F(1): + display_helpfile(); + + /* They tried some key combination we don't support - tell them! */ + default: + beep(); + } + + } + + /* Clear this crap off the screen */ + dialog_clear(); + refresh(); + use_helpfile(NULL); + + if (cancel) + return RET_FAIL; + return RET_SUCCESS; +} + +int +configApache(char *unused) +{ + int i, maxcon; + char company[64], file[128]; + char *tptr; + FILE *fptr; + + /* Be optimistic */ + i = RET_SUCCESS; + + dialog_clear(); + msgConfirm("Since you elected to install the WEB server, we'll now add the\n" + "Apache HTTPD package and set up a few configuration files."); + i = package_add(APACHE_PACKAGE); + if (i != RET_SUCCESS) { + dialog_clear(); + msgConfirm("Hmmmmm. Looks like we weren't able to fetch the Apache WEB server\n" + "package. You may wish to fetch and configure it by hand by looking\n" + "in /usr/ports/net/apache (in the ports collection) or looking for the\n" + "precompiled apache package in packages/networking/%s.", APACHE_PACKAGE); + return (i); + } + + i = apacheOpenDialog(); + if (i != RET_SUCCESS) { + dialog_clear(); + msgConfirm("Configuration of the Apache WEB server was cancelled per\n" + "user request."); + return i; + } + /*** Fix defaults for invalid value ***/ + maxcon = atoi(tconf.maxcon); + if (maxcon <= 0) + maxcon = 150; + + if (! tconf.group[0]) + strcpy(tconf.group, "guest"); + if (! tconf.user[0]) + strcpy(tconf.user, "nobody"); + + if (! tconf.welcome[0]) + strcpy(tconf.welcome, "index.html"); + if (! tconf.userdir[0]) + strcpy(tconf.userdir, "public_html"); + + /*** If the user did not specify a directory, use default ***/ + + if (tconf.docroot[strlen(tconf.docroot)-1] == '/') + tconf.docroot[strlen(tconf.docroot)-1] = '\0'; + + if (!tconf.docroot[0]) + sprintf(tconf.docroot,"%s/%s",APACHE_BASE, DATA_SUBDIR); + + /*** If DocRoot does not exist, create it ***/ + + if (!directoryExists(tconf.docroot)) + vsystem("mkdir -p %s", tconf.docroot); + + if (directoryExists(tconf.docroot)) + { + sprintf(file,"%s/index.html", tconf.docroot); + if (!file_readable(file)) + { + dialog_clear(); + tptr = msgGetInput(NULL, + "What is your company name?"); + if (tptr && strlen(tptr)) + strcpy(company, tptr); + else + strcpy(company, "our Web Page"); + + msgNotify("Creating sample web page..."); + fptr = fopen(file,"w"); + if (fptr) + { + fprintf(fptr,"<CENTER>\n<TITLE>Welcome Page</TITLE>\n"); + fprintf(fptr,"<H1>Welcome to %s </H1>\n</CENTER>\n",company); + fprintf(fptr,"<P><HR SIZE=4>\n<CENTER>\n"); + fprintf(fptr,"<A HREF=\"http://www.FreeBSD.org/What\">\n"); + fprintf(fptr,"<IMG SRC=\"./power.gif\" ALIGN=CENTER BORDER=0 "); + fprintf(fptr," ALT=\"Powered by FreeBSD\"></A>\n"); + if (! tconf.email[0]) + { + if ((tptr = variable_get(VAR_DOMAINNAME))) + sprintf(tconf.email,"root@%s",tptr); + } + if (tconf.email[0]) + { + fprintf(fptr,"<ADDRESS><H4>\n"); + fprintf(fptr," For questions or comments, please send mail to:\n"); + fprintf(fptr," <A HREF=\"mailto:%s\">%s</A>\n", + tconf.email, tconf.email); + fprintf(fptr,"</H4></ADDRESS>\n"); + } + fprintf(fptr,"</CENTER>\n\n"); + fclose(fptr); + if (file_readable(FREEBSD_GIF)) + vsystem("cp %s %s", FREEBSD_GIF, tconf.docroot); + } + else { + msgConfirm("Unable to create sample Web Page."); + i = RET_FAIL; + } + } + } + else { + dialog_clear(); + msgConfirm("Unable to create Document Root Directory."); + i = RET_FAIL; + } + + msgNotify("Writing configuration files...."); + + (void)vsystem("mkdir -p %s/config", APACHE_BASE); + sprintf(file, "%s/%s/access.conf", APACHE_BASE,CONFIG_SUBDIR); + if (file_readable(file)) + vsystem("mv -f %s %s.ORIG", file, file); + + fptr = fopen(file,"w"); + if (fptr) + { + fprintf(fptr,"<Directory %s/cgi-bin>\n", APACHE_BASE); + fprintf(fptr,"Options Indexes FollowSymLinks\n</Directory>\n\n"); + fprintf(fptr,"<Directory %s>\n", tconf.docroot); + fprintf(fptr,"Options Indexes FollowSymLinks\nAllowOverride All\n"); + fprintf(fptr,"</Directory>\n\n"); + fclose(fptr); + } + else { + dialog_clear(); + msgConfirm("Could not create %s",file); + i = RET_FAIL; + } + + sprintf(file, "%s/%s/httpd.conf", APACHE_BASE,CONFIG_SUBDIR); + if (file_readable(file)) + vsystem("mv -f %s %s.ORIG", file, file); + + fptr = fopen(file,"w"); + if (fptr) + { + fprintf(fptr,"ServerType standalone\nPort 80\nTimeOut 400\n"); + fprintf(fptr,"ErrorLog logs/error_log\nTransferLog logs/access_log\n"); + fprintf(fptr,"PidFile /var/run/httpd.pid\n\nStartServers 5\n"); + fprintf(fptr,"MinSpareServers 5\nMaxSpareServers 10\n"); + fprintf(fptr,"MaxRequestsPerChild 30\nMaxClients %d\n\n",maxcon); + fprintf(fptr,"User %s\nGroup %s\n\n",tconf.user,tconf.group); + + if (tconf.email[0]) + fprintf(fptr,"ServerAdmin %s\n",tconf.email); + if (tconf.hostname[0]) + fprintf(fptr,"ServerName %s\n",tconf.hostname); + + fclose(fptr); + } + else { + dialog_clear(); + msgConfirm("Could not create %s",file); + i = RET_FAIL; + } + + sprintf(file, "%s/%s/srm.conf", APACHE_BASE,CONFIG_SUBDIR); + if (file_readable(file)) + vsystem("mv -f %s %s.ORIG", file, file); + fptr = fopen(file,"w"); + if (fptr) + { + fprintf(fptr,"FancyIndexing on\nDefaultType text/plain\n"); + fprintf(fptr,"IndexIgnore */.??* *~ *# */HEADER* */README* */RCS\n"); + fprintf(fptr,"HeaderName HEADER\nReadmeName README\n"); + fprintf(fptr,"AccessFileName .htaccess\n\n"); + fprintf(fptr,"AddEncoding x-compress Z\nAddEncoding x-gzip gz\n"); + fprintf(fptr,"DefaultIcon /icons/unknown.gif\n\n"); + fprintf(fptr, + "AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip\n"); + fprintf(fptr,"AddIconByType (TXT,/icons/text.gif) text/*\n"); + fprintf(fptr,"AddIconByType (IMG,/icons/image2.gif) image/*\n"); + fprintf(fptr,"AddIconByType (SND,/icons/sound2.gif) audio/*\n"); + fprintf(fptr,"AddIconByType (VID,/icons/movie.gif) video/*\n\n"); + + fprintf(fptr,"AddIcon /icons/text.gif .ps .shtml\n"); + fprintf(fptr,"AddIcon /icons/movie.gif .mpg .qt\n"); + fprintf(fptr,"AddIcon /icons/binary.gif .bin\n"); + fprintf(fptr,"AddIcon /icons/burst.gif .wrl\n"); + fprintf(fptr,"AddIcon /icons/binhex.gif .hqx .sit\n"); + fprintf(fptr,"AddIcon /icons/uu.gif .uu\n"); + fprintf(fptr,"AddIcon /icons/tar.gif .tar\n"); + fprintf(fptr,"AddIcon /icons/back.gif ..\n"); + fprintf(fptr,"AddIcon /icons/dir.gif ^^DIRECTORY^^\n"); + fprintf(fptr,"AddIcon /icons/blank.gif ^^BLANKICON^^\n\n"); + + fprintf(fptr,"ScriptAlias /cgi_bin/ %s/cgi_bin/\n",APACHE_BASE); + fprintf(fptr,"Alias /icons/ %s/icons/\n",APACHE_BASE); + fprintf(fptr,"DocumentRoot %s\n",tconf.docroot); + fprintf(fptr,"UserDir %s\nDirectoryIndex %s\n\n", tconf.userdir, + tconf.welcome); + + fclose(fptr); + } + else { + dialog_clear(); + msgConfirm("Could not create %s",file); + i = RET_FAIL; + } + if (i != RET_FAIL) + variable_set2("apache_httpd", "YES"); + return i; +} diff --git a/release/sysinstall/doc.c b/release/sysinstall/doc.c new file mode 100644 index 000000000000..187362ddc64d --- /dev/null +++ b/release/sysinstall/doc.c @@ -0,0 +1,100 @@ +/* + * The new sysinstall program. + * + * This is probably the last program in the `sysinstall' line - the next + * generation being essentially a complete rewrite. + * + * $Id: doc.c,v 1.9 1995/11/04 08:47:22 jkh Exp $ + * + * Jordan Hubbard + * + * My contributions are in the public domain. + * + */ + +#include "sysinstall.h" + +/* + * This is called from the main menu. Try to find a copy of Lynx from somewhere + * and fire it up on the first copy of the handbook we can find. + */ +int +docBrowser(char *junk) +{ + char *browser = variable_get(VAR_BROWSER_PACKAGE); + + if (RunningAsInit && !strstr(variable_get(SYSTEM_STATE), "install")) { + msgConfirm("This option may only be used after the system is installed, sorry!"); + return RET_FAIL; + } + + /* Make sure we have media available */ + if (!mediaVerify()) + return RET_FAIL; + + /* First, make sure we have whatever browser we've chosen is here */ + if (package_add(browser) != RET_SUCCESS) { + dialog_clear(); + msgConfirm("Unable to install the %s HTML browser package. You may\n" + "wish to verify that your media is configured correctly and\n" + "try again.", browser); + return RET_FAIL; + } + if (!file_executable(variable_get(VAR_BROWSER_BINARY))) { + dialog_clear(); + if (!msgYesNo("Hmmm. The %s package claims to have installed, but I can't\n" + "find its binary in %s! You may wish to try a different\n" + "location to load the package from (go to Media menu) and see if that\n" + "makes a difference.\n\n" + "I suggest that we remove the version that was extracted since it does\n" + "not appear to be correct. Would you like me to do that now?")) + vsystem("pkg_delete %s %s", !strcmp(variable_get(VAR_CPIO_VERBOSITY), "high") ? "-v" : "", browser); + return RET_FAIL; + } + + /* Run browser on the appropriate doc */ + dmenuOpenSimple(&MenuHTMLDoc); + return RET_SUCCESS; +} + +/* Try to show one of the documents requested from the HTML doc menu */ +int +docShowDocument(char *str) +{ + char tmp[512], target[512]; + char *where = NULL; + char *browser = variable_get(VAR_BROWSER_BINARY); + + if (!file_executable(browser)) { + dialog_clear(); + msgConfirm("Can't find the browser in %s! Please ensure that it's\n" + "properly set in the Options editor.", browser); + return RET_FAIL; + } + if (!strcmp(str, "Home")) + where = "http://www.freebsd.org"; + else if (!strcmp(str, "Other")) + where = msgGetInput("http://www.freebsd.org", "Please enter the URL of the location you wish to visit."); + else if (!strcmp(str, "FAQ")) { + strcpy(target, "/usr/share/doc/FAQ/freebsd-faq.html"); + if (!file_readable(target)) + strcpy(target, "http://www.freebsd.org/FAQ"); + where = target; + } + else if (!strcmp(str, "Handbook")) { + strcpy(target, "/usr/share/doc/handbook/handbook.html"); + if (!file_readable(target)) + strcpy(target, "http://www.freebsd.org/handbook"); + where = target; + } + if (where) { + sprintf(tmp, "%s %s", browser, where); + systemExecute(tmp); + return RET_SUCCESS; + } + else { + msgConfirm("Hmmmmm! I can't seem to access the documentation you selected!\n" + "Have you loaded the bin distribution? Is your network connected?"); + return RET_FAIL; + } +} diff --git a/release/sysinstall/freebsd.cfg b/release/sysinstall/freebsd.cfg new file mode 100644 index 000000000000..4652d1fc03ad --- /dev/null +++ b/release/sysinstall/freebsd.cfg @@ -0,0 +1,58 @@ +# This is the installation configuration file for my laptop, fat.cdrom.com. +# It is included here merely as a sort-of-documented example. + +# Turn on extra debugging. +debug=yes + +# My host specific data +hostname=fat.cdrom.com +domainname=cdrom.com +nameserver=192.216.222.3 +defaultrouter=192.216.222.225 +ipaddr=192.216.222.227 +netmask=255.255.255.240 + +# Which installation device to use - ftp is pointed directly at my local +# machine and the installation device is my PC CARD ethernet interface. +# the "script" keyword lets mediaSetFTP know that it's being run from +# a script and shouldn't prompt the user for extra details. If you *want* +# it to prompt, you can pass it either "express", "novice" or "custom" +# to set the level of detail for such prompting. This is a general convention +# which you'll see elsewhere in this script file. +ftp=ftp://time.cdrom.com/pub +mediaSetFTP=script +tcpInstallDevice=ze0 + +# Select which distributions we want. +distSetUser + +# Now set the parameters for the partition editor. Set to use all remaining +# free space (could also be "all" or "existing" to use all the disk or an +# existing FreeBSD slice). Pass the script parameter to diskPartitionEditor +# so it's not interactive, as described above. +disk=wd0 +diskSpace=free +bootManager=booteasy +diskPartitionEditor=script + +# It's bogus that we have to re-enter the label editor for each partition +# we want to create, but it was easier to do it this way (from a programming +# standpoint, not a user standpoint!). This assumes that slice 1 is a DOS +# partition and mounts it as /dos, which is the case on my laptop. +# We can also create a root partition of 20MB in size on the same pass since +# it's in a different slice (s2). All sizes are expressed in 512 byte blocks! +wd0s1=/dos N +wd0s2=partition 40960 / +diskLabelEditor=script + +# Now make a 20MB swap partition in the second slice. +wd0s2=swap 40960 none +diskLabelEditor=script + +# Size of 0 means allocate the rest of the space to /usr +wd0s2=partition 0 /usr +diskLabelEditor=script + +# OK, everything is set. Do it! +installCommit=script + diff --git a/release/sysinstall/help/anonftp.hlp b/release/sysinstall/help/anonftp.hlp new file mode 100644 index 000000000000..e90985e235fe --- /dev/null +++ b/release/sysinstall/help/anonftp.hlp @@ -0,0 +1,19 @@ +This screen allows you to configure the anonymous FTP user. + +The following configuration values are editable: + +UID: The user ID you wish to assign to the anonymous FTP user. + All files uploaded will be owned by this ID. + +Group: Which group you wish the anonymous FTP user to be in. + +Comment: String describing this user in /etc/passwd + + +FTP Root Directory: + + Where files available for anonymous FTP will be kept. + +Upload subdirectory: + + Where files uploaded by anonymous FTP users will go. diff --git a/release/sysinstall/help/apache.hlp b/release/sysinstall/help/apache.hlp new file mode 100644 index 000000000000..3880dddb2ba6 --- /dev/null +++ b/release/sysinstall/help/apache.hlp @@ -0,0 +1,51 @@ +There are two sets of options that the Apache HTTP Server needs. + +The first set covers how it operates. These are as follows: + + The "HostName" field is the name of this host, as it is + reported to each client connection. Normally, the fully + qualified domain name of the host running the server is + returned. If you want this set to something else, however, + (usually "www.my.domain") then this can be entered here. + + Additionally, the server needs to know how many connections + are allowed at one time - this is the "Max Connections" + field. If more than this number of clients attempt to connect + at once, the additional connections will be refused. This is + used to limit how much system load will be imposed by the HTTP + server. + + The "Email Address" field is the address of the person (or + system alias) who is the administrator for this web site. In + addition to being used by the Apache Server itself, it is also + put at the bottom of the sample web page that is created. + + Finally, the "Default User" and "Default Group" fields specify + what user id and group id should be used by the server for + remote connections. Local connections are kept as the UID and + GID of the local process. + +The second set of options determine what information is made available +to each client: + + The "Document Root Path" is the top of the tree of documents + that are made avaliable. For example, if the value is + "/usr/web", then the URL "http://www.foo.com/doc.html" would + translate as "/usr/web/doc.html". + + Similarly, the "User Directory" is the location in each user's + home directory where their public web documents are + stored. Thus if the value if this is "Public", then the URL + "http://www.foo.com/~joe/doc" would translate to the path + "~joe/Public/doc". + + Finally, if the URL points to a directory, there is always a + "Default Document" that Apache will use. This field holds the + name (not the path) of this document. By default, Apache uses + the file "index.html". However, some sites may be more used to + using the file "welcome.html". + +There are a number of other options that can be configured with +Apache, such as path aliases, masquerading as multiple hosts, server +child process parameters, and so forth. For more information on these, +consult the Apache man pages at http://www.apache.org. diff --git a/release/sysinstall/help/upgrade.hlp b/release/sysinstall/help/upgrade.hlp new file mode 100644 index 000000000000..5cba594a9c9c --- /dev/null +++ b/release/sysinstall/help/upgrade.hlp @@ -0,0 +1,38 @@ +Welcome to the 2.0.5 -> 2.1 upgrade procedure! + +It must first be said that this upgrade DOES NOT take a particularly +sophisticated approach to the upgrade problem, it being more a question +of providing what seemed "good enough" at the time. A truly polished +upgrade that deals properly with the broad spectrum of installed 2.0.5 +systems would be nice to have, but until that gets written what you get is +this - the brute-force approach! + +What this upgrade will attempt to do is best summarized thusly: + + 1. fsck and mount all file systems chosen in the label editor. + 2. Ask for a location to preserve your /etc directory into and do so. + 3. Extract all selected distributions on top of your existing system. + 4. Copy certain obvious files back from the preserved /etc, leaving the + rest of the /etc file merge up to the user. + 5. Drop user in a shell so that they may perform that merge before + rebooting into the new system. + +And that's it! This "upgrade" is not going to hold your hand in all +major respects, it's simply provided to make one PART of the upgrade +easier. + +IMPORTANT NOTE: What this upgrade procedure may also do, in fact, is +completely destroy your system (though much more quickly than you +would have been able to destroy it yourself). It is simply impossible +to guarantee that this procedure's crude form of upgrade automation +will work in all cases and if you do this upgrade without proper +BACKUPS for any important data then you really must like living life +close to the edge, that's all we can say! + +NOTE to 2.0 users: We're sorry, but the "slice" changes that were +added in FreeBSD 2.0.5 made automated upgrades pretty difficult due to +the fact that a complete reinstall is pretty much called for. Things +may still *work* after a 2.1 upgrade, but you will also no doubt +receive many warnings at boot time about non-aligned slices and such; +we really do recommend a fresh installation for 2.0 systems! (But +back up your user data first :-). diff --git a/release/sysinstall/index.c b/release/sysinstall/index.c new file mode 100644 index 000000000000..6198a5eaf1ed --- /dev/null +++ b/release/sysinstall/index.c @@ -0,0 +1,569 @@ +/* + * The new sysinstall program. + * + * This is probably the last program in the `sysinstall' line - the next + * generation being essentially a complete rewrite. + * + * $Id: index.c,v 1.19 1995/11/06 22:26:28 jkh Exp $ + * + * Copyright (c) 1995 + * Jordan Hubbard. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * verbatim and that no modifications are made prior to this + * point in the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Jordan Hubbard + * for the FreeBSD Project. + * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <ncurses.h> +#include <dialog.h> +#include "sysinstall.h" + +/* Macros and magic values */ +#define MAX_MENU 13 +#define _MAX_DESC 62 + +/* Smarter strdup */ +inline char * +_strdup(char *ptr) +{ + return ptr ? strdup(ptr) : NULL; +} + +static char *descrs[] = { + "Package Selection", "To mark a package or select a category, move to it and press SPACE.\n" + "To unmark a package, press SPACE again. When you want to commit your\n" + "marks, press [ENTER]. To go to a previous menu, select UP item or Cancel.\n" + "To search for a package by name, press ESC. To extract packages, you\n" + "should Cancel all the way out of any submenus and finally this menu.", + "Package Targets", "These are the packages you've selected for extraction.\n\n" + "If you're sure of these choices, select OK.\n" + "If not, select Cancel to go back to the package selection menu.\n", + "All", "All available packages in all categories.", + "applications", "User application software.", + "archivers", "Utilities for archiving and unarchiving data.", + "audio", "Audio utilities - most require a supported sound card.", + "benchmarks", "Utilities for measuring system performance.", + "benchmarking", "Utilities for measuring system performance.", + "cad", "Computer Aided Design utilities.", + "comms", "Communications utilities.", + "databases", "Database software.", + "devel", "Software development utilities and libraries.", + "development", "Software development utilities and libraries.", + "documentation", "Document preparation utilities.", + "editors", "Common text editors.", + "emulation", "Utilities for emulating other OS types.", + "emulators", "Utilities for emulating other OS types.", + "games", "Various and sundry amusements.", + "graphics", "Graphics libraries and utilities.", + "japanese", "Ported software for the Japanese market.", + "lang", "Computer languages.", + "languages", "Computer languages.", + "libraries", "Software development libraries.", + "mail", "Electronic mail packages and utilities.", + "math", "Mathematical computation software.", + "net", "Networking utilities.", + "networking", "Networking utilities.", + "news", "USENET News support software.", + "numeric", "Mathematical computation software.", + "orphans", "Packages without a home elsewhere.", + "plan9", "Software from the plan9 Operating System.", + "print", "Utilities for dealing with printing.", + "printing", "Utilities for dealing with printing.", + "programming", "Software development utilities and libraries.", + "russian", "Ported software for the Russian market.", + "security", "System security software.", + "shells", "Various shells (tcsh, bash, etc).", + "sysutils", "Various system utilities.", + "troff", "TROFF Text formatting utilities.", + "utils", "Various user utilities.", + "utilities", "Various user utilities.", + "x11", "X Window System based utilities.", + NULL, NULL, +}; + +static char * +fetch_desc(char *name) +{ + int i; + + for (i = 0; descrs[i]; i += 2) { + if (!strcmp(descrs[i], name)) + return descrs[i + 1]; + } + return "No description provided"; +} + +static PkgNodePtr +new_pkg_node(char *name, node_type type) +{ + PkgNodePtr tmp = safe_malloc(sizeof(PkgNode)); + + tmp->name = _strdup(name); + tmp->type = type; + return tmp; +} + +static IndexEntryPtr +new_index(char *name, char *pathto, char *prefix, char *comment, char *descr, char *maint) +{ + IndexEntryPtr tmp = safe_malloc(sizeof(IndexEntry)); + + tmp->name = _strdup(name); + tmp->path = _strdup(pathto); + tmp->prefix = _strdup(prefix); + tmp->comment = _strdup(comment); + tmp->descrfile = _strdup(descr); + tmp->maintainer = _strdup(maint); + return tmp; +} + +static void +index_register(PkgNodePtr top, char *where, IndexEntryPtr ptr) +{ + PkgNodePtr p, q; + + for (q = NULL, p = top->kids; p; p = p->next) { + if (!strcmp(p->name, where)) { + q = p; + break; + } + } + if (!p) { + /* Add new category */ + q = new_pkg_node(where, PLACE); + q->desc = fetch_desc(where); + q->next = top->kids; + top->kids = q; + } + p = new_pkg_node(ptr->name, PACKAGE); + p->desc = ptr->comment; + p->data = ptr; + p->next = q->kids; + q->kids = p; +} + +static int +copy_to_sep(char *to, char *from, int sep) +{ + char *tok; + + tok = strchr(from, sep); + if (!tok) { + fprintf(stderr, "missing '%c' token.\n", sep); + *to = '\0'; + return 0; + } + *tok = '\0'; + strcpy(to, from); + return tok + 1 - from; +} + +static int +readline(int fd, char *buf, int max) +{ + int rv, i = 0; + char ch; + + while ((rv = read(fd, &ch, 1)) == 1 && ch != '\n' && i < max) + buf[i++] = ch; + if (i < max) + buf[i] = '\0'; + return rv; +} + +int +index_parse(int fd, char *name, char *pathto, char *prefix, char *comment, char *descr, char *maint, + char *cats, char *keys) +{ + char line[1024]; + char *cp; + int i; + + i = readline(fd, line, 1024); + if (i <= 0) + return EOF; + cp = line; + cp += copy_to_sep(name, cp, '|'); + cp += copy_to_sep(pathto, cp, '|'); + cp += copy_to_sep(prefix, cp, '|'); + cp += copy_to_sep(comment, cp, '|'); + cp += copy_to_sep(descr, cp, '|'); + cp += copy_to_sep(maint, cp, '|'); + cp += copy_to_sep(cats, cp, '|'); + strcpy(keys, cp); + return 0; +} + +int +index_get(char *fname, PkgNodePtr papa) +{ + int i, fd; + + fd = open(fname, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "Unable to open index file `%s' for reading.\n", fname); + i = -1; + } + else + i = index_read(fd, papa); + close(fd); + return i; +} + +int +index_read(int fd, PkgNodePtr papa) +{ + char name[127], pathto[255], prefix[255], comment[255], descr[127], maint[127], cats[511], keys[511]; + + while (index_parse(fd, name, pathto, prefix, comment, descr, maint, cats, keys) != EOF) { + char *cp, *cp2, tmp[511]; + IndexEntryPtr idx; + + idx = new_index(name, pathto, prefix, comment, descr, maint); + /* For now, we only add things to menus if they're in categories. Keywords are ignored */ + for (cp = strcpy(tmp, cats); (cp2 = strchr(cp, ' ')) != NULL; cp = cp2 + 1) { + *cp2 = '\0'; + index_register(papa, cp, idx); + } + index_register(papa, cp, idx); + + /* Add to special "All" category */ + index_register(papa, "All", idx); + } + return 0; +} + +void +index_init(PkgNodePtr top, PkgNodePtr plist) +{ + top->next = top->kids = NULL; + top->name = "Package Selection"; + top->type = PLACE; + top->desc = fetch_desc(top->name); + top->data = NULL; + + plist->next = plist->kids = NULL; + plist->name = "Package Targets"; + plist->type = PLACE; + plist->desc = fetch_desc(plist->name); + plist->data = NULL; +} + +void +index_entry_free(IndexEntryPtr top) +{ + safe_free(top->name); + safe_free(top->path); + safe_free(top->prefix); + safe_free(top->comment); + safe_free(top->descrfile); + safe_free(top->maintainer); + free(top); +} + +void +index_node_free(PkgNodePtr top, PkgNodePtr plist) +{ + PkgNodePtr tmp; + + tmp = plist; + while (tmp) { + PkgNodePtr tmp2 = tmp->next; + + safe_free(tmp); + tmp = tmp2; + } + + for (tmp = top; tmp; tmp = tmp->next) { + free(tmp->name); + if (tmp->type == PACKAGE && tmp->data) + index_entry_free((IndexEntryPtr)tmp->data); + if (tmp->kids) + index_node_free(tmp->kids, NULL); + } +} + +void +index_print(PkgNodePtr top, int level) +{ + int i; + + while (top) { + for (i = 0; i < level; i++) putchar('\t'); + printf("name [%s]: %s\n", top->type == PLACE ? "place" : "package", top->name); + for (i = 0; i < level; i++) putchar('\t'); + printf("desc: %s\n", top->desc); + if (top->kids) + index_print(top->kids, level + 1); + top = top->next; + } +} + +/* Swap one node for another */ +static void +swap_nodes(PkgNodePtr a, PkgNodePtr b) +{ + PkgNode tmp; + + tmp = *a; + *a = *b; + a->next = tmp.next; + tmp.next = b->next; + *b = tmp; +} + +/* Use a disgustingly simplistic bubble sort to put our lists in order */ +void +index_sort(PkgNodePtr top) +{ + PkgNodePtr p, q; + + /* Sort everything at the top level */ + for (p = top->kids; p; p = p->next) { + for (q = top->kids; q; q = q->next) { + if (q->next && strcmp(q->name, q->next->name) > 0) + swap_nodes(q, q->next); + } + } + + /* Now sub-sort everything n levels down */ + + for (p = top->kids; p; p = p->next) { + if (p->kids) + index_sort(p); + } +} + +/* + * No, we don't free n because someone else is still pointing at it. + * It's just clone linked from another location, which we're adjusting. + */ +void +index_delete(PkgNodePtr n) +{ + if (n->next) + *n = *(n->next); + else /* Kludgy end sentinal */ + n->name = NULL; +} + +PkgNodePtr +index_search(PkgNodePtr top, char *str, PkgNodePtr *tp) +{ + PkgNodePtr p, sp; + + for (p = top->kids; p && p->name; p = p->next) { + /* Subtract out the All category from searches */ + if (!strcmp(p->name, "All")) + continue; + + /* If tp == NULL, we're looking for an exact package match */ + if (!tp && !strcmp(p->name, str)) + return p; + + /* If tp, we're looking for both a package and a pointer to the place it's in */ + if (tp && strstr(p->name, str)) { + *tp = top; + return p; + } + + /* The usual recursion-out-of-laziness ploy */ + if (p->kids) + if ((sp = index_search(p, str, tp)) != NULL) + return sp; + } + if (p && !p->name) + p = NULL; + return p; +} + +/* Work function for seeing if name x is in result string y */ +static Boolean +is_selected_in(char *name, char *result) +{ + Boolean ret = FALSE; + + while (*result) { + char *cp; + + cp = index(result, '\n'); + if (!cp) { + ret = !strcmp(name, result); + break; + } + else { + ret = !strncmp(name, result, cp - result - 1); + if (ret) + break; + } + result = cp + 1; + } + return ret; +} + +int +index_menu(PkgNodePtr top, PkgNodePtr plist, int *pos, int *scroll) +{ + int n, rval, maxname; + int curr, max; + PkgNodePtr sp, kp; + char **nitems; + char result[4096]; + Boolean hasPackages; + + hasPackages = FALSE; + nitems = NULL; + + n = maxname = 0; + /* Figure out if this menu is full of "leaves" or "branches" */ + for (kp = top->kids; kp && kp->name; kp = kp->next) { + int len; + + ++n; + if (kp->type == PACKAGE && plist) { + hasPackages = TRUE; + if ((len = strlen(kp->name)) > maxname) + maxname = len; + } + } + if (!n && plist) { + dialog_clear(); + msgConfirm("The %s menu is empty.", top->name); + return RET_DONE; + } + + dialog_clear(); + while (1) { + n = 0; + curr = max = 0; + kp = top->kids; + if (!hasPackages && kp && kp->name && plist) { + nitems = item_add_pair(nitems, "UP", "<RETURN TO PREVIOUS MENU>", &curr, &max); + ++n; + } + while (kp && kp->name) { + /* Brutally adjust description to fit in menu */ + if (strlen(kp->desc) > (_MAX_DESC - maxname)) + kp->desc[_MAX_DESC - maxname] = '\0'; + nitems = item_add_pair(nitems, kp->name, kp->desc, &curr, &max); + if (hasPackages) { + if (kp->type == PACKAGE && plist) + nitems = item_add(nitems, index_search(plist, kp->name, NULL) ? "ON" : "OFF", &curr, &max); + else + nitems = item_add(nitems, "OFF", &curr, &max); + } + ++n; + kp = kp->next; + } + nitems = item_add(nitems, NULL, &curr, &max); + + if (hasPackages) + rval = dialog_checklist(top->name, top->desc, -1, -1, n > MAX_MENU ? MAX_MENU : n, n, + (unsigned char **)nitems, result); + else /* It's a categories menu */ + rval = dialog_menu(top->name, top->desc, -1, -1, n > MAX_MENU ? MAX_MENU : n, n, + (unsigned char **)nitems, result, pos, scroll); + if (!rval && plist && strcmp(result, "UP")) { + for (kp = top->kids; kp; kp = kp->next) { + if (kp->type == PACKAGE) { + sp = index_search(plist, kp->name, NULL); + if (is_selected_in(kp->name, result)) { + if (!sp) { + PkgNodePtr np = (PkgNodePtr)safe_malloc(sizeof(PkgNode)); + + *np = *kp; + np->next = plist->kids; + plist->kids = np; + standout(); + mvprintw(23, 0, "Selected packages were added to selection list\n", kp->name); + standend(); + refresh(); + } + } + else if (sp) { + standout(); + mvprintw(23, 0, "Deleting unselected packages from selection list\n", kp->name); + standend(); + refresh(); + index_delete(sp); + } + } + else if (!strcmp(kp->name, result)) { /* Not a package, must be a directory */ + int p, s; + + p = s = 0; + index_menu(kp, plist, &p, &s); + } + } + } + else if (rval == -1 && plist) { + static char *cp; + PkgNodePtr menu; + + /* Search */ + if ((cp = msgGetInput(cp, "Search by package name. Please enter search string:")) != NULL) { + PkgNodePtr p = index_search(top, cp, &menu); + + if (p) { + int pos, scroll; + + /* These need to be set to point at the found item, actually. Hmmm! */ + pos = scroll = 0; + index_menu(menu, plist, &pos, &scroll); + } + else { + msgConfirm("Search string: %s yielded no hits.", cp); + } + } + } + else { + dialog_clear(); + items_free(nitems, &curr, &max); + return rval ? RET_FAIL : RET_SUCCESS; + } + } +} + +int +index_extract(Device *dev, PkgNodePtr plist) +{ + PkgNodePtr tmp; + int status = RET_SUCCESS; + + for (tmp = plist->kids; tmp; tmp = tmp->next) { + if (package_extract(dev, tmp->name) != RET_SUCCESS) + status = RET_FAIL; + } + return status; +} diff --git a/release/sysinstall/installFinal.c b/release/sysinstall/installFinal.c new file mode 100644 index 000000000000..050e86ed3105 --- /dev/null +++ b/release/sysinstall/installFinal.c @@ -0,0 +1,223 @@ +/* + * The new sysinstall program. + * + * This is probably the last program in the `sysinstall' line - the next + * generation being essentially a complete rewrite. + * + * $Id: installFinal.c,v 1.20 1995/11/12 11:12:25 jkh Exp $ + * + * Copyright (c) 1995 + * Jordan Hubbard & Coranth Gryphon. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * verbatim and that no modifications are made prior to this + * point in the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the authors listed above + * for the FreeBSD Project. + * 4. The names of the authors or the FreeBSD project may not be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR THEIR PETS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include "sysinstall.h" +#include <sys/disklabel.h> +#include <sys/errno.h> +#include <sys/ioctl.h> +#include <sys/fcntl.h> +#include <sys/wait.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <unistd.h> +#include <sys/mount.h> + +/* This file contains all the final configuration thingies */ + +static DMenu MenuSamba = { + DMENU_MULTIPLE_TYPE | DMENU_SELECTION_RETURNS, + "Samba Services Menu", + "This allows you to configure various aspects of your Samba server.", + NULL, + NULL, +{ { "Homes", "Make home directories available to users.", + DMENU_SET_VARIABLE, "SAMBA_homes=YES", 0, 0, dmenuVarCheck }, + { "Printers", "Allows for sharing of local printers.", + DMENU_SET_VARIABLE, "SAMBA_printers=YES", 0, 0, dmenuVarCheck}, + { "Export Paths", "Specify local directories to make available.", + DMENU_SET_VARIABLE, "SAMBA_export=YES", 0, 0, dmenuVarCheck }, + { NULL } }, +}; + +/* These probably shouldn't be hard-coded, but making them options might prove to be even more confusing! */ +#define SMB_CONF "./smb.conf" + + +/* Load gated package */ +int +configGated(char *unused) +{ + if (package_add("gated-3.5a11") == RET_SUCCESS) + variable_set2("gated", "YES"); + return RET_SUCCESS; +} + +/* Load pcnfsd package */ +int +configPCNFSD(char *unused) +{ + if (package_add("pcnfsd-93.02.16") == RET_SUCCESS) + variable_set2("pcnfsd", "YES"); + return RET_SUCCESS; +} + +int +configSamba(char *unused) +{ + int i = RET_SUCCESS; + + if (!dmenuOpenSimple(&MenuSamba)) + i = RET_FAIL; + else if (package_add("samba-1.9.14") != RET_SUCCESS) + i = RET_FAIL; + else { + FILE *fptr; + char tbuf[256], *tptr; + int tval; + + fptr = fopen("/tmp/smb.conf","w"); + if (fptr) { + strcpy(tbuf,"FreeBSD - Samba %v"); + if (variable_get("SAMBA_string")) { + tptr = msgGetInput("FreeBSD - Samba %%v", "What should this server list as its description?\n" + "Note that the \"%%v\" refers to the samba version number."); + if (tptr && *tptr) + strcpy(tbuf, tptr); + } + + fprintf(fptr, "[global]\n"); + fprintf(fptr, "comment = %s\n", tbuf); + fprintf(fptr, "log file = /var/log/samba.log\n"); + fprintf(fptr, "dont descend = /dev,/proc,/root,/stand\n\n"); + + fprintf(fptr, "printing = bsd\n"); + fprintf(fptr, "map archive = no\n"); + fprintf(fptr, "status = yes\n"); + fprintf(fptr, "public = yes\n"); + fprintf(fptr, "read only = no\n"); + fprintf(fptr, "preserve case = yes\n"); + fprintf(fptr, "strip dot = yes\n"); + fprintf(fptr, "security = share\n"); + fprintf(fptr, "guest ok = yes\n\n"); + + if (variable_get("SAMBA_homes")) { + fprintf(fptr, "[homes]\n"); + fprintf(fptr, "browseable = no\n"); + fprintf(fptr, "comment = User Home Directory\n"); + fprintf(fptr, "create mode = 0775\n"); + fprintf(fptr, "public = no\n\n"); + } + + if (variable_get("SAMBA_printers")) { + fprintf(fptr, "[printers]\n"); + fprintf(fptr, "path = /var/spool\n"); + fprintf(fptr, "comment = Printers\n"); + fprintf(fptr, "create mode = 0700\n"); + fprintf(fptr, "browseable = no\n"); + fprintf(fptr, "printable = yes\n"); + fprintf(fptr, "read only = yes\n"); + fprintf(fptr, "public = no\n\n"); + } + + if (variable_get("SAMBA_export")) { + for (tval = 0; ! tval; tval = msgYesNo("Another?")) { + tptr = msgGetInput(NULL,"What directory to export?"); + if (tptr && *tptr && (tptr[0] == '/')) { + int len = strlen(tbuf); + + strcpy(tbuf, tptr); + if (tbuf[len - 1] == '/') + tbuf[len - 1] = '\0'; + if (directoryExists(tbuf)) { + tptr = msgGetInput(pathBaseName(tbuf), "What do you want to call this share?"); + if (tptr && *tptr) { + fprintf(fptr, "[%s]\npath = %s\n", tptr, tbuf); + tptr = msgGetInput(NULL, "Enter a short description of this share?"); + if (tptr && *tptr) + fprintf(fptr, "comment = %s\n", tptr); + if (msgYesNo("Do you want this share to be read only?")) + fprintf(fptr, "read only = no\n\n"); + else + fprintf(fptr, "read only = yes\n\n"); + } + else { + dialog_clear(); + msgConfirm("Invalid Share Name."); + } + } + else { + dialog_clear(); + msgConfirm("Directory does not exist."); + } + } /* end if (tptr) */ + } /* end for loop */ + } /* end if (SAMBA_export) */ + fclose(fptr); + vsystem("mv -f /tmp/smb.conf %s", SMB_CONF); + } + else { + dialog_clear(); + msgConfirm("Unable to open temporary smb.conf file.\n" + "Samba will have to be configured by hand."); + } + } + return i; +} + +int +configNFSServer(char *unused) +{ + /* If we're an NFS server, we need an exports file */ + if (!file_readable("/etc/exports")) { + dialog_clear(); + msgConfirm("Operating as an NFS server means that you must first configure\n" + "an /etc/exports file to indicate which hosts are allowed certain\n" + "kinds of access to your local file systems.\n" + "Press [ENTER] now to invoke an editor on /etc/exports (the editor\n" + "may take a little while to uncompress the first time - please be\n" + "patient!)"); + vsystem("echo '#The following examples export /usr to 3 machines named after ducks,' > /etc/exports"); + vsystem("echo '#/home and all directories under it to machines named after dead rock stars' >> /etc/exports"); + vsystem("echo '#and, finally, /a to 2 privileged machines allowed to write on it as root.' >> /etc/exports"); + vsystem("echo '#/usr huey louie dewie' >> /etc/exports"); + vsystem("echo '#/home -alldirs janice jimmy frank' >> /etc/exports"); + vsystem("echo '#/a -maproot=0 bill albert' >> /etc/exports"); + vsystem("echo '#' >> /etc/exports"); + vsystem("echo '# You should replace these lines with your actual exported filesystems.' >> /etc/exports"); + vsystem("echo >> /etc/exports"); + dialog_clear(); + systemExecute("/stand/ee /etc/exports"); + } + variable_set2("nfs_server", "YES"); + return RET_SUCCESS; +} diff --git a/release/sysinstall/installPreconfig.c b/release/sysinstall/installPreconfig.c new file mode 100644 index 000000000000..e5f323223c7e --- /dev/null +++ b/release/sysinstall/installPreconfig.c @@ -0,0 +1,221 @@ +/* + * The new sysinstall program. + * + * This is probably the last program in the `sysinstall' line - the next + * generation being essentially a complete rewrite. + * + * $Id: installPreconfig.c,v 1.16 1995/10/27 17:00:23 jkh Exp $ + * + * Copyright (c) 1995 + * Jordan Hubbard. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * verbatim and that no modifications are made prior to this + * point in the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Jordan Hubbard + * for the FreeBSD Project. + * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include "sysinstall.h" +#include <ctype.h> +#include <sys/disklabel.h> +#include <sys/errno.h> +#include <sys/ioctl.h> +#include <sys/fcntl.h> +#include <sys/wait.h> +#include <sys/param.h> +#define MSDOSFS +#include <sys/mount.h> +#undef MSDOSFS +#include <sys/stat.h> +#include <unistd.h> +#include <sys/mount.h> + +static struct _word { + char *name; + int (*handler)(char *str); +} resWords[] = { + { "configAnonFTP", configAnonFTP }, + { "configApache", configApache }, + { "configGated", configGated }, + { "configNFSServer", configNFSServer }, + { "configSamba", configSamba }, + { "diskPartitionEditor", diskPartitionEditor }, + { "diskPartitionWrite", diskPartitionWrite }, + { "diskLabelEditor", diskLabelEditor }, + { "diskLabelCommit", diskLabelCommit }, + { "distReset", distReset }, + { "distSetCustom", distSetCustom }, + { "distSetDeveloper", distSetDeveloper }, + { "distSetXDeveloper", distSetXDeveloper }, + { "distSetKernDeveloper", distSetKernDeveloper }, + { "distSetUser", distSetUser }, + { "distSetXUser", distSetXUser }, + { "distSetMinimum", distSetMinimum }, + { "distSetEverything", distSetEverything }, + { "distSetDES", distSetDES }, + { "distSetSrc", distSetSrc }, + { "distSetXF86", distSetXF86 }, + { "distExtractAll", distExtractAll }, + { "docBrowser", docBrowser }, + { "docShowDocument", docShowDocument }, + { "installCommit", installCommit }, + { "installExpress", installExpress }, + { "installUpgrade", installUpgrade }, + { "installPreconfig", installPreconfig }, + { "installFixup", installFixup }, + { "installFilesystems", installFilesystems }, + { "mediaSetCDROM", mediaSetCDROM }, + { "mediaSetFloppy", mediaSetFloppy }, + { "mediaSetDOS", mediaSetDOS }, + { "mediaSetTape", mediaSetTape }, + { "mediaSetFTP", mediaSetFTP }, + { "mediaSetFTPActive", mediaSetFTPActive }, + { "mediaSetFTPPassive", mediaSetFTPPassive }, + { "mediaSetUFS", mediaSetUFS }, + { "mediaSetNFS", mediaSetNFS }, + { "mediaSetFtpUserPass", mediaSetFtpUserPass }, + { "mediaSetCPIOVerbosity", mediaSetCPIOVerbosity }, + { "mediaGetType", mediaGetType }, + { "msgConfirm", msgSimpleConfirm }, + { "msgNotify", msgSimpleNotify }, + { "packageAdd", package_add }, + { "system", (int (*)(char *))vsystem }, + { "systemInteractive", systemExecute }, + { "tcpInstallDevice", tcpInstallDevice }, + { NULL, NULL }, +}; + +static int +call_possible_resword(char *name, char *value, int *status) +{ + int i, rval; + + rval = 0; + for (i = 0; resWords[i].name; i++) { + if (!strcmp(name, resWords[i].name)) { + *status = resWords[i].handler(value); + rval = 1; + break; + } + } + return rval; +} + +/* From the top menu - try to mount the floppy and read a configuration file from it */ +int +installPreconfig(char *str) +{ + struct ufs_args u_args; + struct msdosfs_args m_args; + int fd, i; + char buf[128]; + char *cfg_file; + + memset(&u_args, 0, sizeof(u_args)); + u_args.fspec = "/dev/fd0"; + Mkdir("/mnt2", NULL); + + memset(&m_args, 0, sizeof(m_args)); + m_args.fspec = "/dev/fd0"; + m_args.uid = m_args.gid = 0; + m_args.mask = 0777; + + i = RET_FAIL; + while (1) { + if (!(cfg_file = variable_get_value(VAR_CONFIG_FILE, + "Please insert the floppy containing this configuration file\n" + "into drive A now and press [ENTER]."))) + break; + + if (mount(MOUNT_UFS, "/mnt2", MNT_RDONLY, (caddr_t)&u_args) == -1) { + if (mount(MOUNT_MSDOS, "/mnt2", MNT_RDONLY, (caddr_t)&m_args) == -1) { + dialog_clear(); + if (msgYesNo("Unable to mount the configuration floppy - do you want to try again?")) + break; + else + continue; + } + } + fnord: + if (!cfg_file) + break; + sprintf(buf, "/mnt2/%s", cfg_file); + msgDebug("Attempting to open configuration file: %s\n", buf); + fd = open(buf, O_RDONLY); + if (fd == -1) { + dialog_clear(); + if (msgYesNo("Unable to find the configuration file: %s\n" + "Do you want to try again?", buf)) { + unmount("/mnt2", MNT_FORCE); + break; + } + else + goto fnord; + } + else { + Attribs *cattr = safe_malloc(sizeof(Attribs) * MAX_ATTRIBS); + int i, j; + + if (attr_parse(cattr, fd) == RET_FAIL) { + dialog_clear(); + msgConfirm("Cannot parse configuration file %s! Please verify your media.", cfg_file); + } + else { + i = RET_SUCCESS; + for (j = 0; cattr[j].name[0]; j++) { + int status; + + if (call_possible_resword(cattr[j].name, cattr[j].value, &status)) { + if (status != RET_SUCCESS) { + msgDebug("macro call to %s(%s) returns %d status!\n", cattr[j].name, cattr[j].value, + status); + i = status; + } + } + else + variable_set2(cattr[j].name, cattr[j].value); + } + if (i == RET_SUCCESS) { + dialog_clear(); + msgConfirm("Configuration file %s loaded successfully!\n" + "Some parameters may now have new default values.", buf); + } + else if (i == RET_FAIL) { + dialog_clear(); + msgConfirm("Configuration file %s loaded with some errors.", buf); + } + } + close(fd); + safe_free(cattr); + unmount("/mnt2", MNT_FORCE); + break; + } + } + return i; +} diff --git a/release/sysinstall/installUpgrade.c b/release/sysinstall/installUpgrade.c new file mode 100644 index 000000000000..2a2d19b217ec --- /dev/null +++ b/release/sysinstall/installUpgrade.c @@ -0,0 +1,396 @@ +/* + * The new sysinstall program. + * + * This is probably the last program in the `sysinstall' line - the next + * generation being essentially a complete rewrite. + * + * $Id: installUpgrade.c,v 1.17 1995/11/08 07:09:27 jkh Exp $ + * + * Copyright (c) 1995 + * Jordan Hubbard. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * verbatim and that no modifications are made prior to this + * point in the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Jordan Hubbard + * for the FreeBSD Project. + * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include "sysinstall.h" +#include <sys/disklabel.h> +#include <sys/errno.h> +#include <sys/ioctl.h> +#include <sys/fcntl.h> +#include <sys/wait.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <unistd.h> +#include <sys/mount.h> + +typedef struct _hitList { + enum { JUST_COPY, CALL_HANDLER } action ; + char *name; + Boolean optional; + void (*handler)(struct _hitList *self); +} HitList; + +/* cop-out function for files we can't handle */ +static void +doByHand(HitList *h) +{ + dialog_clear(); + msgConfirm("/etc/%s is one of those files that this upgrade procedure just isn't\n" + "smart enough to deal with right now. You'll need to merge the old and\n" + "new versions by hand when the option to do so manually is later\n" + "presented (in the meantime, you might want to write the name of\n" + "this file down! - the holographic shell on VTY4 is a good place for\n" + "this).", h->name); +} + +static void +yellSysconfig(HitList *h) +{ + dialog_clear(); + msgConfirm("/etc/sysconfig is one of those files that this upgrade procedure just isn't\n" + "smart enough to deal with right now. Unfortunately, your system\n" + "will also come up with a very different \"personality\" than it had\n" + "before if you do not merge at LEAST the hostname and ifconfig lines\n" + "from the old one! This is very important, so please do this merge\n" + "even if you do no others before the system is allowed to reboot."); +} + +/* These are the only meaningful files I know about */ +static HitList etc_files [] = { + { JUST_COPY, "Xaccel.ini", TRUE, NULL }, + { JUST_COPY, "adduser.conf", TRUE, NULL }, + { JUST_COPY, "aliases", TRUE, NULL }, + { JUST_COPY, "aliases.db", TRUE, NULL }, + { JUST_COPY, "amd.map", TRUE, NULL }, + { JUST_COPY, "crontab", TRUE, NULL }, + { JUST_COPY, "csh.cshrc", TRUE, NULL }, + { JUST_COPY, "csh.login", TRUE, NULL }, + { JUST_COPY, "csh.logout", TRUE, NULL }, + { JUST_COPY, "daily", TRUE, NULL }, + { JUST_COPY, "disktab", TRUE, NULL }, + { JUST_COPY, "dm.conf", TRUE, NULL }, + { JUST_COPY, "exports", TRUE, NULL }, + { JUST_COPY, "fbtab", TRUE, NULL }, + { CALL_HANDLER, "fstab", FALSE, doByHand }, + { JUST_COPY, "ftpusers", TRUE, NULL }, + { JUST_COPY, "gnats", TRUE, NULL }, + { JUST_COPY, "group", FALSE, NULL }, + { JUST_COPY, "host.conf", TRUE, NULL }, + { JUST_COPY, "hosts", TRUE, NULL }, + { JUST_COPY, "hosts.equiv", TRUE, NULL }, + { JUST_COPY, "hosts.lpd", TRUE, NULL }, + { CALL_HANDLER, "inetd.conf", FALSE, doByHand }, + { CALL_HANDLER, "kerberosIV", TRUE, doByHand }, + { JUST_COPY, "localtime", TRUE, NULL }, + { JUST_COPY, "login.access", TRUE, NULL }, + { JUST_COPY, "mail.rc", TRUE, NULL }, + { JUST_COPY, "make.conf", TRUE, NULL }, + { JUST_COPY, "manpath.config", TRUE, NULL }, + { JUST_COPY, "master.passwd", TRUE, NULL }, + { JUST_COPY, "mib.txt", TRUE, NULL }, + { JUST_COPY, "modems", TRUE, NULL }, + { JUST_COPY, "monthly", TRUE, NULL }, + { JUST_COPY, "motd", TRUE, NULL }, + { JUST_COPY, "namedb", TRUE, NULL }, + { CALL_HANDLER, "netstart", FALSE, doByHand }, + { JUST_COPY, "networks", TRUE, NULL }, + { JUST_COPY, "passwd", FALSE, NULL }, + { JUST_COPY, "phones", TRUE, NULL }, + { JUST_COPY, "ppp", TRUE, NULL }, + { JUST_COPY, "printcap", TRUE, NULL }, + { JUST_COPY, "profile", TRUE, NULL }, + { JUST_COPY, "protocols", TRUE, NULL }, + { JUST_COPY, "pwd.db", TRUE, NULL }, + { CALL_HANDLER, "rc", FALSE, doByHand }, + { CALL_HANDLER, "rc.i386", TRUE, doByHand }, + { JUST_COPY, "rc.local", TRUE, NULL }, + { CALL_HANDLER, "rc.serial", TRUE, doByHand }, + { JUST_COPY, "remote", TRUE, NULL }, + { JUST_COPY, "resolv.conf", TRUE, NULL }, + { JUST_COPY, "rmt", TRUE, NULL }, + { JUST_COPY, "security", TRUE, NULL }, + { JUST_COPY, "sendmail.cf", TRUE, NULL }, + { CALL_HANDLER, "services", TRUE, doByHand }, + { JUST_COPY, "shells", TRUE, NULL }, + { JUST_COPY, "skeykeys", TRUE, NULL }, + { JUST_COPY, "spwd.db", TRUE, NULL }, + { JUST_COPY, "supfile", TRUE, NULL }, + { CALL_HANDLER, "sysconfig", FALSE, yellSysconfig }, + { JUST_COPY, "syslog.conf", TRUE, NULL }, + { JUST_COPY, "termcap", TRUE, NULL }, + { JUST_COPY, "ttys", TRUE, NULL }, + { JUST_COPY, "uucp", TRUE, NULL }, + { JUST_COPY, "weekly", TRUE, NULL }, + { 0 }, +}; + +void +traverseHitlist(HitList *h) +{ + while (h->name) { + if (!file_readable(h->name)) { + if (!h->optional) { + dialog_clear(); + msgConfirm("Unable to find an old /etc/%s file! That is decidedly non-standard and\n" + "your upgraded system may function a little strangely as a result."); + } + } + else { + if (h->action == JUST_COPY) { + /* Nuke the just-loaded copy thoroughly */ + vsystem("rm -rf /etc/%s", h->name); + + /* Copy the old one into its place */ + msgNotify("Resurrecting %s..", h->name); + /* Do this with tar so that symlinks and such are preserved */ + if (vsystem("tar cf - %s | tar xpf - -C /etc", h->name)) { + dialog_clear(); + msgConfirm("Unable to resurrect your old /etc/%s! Hmmmm.", h->name); + } + } + else /* call handler */ + h->handler(h); + } + ++h; + } +} + +int +installUpgrade(char *str) +{ + char *saved_etc = NULL; + Boolean extractingBin = TRUE; + struct termios foo; + + if (!RunningAsInit) { + dialog_clear(); + msgConfirm("You can only perform this procedure when booted off the installation\n" + "floppy."); + return RET_FAIL; + } + + systemDisplayHelp("upgrade"); + + if (msgYesNo("Given all that scary stuff you just read, are you sure you want to\n" + "risk it all and proceed with this upgrade?")) + return RET_FAIL; + + if (!Dists) { + dialog_clear(); + msgConfirm("You haven't specified any distributions yet. The upgrade procedure will\n" + "only upgrade those portions of the system for which a distribution has\n" + "been selected. In the next screen, we'll go to the Distributions menu\n" + "to select those portions of 2.1 you wish to install on top of your 2.0.5\n" + "system."); + if (!dmenuOpenSimple(&MenuDistributions)) + return RET_FAIL; + } + + /* No bin selected? Not much of an upgrade.. */ + if (!(Dists & DIST_BIN)) { + dialog_clear(); + if (msgYesNo("You didn't select the bin distribution as one of the distributons to load.\n" + "This one is pretty vital to a successful 2.1 upgrade. Are you SURE you don't\n" + "want to select the bin distribution? Chose _No_ to bring up the Distributions\n" + "menu.")) { + (void)dmenuOpenSimple(&MenuDistributions); + } + } + + /* Still?! OK! They must know what they're doing.. */ + if (!(Dists & DIST_BIN)) + extractingBin = FALSE; + + if (!mediaDevice) { + dialog_clear(); + msgConfirm("Now you must specify an installation medium for the upgrade."); + if (!dmenuOpenSimple(&MenuMedia) || !mediaDevice) + return RET_FAIL; + } + + dialog_clear(); + msgConfirm("OK. First, we're going to go to the disk label editor. In this editor\n" + "you will be expected to *Mount* any partitions you're interested in\n" + "upgrading. Don't set the Newfs flag to Y on anything in the label editor\n" + "unless you're absolutely sure you know what you're doing! In this\n" + "instance, you'll be using the label editor as little more than a fancy\n" + "screen-oriented filesystem mounting utility, so think of it that way.\n\n" + "Once you're done in the label editor, press Q to return here for the next\n" + "step."); + + if (diskLabelEditor(NULL) == RET_FAIL) { + dialog_clear(); + msgConfirm("The disk label editor failed to work properly! Upgrade operation\n" + "aborted."); + return RET_FAIL; + } + + /* Don't write out MBR info */ + variable_set2(DISK_PARTITIONED, "written"); + if (diskLabelCommit("upgrade") == RET_FAIL) { + dialog_clear(); + msgConfirm("Not all file systems were properly mounted. Upgrade operation\n" + "aborted."); + variable_unset(DISK_PARTITIONED); + return RET_FAIL; + } + + if (!copySelf()) { + dialog_clear(); + msgConfirm("Couldn't clone the boot floppy onto the root file system.\n" + "Aborting."); + return RET_FAIL; + } + + if (chroot("/mnt") == RET_FAIL) { + dialog_clear(); + msgConfirm("Unable to chroot to /mnt - something is wrong with the\n" + "root partition or the way it's mounted if this doesn't work."); + variable_unset(DISK_PARTITIONED); + return RET_FAIL; + } + + chdir("/"); + systemCreateHoloshell(); + + if (!rootExtract()) { + dialog_clear(); + msgConfirm("Failed to load the ROOT distribution. Please correct\n" + "this problem and try again (the system will now reboot)."); + reboot(0); + } + + if (extractingBin) { + while (!saved_etc) { + saved_etc = msgGetInput("/usr/tmp/etc", "Under which directory do you wish to save your current /etc?"); + if (!saved_etc || !*saved_etc || Mkdir(saved_etc, NULL)) { + dialog_clear(); + if (msgYesNo("Directory was not specified, was invalid or user selected Cancel.\n\n" + "Doing an upgrade without first backing up your /etc directory is a very\n" + "bad idea! Do you want to go back and specify the save directory again?")) + break; + } + } + + if (saved_etc) { + msgNotify("Preserving /etc directory.."); + /* cp returns a bogus status, so we can't check the status meaningfully. Bleah. */ + (void)vsystem("cp -pr /etc/* %s", saved_etc); + } + if (file_readable("/kernel")) { + msgNotify("Moving old kernel to /kernel.205"); + if (system("chflags noschg /kernel && mv /kernel /kernel.205")) { + dialog_clear(); + if (!msgYesNo("Hmmm! I couldn't move the old kernel over! Do you want to\n" + "treat this as a big problem and abort the upgrade? Due to the\n" + "way that this upgrade process works, you will have to reboot\n" + "and start over from the beginning. Select Yes to reboot now")) { + reboot(0); + } + } + } + } + + msgNotify("Beginning extraction of distributions.."); + if (distExtractAll("upgrade") == RET_FAIL) { + if (extractingBin && (Dists & DIST_BIN)) { + dialog_clear(); + msgConfirm("Hmmmm. We couldn't even extract the bin distribution. This upgrade\n" + "should be considered a failure and started from the beginning, sorry!\n" + "The system will reboot now."); + reboot(0); + } + dialog_clear(); + msgConfirm("The extraction process seems to have had some problems, but we got most\n" + "of the essentials. We'll treat this as a warning since it may have been\n" + "only non-essential distributions which failed to load."); + } + + if (extractingBin) { + msgNotify("OK, now it's time to go pound on your root a little bit to create all the\n" + "/dev entries and such that a 2.1 system expects to see. I'll also perform a\n" + "few \"fixup\" operations to repair the effects of splatting a bin distribution\n" + "on top of an existing system.."); + if (installFixup("upgrade") == RET_FAIL) { + dialog_clear(); + msgConfirm("Hmmmmm. The fixups don't seem to have been very happy.\n" + "You may wish to examine the system a little more closely when\n" + "it comes time to merge your /etc customizations back."); + } + } + + dialog_clear(); + msgConfirm("First stage of upgrade completed successfully!\n\n" + "Next comes stage 2, where we attempt to resurrect your /etc\n" + "directory!"); + + if (chdir(saved_etc)) { + dialog_clear(); + msgConfirm("Unable to go to your saved /etc directory in %s?! Argh!\n" + "Something went seriously wrong! It's quite possible that\n" + "your former /etc is toast. I hope you didn't have any\n" + "important customizations you wanted to keep in there.. :("); + } + else { + /* Now try to resurrect the /etc files */ + traverseHitlist(etc_files); + } + + dialog_clear(); + msgConfirm("OK! At this stage, we've resurrected all the /etc files we could\n" + "(and you may have been warned about some that you'll have to merge\n" + "yourself by hand) and we're going to drop you into a shell to do\n" + "the rest yourself (sorry about this!). Once the system looks good\n" + "to you, exit the shell to reboot the system."); + + chdir("/"); + dialog_clear(); + dialog_update(); + end_dialog(); + DialogActive = FALSE; + + signal(SIGTTOU, SIG_IGN); + if (tcgetattr(0, &foo) != -1) { + foo.c_cc[VERASE] = '\010'; + if (tcsetattr(0, TCSANOW, &foo) == -1) + msgDebug("Unable to set the erase character.\n"); + } + else + msgDebug("Unable to get the terminal attributes!\n"); + printf("Well, good luck! When you're done, please type \"reboot\" or exit\n" + "the shell to reboot the new system.\n"); + execlp("sh", "-sh", 0); + msgDebug("Was unable to execute sh for post-upgrade shell!\n"); + reboot(0); + /* NOTREACHED */ + return 0; +} diff --git a/release/sysinstall/lndir.c b/release/sysinstall/lndir.c new file mode 100644 index 000000000000..665f3627d343 --- /dev/null +++ b/release/sysinstall/lndir.c @@ -0,0 +1,217 @@ +/* $XConsortium: lndir.c,v 1.14 95/01/09 20:08:20 kaleb Exp $ */ +/* $XFree86: xc/config/util/lndir.c,v 3.3 1995/01/28 15:41:09 dawes Exp $ */ +/* Create shadow link tree (after X11R4 script of the same name) + Mark Reinhold (mbr@lcs.mit.edu)/3 January 1990 */ + +/* Hacked somewhat by Jordan Hubbard, The FreeBSD Project, to make it */ +/* an invokable function from sysinstall rather than a stand-alone binary */ + +/* +Copyright (c) 1990, X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +*/ + +/* From the original /bin/sh script: + + Used to create a copy of the a directory tree that has links for all + non-directories (except those named RCS, SCCS or CVS.adm). If you are + building the distribution on more than one machine, you should use + this technique. + + If your master sources are located in /usr/local/src/X and you would like + your link tree to be in /usr/local/src/new-X, do the following: + + % mkdir /usr/local/src/new-X + % cd /usr/local/src/new-X + % lndir ../X +*/ + +#include <stdio.h> +#include <string.h> +#include <sys/errno.h> +#include <sys/stat.h> +#include <sys/param.h> +#include <errno.h> +#include <dirent.h> +#include <stdarg.h> +#include "sysinstall.h" + +#ifndef MAXPATHLEN +#define MAXPATHLEN 2048 +#endif + +static char *rcurdir; +static char *curdir; + +static int +equivalent(char *lname, char *rname) +{ + char *s; + + if (!strcmp(lname, rname)) + return 1; + for (s = lname; *s && (s = strchr(s, '/')); s++) { + while (s[1] == '/') + strcpy(s+1, s+2); + } + return !strcmp(lname, rname); +} + + +/* Recursively create symbolic links from the current directory to the "from" + directory. Assumes that files described by fs and ts are directories. */ + +static int +dodir(char *fn, struct stat *fs, struct stat *ts, int rel) +{ + DIR *df; + struct dirent *dp; + char buf[MAXPATHLEN + 1], *p; + char symbuf[MAXPATHLEN + 1]; + struct stat sb, sc; + int n_dirs; + int symlen; + char *ocurdir; + + if ((fs->st_dev == ts->st_dev) && (fs->st_ino == ts->st_ino)) + return 1; + + if (rel) + strcpy (buf, "../"); + else + buf[0] = '\0'; + strcat (buf, fn); + + if (!(df = opendir (buf))) { + msgDebug("%s: Cannot opendir\n", buf); + return 1; + } + + p = buf + strlen (buf); + *p++ = '/'; + n_dirs = fs->st_nlink; + while ((dp = readdir (df)) != NULL) { + if (dp->d_name[strlen(dp->d_name) - 1] == '~') + continue; + strcpy (p, dp->d_name); + + if (n_dirs > 0) { + if (stat (buf, &sb) < 0) { + msgDebug("Can't stat: %s\n", buf); + continue; + } + + if (S_ISDIR(sb.st_mode)) { + /* directory */ + n_dirs--; + if (dp->d_name[0] == '.' && + (dp->d_name[1] == '\0' || (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) + continue; + if (!strcmp (dp->d_name, "RCS")) + continue; + if (!strcmp (dp->d_name, "SCCS")) + continue; + if (!strcmp (dp->d_name, "CVS")) + continue; + if (!strcmp (dp->d_name, "CVS.adm")) + continue; + ocurdir = rcurdir; + rcurdir = buf; + curdir = isDebug() ? buf : (char *)0; + if (isDebug()) + msgDebug("%s:\n", buf); + if ((stat(dp->d_name, &sc) < 0) && (errno == ENOENT)) { + if (mkdir(dp->d_name, 0777) < 0 || + stat (dp->d_name, &sc) < 0) { + msgDebug("Unable to make or stat: %s\n", dp->d_name); + curdir = rcurdir = ocurdir; + continue; + } + } + if (readlink (dp->d_name, symbuf, sizeof(symbuf) - 1) >= 0) { + msgDebug("%s: is a link instead of a directory\n", dp->d_name); + curdir = rcurdir = ocurdir; + continue; + } + if (chdir (dp->d_name) < 0) { + msgDebug("Unable to chdir to: %s\n", dp->d_name); + curdir = rcurdir = ocurdir; + continue; + } + (void)dodir(buf, &sb, &sc, (buf[0] != '/')); + if (chdir ("..") < 0) { + msgDebug("Unable to get back to ..\n"); + return RET_FAIL; + } + curdir = rcurdir = ocurdir; + continue; + } + } + + /* non-directory */ + symlen = readlink (dp->d_name, symbuf, sizeof(symbuf) - 1); + if (symlen >= 0) { + symbuf[symlen] = '\0'; + if (!equivalent (symbuf, buf)) + msgDebug("%s: %s\n", dp->d_name, symbuf); + } else if (symlink (buf, dp->d_name) < 0) + msgDebug("Unable to create symlink: %s\n", dp->d_name); + } + + closedir (df); + return 0; +} + +int +lndir(char *from, char *to) +{ + struct stat fs, ts; + + if (!to) + to = "."; + + /* to directory */ + if (stat(to, &ts) < 0) { + msgDebug("Destination directory doesn't exist: %s\n", to); + return RET_FAIL; + } + if (!(S_ISDIR(ts.st_mode))) { + msgDebug ("%s: Not a directory\n", to); + return RET_FAIL; + } + if (chdir(to) < 0) { + msgDebug("Unable to chdir to %s\n", to); + return RET_FAIL; + } + /* from directory */ + if (stat(from, &fs) < 0) { + msgDebug("From directory doesn't exist: %s\n", from); + return RET_FAIL; + } + if (!(S_ISDIR(fs.st_mode))) { + msgDebug ("%s: Not a directory\n", from); + return RET_FAIL; + } + return dodir(from, &fs, &ts, 0); +} diff --git a/release/sysinstall/options.c b/release/sysinstall/options.c new file mode 100644 index 000000000000..c9c099afe766 --- /dev/null +++ b/release/sysinstall/options.c @@ -0,0 +1,289 @@ +/* + * The new sysinstall program. + * + * This is probably the last attempt in the `sysinstall' line, the next + * generation being slated for what's essentially a complete rewrite. + * + * $Id: options.c,v 1.26 1995/11/03 12:02:44 jkh Exp $ + * + * Copyright (c) 1995 + * Jordan Hubbard. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * verbatim and that no modifications are made prior to this + * point in the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Jordan Hubbard + * for the FreeBSD Project. + * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include "sysinstall.h" +#include <ctype.h> + +static char * +varCheck(Option opt) +{ + char *cp = NULL; + + if (opt.aux) + cp = variable_get((char *)opt.aux); + if (!cp) + return "<not set>"; + return cp; +} + +/* Show our little logo */ +static char * +resetLogo(char *str) +{ + return "[WHAP!]"; +} + +static char * +mediaCheck(Option opt) +{ + if (mediaDevice) { + switch(mediaDevice->type) { + case DEVICE_TYPE_UFS: + case DEVICE_TYPE_DISK: + return "File system"; + + case DEVICE_TYPE_FLOPPY: + return "Floppy"; + + case DEVICE_TYPE_FTP: + return "FTP"; + + case DEVICE_TYPE_CDROM: + return "CDROM"; + + case DEVICE_TYPE_TAPE: + return "Tape"; + + case DEVICE_TYPE_DOS: + return "DOS"; + + case DEVICE_TYPE_NFS: + return "NFS"; + + case DEVICE_TYPE_NONE: + case DEVICE_TYPE_NETWORK: + case DEVICE_TYPE_ANY: + default: + return "<unknown>"; + } + } + return "<unset>"; +} + +#define TAPE_PROMPT "Please enter the tape block size in 512 byte blocks:" +#define RELNAME_PROMPT "Please specify the release you wish to load:" +#define BPKG_PROMPT "Please specify the name of the HTML browser package:" +#define BBIN_PROMPT "Please specify a full pathname to the HTML browser binary:" +#define RETRY_PROMPT "Please specify the number of times to retry an FTP request:" +#define PKG_PROMPT "Please specify a temporary directory with lots of free space:" + +static Option Options[] = { +{ "NFS Secure", "NFS server talks only on a secure port", + OPT_IS_VAR, NULL, VAR_NFS_SECURE, varCheck }, +{ "NFS Slow", "User is using a slow PC or ethernet card", + OPT_IS_VAR, NULL, VAR_SLOW_ETHER, varCheck }, +{ "Debugging", "Emit extra debugging output on VTY2 (ALT-F2)", + OPT_IS_VAR, NULL, VAR_DEBUG, varCheck }, +{ "Yes to All", "Assume \"Yes\" answers to all non-critical dialogs", + OPT_IS_VAR, NULL, VAR_NO_CONFIRM, varCheck }, +{ "FTP OnError", "What to do when FTP requests fail: abort, retry, reselect.", + OPT_IS_FUNC, mediaSetFtpOnError, VAR_FTP_ONERROR, varCheck }, +{ "FTP Retries", "If FTP OnError == retry, this is the number of times to try.", + OPT_IS_VAR, RETRY_PROMPT, VAR_FTP_RETRIES, varCheck }, +{ "FTP username", "Username and password to use instead of anonymous", + OPT_IS_FUNC, mediaSetFtpUserPass, VAR_FTP_USER, varCheck }, +{ "Tape Blocksize", "Tape media block size in 512 byte blocks", + OPT_IS_VAR, TAPE_PROMPT, VAR_TAPE_BLOCKSIZE, varCheck }, +{ "Extract Detail", "How verbosely to display file name information during extractions", + OPT_IS_FUNC, mediaSetCPIOVerbosity, VAR_CPIO_VERBOSITY, varCheck }, +{ "Release Name", "Which release to attempt to load from installation media", + OPT_IS_VAR, RELNAME_PROMPT, VAR_RELNAME, varCheck }, +{ "Browser Pkg", "This is the browser package that will be used for viewing HTML docs", + OPT_IS_VAR, BPKG_PROMPT, VAR_BROWSER_PACKAGE, varCheck }, +{ "Browser Exec", "This is the path to the main binary of the browser package", + OPT_IS_VAR, BBIN_PROMPT, VAR_BROWSER_BINARY, varCheck }, +{ "Media Type", "The current installation media type.", + OPT_IS_FUNC, mediaGetType, VAR_MEDIA_TYPE, mediaCheck }, +{ "Package Temp", "The directory where package temporary files should go", + OPT_IS_VAR, PKG_PROMPT, "PKG_TMPDIR", varCheck }, +{ "Use Defaults", "Reset all values to startup defaults", + OPT_IS_FUNC, installVarDefaults, 0, resetLogo }, +{ NULL }, +}; + +#define OPT_START_ROW 4 +#define OPT_END_ROW 20 +#define OPT_NAME_COL 0 +#define OPT_VALUE_COL 16 +#define GROUP_OFFSET 40 + +static char * +value_of(Option opt) +{ + static char ival[40]; + + switch (opt.type) { + case OPT_IS_STRING: + return (char *)opt.data; + + case OPT_IS_INT: + sprintf(ival, "%d", (int)opt.data); + return ival; + + case OPT_IS_FUNC: + case OPT_IS_VAR: + if (opt.check) + return opt.check(opt); + else + return "<*>"; + } + return "<unknown>"; +} + +static void +fire(Option opt) +{ + if (opt.type == OPT_IS_FUNC) { + int (*cp)(char *) = opt.data; + + cp(NULL); + } + else if (opt.type == OPT_IS_VAR) { + if (opt.data) { + (void)variable_get_value(opt.aux, opt.data); + dialog_clear(); + } + else if (variable_get(opt.aux)) + variable_unset(opt.aux); + else + variable_set2(opt.aux, "YES"); + } + if (opt.check) + opt.check(opt); + clear(); + refresh(); +} + +int +optionsEditor(char *str) +{ + int i, optcol, optrow, key; + static int currOpt = 0; + + dialog_clear(); + clear(); + + while (1) { + /* Whap up the header */ + attrset(A_REVERSE); mvaddstr(0, 0, "Options Editor"); attrset(A_NORMAL); + for (i = 0; i < 2; i++) { + mvaddstr(OPT_START_ROW - 2, OPT_NAME_COL + (i * GROUP_OFFSET), "Name"); + mvaddstr(OPT_START_ROW - 1, OPT_NAME_COL + (i * GROUP_OFFSET), "----"); + + mvaddstr(OPT_START_ROW - 2, OPT_VALUE_COL + (i * GROUP_OFFSET), "Value"); + mvaddstr(OPT_START_ROW - 1, OPT_VALUE_COL + (i * GROUP_OFFSET), "-----"); + } + /* And the footer */ + mvprintw(OPT_END_ROW + 0, 0, "Use SPACE to select/toggle an option, arrow keys to move,"); + mvprintw(OPT_END_ROW + 1, 0, "? or F1 for more help. When you're done, type Q to Quit."); + + optrow = OPT_START_ROW; + optcol = OPT_NAME_COL; + for (i = 0; Options[i].name; i++) { + /* Names are painted somewhat gratuitously each time, but it's easier this way */ + mvprintw(optrow, OPT_NAME_COL + optcol, Options[i].name); + if (currOpt == i) standout(); + mvprintw(optrow++, OPT_VALUE_COL + optcol, value_of(Options[i])); + if (currOpt == i) standend(); + if (optrow == OPT_END_ROW) { + optrow = OPT_START_ROW; + optcol += GROUP_OFFSET; + } + clrtoeol(); + } + standout(); + mvaddstr(OPT_END_ROW + 3, 0, Options[currOpt].desc); + standend(); + clrtoeol(); + move(0, 14); + + /* Start the edit loop */ + key = toupper(getch()); + switch (key) { + case KEY_F(1): + case '?': + systemDisplayHelp("options"); + break; + + case KEY_UP: + if (currOpt) + --currOpt; + else + beep(); + continue; + + case KEY_DOWN: + if (Options[currOpt + 1].name) + ++currOpt; + else + beep(); + continue; + + case KEY_HOME: + currOpt = 0; + continue; + + case KEY_END: + while (Options[currOpt + 1].name) + ++currOpt; + continue; + + case ' ': + dialog_clear(); + fire(Options[currOpt]); + dialog_clear(); + clear(); + continue; + + case 'Q': + clear(); + dialog_clear(); + return RET_SUCCESS; + + default: + beep(); + } + } + /* NOTREACHED */ + return RET_SUCCESS; +} diff --git a/release/sysinstall/package.c b/release/sysinstall/package.c new file mode 100644 index 000000000000..cd75c084f720 --- /dev/null +++ b/release/sysinstall/package.c @@ -0,0 +1,280 @@ +/* + * The new sysinstall program. + * + * This is probably the last program in the `sysinstall' line - the next + * generation being essentially a complete rewrite. + * + * $Id: package.c,v 1.26 1995/11/12 11:02:43 jkh Exp $ + * + * Copyright (c) 1995 + * Jordan Hubbard. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * verbatim and that no modifications are made prior to this + * point in the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Jordan Hubbard + * for the FreeBSD Project. + * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/errno.h> +#include <sys/param.h> +#include <sys/mount.h> +#include <sys/stat.h> +#include "sysinstall.h" + +static char *make_playpen(char *pen, size_t sz); + +/* Like package_extract, but assumes current media device */ +int +package_add(char *name) +{ + if (!mediaVerify()) + return RET_FAIL; + return package_extract(mediaDevice, name); +} + +/* Extract a package based on a namespec and a media device */ +int +package_extract(Device *dev, char *name) +{ + char path[511]; + char pen[FILENAME_MAX]; + char *where; + int fd, ret; + + /* If necessary, initialize the ldconfig hints */ + if (!file_readable("/var/run/ld.so.hints")) + vsystem("ldconfig /usr/lib /usr/local/lib /usr/X11R6/lib"); + + /* Check to make sure it's not already there */ + if (!vsystem("pkg_info -e %s", name)) { + msgDebug("package %s marked as already installed - return SUCCESS.\n", name); + return RET_SUCCESS; + } + + if (!dev->init(dev)) { + dialog_clear(); + msgConfirm("Unable to initialize media type for package extract."); + return RET_FAIL; + } + + ret = RET_FAIL; + /* Make a couple of paranoid locations for temp files to live if user specified none */ + if (!variable_get("PKG_TMPDIR")) { + Mkdir("/usr/tmp", NULL); + Mkdir("/var/tmp", NULL); + } + + sprintf(path, "packages/All/%s%s", name, strstr(name, ".tgz") ? "" : ".tgz"); + msgNotify("Adding %s\nfrom %s", path, dev->name); + fd = dev->get(dev, path, TRUE); + if (fd >= 0) { + pen[0] = '\0'; + if ((where = make_playpen(pen, 0)) != NULL) { + if (mediaExtractDist(pen, fd)) { + if (file_readable("+CONTENTS")) { + /* Set some hints for pkg_add so that it knows how we got here in case of any depends */ + switch (mediaDevice->type) { + case DEVICE_TYPE_FTP: + if (variable_get(VAR_FTP_PATH)) { + char ftppath[512]; + + /* Special case to leave hint for pkg_add that this is an FTP install */ + sprintf(ftppath, "%spackages/All/", variable_get(VAR_FTP_PATH)); + variable_set2("PKG_ADD_BASE", ftppath); + } + break; + + case DEVICE_TYPE_DOS: + variable_set2("PKG_PATH", "/dos/freebsd/packages/All:/dos/packages/All"); + break; + + case DEVICE_TYPE_CDROM: + variable_set2("PKG_PATH", "/cdrom/packages/All:/cdrom/usr/ports/packages/All"); + break; + + default: + variable_set2("PKG_PATH", "/dist/packages/All:/dist/freebsd/packages/All"); + break; + } + + if (vsystem("(pwd; cat +CONTENTS) | pkg_add %s-S", + !strcmp(variable_get(VAR_CPIO_VERBOSITY), "high") ? "-v " : "")) { + dialog_clear(); + if (!variable_get(VAR_NO_CONFIRM)) + msgConfirm("An error occurred while trying to pkg_add %s.\n" + "Please check debugging screen for possible further details.", name); + else + msgNotify("An error occurred while trying to pkg_add %s.", name); + } + else { + msgNotify("Package %s added successfully!", name); + ret = RET_SUCCESS; + } + } + else { + dialog_clear(); + if (!variable_get(VAR_NO_CONFIRM)) + msgConfirm("The package specified (%s) has no CONTENTS file. This means\n" + "that there was either a media error of some sort or the package\n" + "file itself is corrupted. It is also possible that you simply\n" + "ran out of temporary space and need to go to the options editor\n" + "to select a package temp directory with more space. Either way,\n" + "you may wish to look into the problem and try again.", name); + else + msgNotify("The package specified (%s) has no CONTENTS file. Skipping.", name); + } + } + else { + ret = RET_FAIL; + if (!variable_get(VAR_NO_CONFIRM)) + msgConfirm("Unable to extract the contents of package %s. This means\n" + "that there was either a media error of some sort or the package\n" + "file itself is corrupted.\n" + "You may wish to look into this and try again.", name); + else + msgNotify("Unable to extract the contents of package %s. Skipping.", name); + } + if (chdir(where) == -1) + msgFatal("Unable to get back to where I was before, Jojo! (That was: %s)", where); + vsystem("rm -rf %s", pen); + if (isDebug()) + msgDebug("Nuked pen: %s\n", pen); + } + else { + dialog_clear(); + msgConfirm("Unable to find a temporary location to unpack this stuff in.\n" + "You must simply not have enough space or you've configured your\n" + "system oddly. Sorry!"); + ret = RET_FAIL; + } + dev->close(dev, fd); + if (dev->type == DEVICE_TYPE_TAPE) + unlink(path); + } + else { + msgDebug("pkg_extract: get operation returned %d\n", fd); + if (variable_get(VAR_NO_CONFIRM)) + msgNotify("Unable to fetch package %s from selected media.\n" + "No package add will be done.", name); + else { + dialog_clear(); + msgConfirm("Unable to fetch package %s from selected media.\n" + "No package add will be done.", name); + } + } + return ret; +} + +static size_t +min_free(char *tmpdir) +{ + struct statfs buf; + + if (statfs(tmpdir, &buf) != 0) { + msgDebug("Error in statfs, errno = %d\n", errno); + return -1; + } + return buf.f_bavail * buf.f_bsize; +} + +/* Find a good place to play. */ +static char * +find_play_pen(char *pen, size_t sz) +{ + struct stat sb; + + if (pen[0] && stat(pen, &sb) != RET_FAIL && (min_free(pen) >= sz)) + return pen; + else if (stat("/var/tmp", &sb) != RET_FAIL && min_free("/var/tmp") >= sz) + strcpy(pen, "/var/tmp/instmp.XXXXXX"); + else if (stat("/tmp", &sb) != RET_FAIL && min_free("/tmp") >= sz) + strcpy(pen, "/tmp/instmp.XXXXXX"); + else if ((stat("/usr/tmp", &sb) == RET_SUCCESS || mkdir("/usr/tmp", 01777) == RET_SUCCESS) && + min_free("/usr/tmp") >= sz) + strcpy(pen, "/usr/tmp/instmp.XXXXXX"); + else { + dialog_clear(); + msgConfirm("Can't find enough temporary space to extract the files, please try\n" + "This again after your system is up (you can run /stand/sysinstall\n" + "directly) and you've had a chance to point /var/tmp somewhere with\n" + "sufficient temporary space available."); + return NULL; + } + return pen; +} + +/* + * Make a temporary directory to play in and chdir() to it, returning + * pathname of previous working directory. + */ +static char * +make_playpen(char *pen, size_t sz) +{ + static char Previous[FILENAME_MAX]; + + if (!find_play_pen(pen, sz)) + return NULL; + + if (!mktemp(pen)) { + dialog_clear(); + msgConfirm("Can't mktemp '%s'.", pen); + return NULL; + } + if (mkdir(pen, 0755) == RET_FAIL) { + dialog_clear(); + msgConfirm("Can't mkdir '%s'.", pen); + return NULL; + } + if (isDebug()) { + if (sz) + msgDebug("Requested space: %d bytes, free space: %d bytes in %s\n", (int)sz, min_free(pen), pen); + } + if (min_free(pen) < sz) { + rmdir(pen); + dialog_clear(); + msgConfirm("Not enough free space to create: `%s'\n" + "Please try this again after your system is up (you can run\n" + "/stand/sysinstall directly) and you've had a chance to point\n" + "/var/tmp somewhere with sufficient temporary space available."); + return NULL; + } + if (!getcwd(Previous, FILENAME_MAX)) { + dialog_clear(); + msgConfirm("getcwd"); + return NULL; + } + if (chdir(pen) == RET_FAIL) { + dialog_clear(); + msgConfirm("Can't chdir to '%s'.", pen); + } + return Previous; +} diff --git a/release/sysinstall/power.uu b/release/sysinstall/power.uu new file mode 100644 index 000000000000..0a90d3ba904d --- /dev/null +++ b/release/sysinstall/power.uu @@ -0,0 +1,121 @@ +begin 664 power.gif +M1TE&.#EAJP!``/<```````0#$@L`(0P,#Q,("!0:*A<0'ALE-!X:)2,`4"0D +M,"4`4B4@*28:*2<`52@P02H`62HB-"L#4RL&3BLG.2P`6RT`7C`P$S`P,#$I +M/3((5#(/0#(V13,O0#0>&C4D,S8I/S@H-SA&7#DP0#DP2#HS2CHV1#P22#PK +M"CP]3STP(SXU2#X^)C\X2D`624,V24,Y340]5D0^1$0^3D4<2$5%6D8S.D<0 +M.D@714A(3TH_5TI(84ICA$LK.DPB/TPH/TU$74U-8DU38$]:;U`=0%$_35%) +M7%%ND%(W1U,C/54G0%<O1%<S,U=*5%=-8%=265A\H5HK/5I")5]?7V&'IV<Q +M/6A=3FAI9VLU06P]3'%%5'%.5G-R6G0H,G4:)G<Y17A(+7F<J7I6#GQ\77TP +M.X&!@H=&0(@[1HE=38F%>8I00HI@$(UG18Z.B)!M1)2)$Y<\1I=E"IA\"YE8 +M,YF8C)IP`YM,`)M=`)N;`*!I'J.CHZ0B+:HP.*MC4JMV%*VLJZY_&*Z8,J]& +M3K")%;"C3["VN;(Z0K*QL;R\O+Z^OK^$`,"Z?L7#0,:%%LJ+%\O*MLPI,<P[ +M0LR$&LUM2-`S.M"-#]"?$=9,3]=$1]>6#]GB=]NF"^+7(^;(%>JU">K)`.L] +M0>M%1.VF`O&F!?'I@/1-2_=$0_=44??Q#O?\ZOCE#_R_`/SX!OW[`_W]!O[^ +M`_]:5_]K9?^P`/^Q`/^R`/^S`/^T`/^U`/^V`/^W`/^X`/^Y`/^Z`/^[`/^\ +M`/^]`/^_`/_``/_!`/_"`/_#`/_$`/_%`/_&`/_(`/_)`/_*`/_+`/_,`/_- +M`/_.`/_/`/_0`/_1`/_2`/_3`/_4`/_5`/_6`/_7`/_8`/_9`/_:`/_;`/_< +M`/_=`/_>`/_?`/_@`/_A`/_B`/_C`/_D`/_E`/_F`/_G`/_H`/_I`/_J`/_K +M`/_L`/_M`/_N`/_O`/_P`/_Q`/_R`/_S`/_S(__U`/_V`/_Y`/_]`/_^\/__ +M`/__9````````````````"'Y!`$``(D`+`````"K`$``0`C_`!,)'$BPH,&# +M"!,J7,BPH<.'$"-*G$BQHL6+"9]`@O/@@`P,'FY4P6(#00`"5PQ.,51$P"&, +M,&/*G-E03Y1%;5+=&),J%:E\8;Q0@L,D"9,0$2)T`,$`0!E$-`\"P%!0#P`& +MC-8`D")+#`$`BKR"K84"0!Q%*%"(`H!"EJQ*;!7%02$F#@`Q:._6<BL+@-DZ +M!`BLXB7&KZ)5=%>)07&L#HI-R90M:^8,&C1ITJA9NX8-F[9MW+I]`Q=.W#AR +MJGHP&K=N73LWETZ9R3*E2`Q!I4+I#@6*3X\/(YJTH-!$G_'CR),K7WX<#\5] +M?*.[G9/`1W1)2J1KW\YW%BU;MV[E_](E"4*"7[^$%3.3(($Q3PE.0&/&K%DS +M&I:D3:/^0ULVT*IT$T@%"?Q0#CGFJ$((&&!,L@4GJJB"QA9PP"*(`'B@@@<+ +MEV#"&RBFF")($"44P=R)*"[GW$30<4>===L1&%T>YHTBW2P:.`#&+KSPX@MZ +MOSABWC#$%'/,,2Y`,(<G-$CS##319&;!`ME@XT:!WG@SFFGD+)'`(/&HLPX[ +M[;SS3CSRS#.//?;<XR8^^M"3P0Q-3`$$B1F`T$$&&235Q"LI'N=*`QY$L046 +M333QA`%6J/@<=Y!&VATMM8`W'H^]_/A+,,(,4TPQQAR#C&3U.?.D?M-48PTV +MV7P6VFBEG?]6SCGHI*,..^RX\PX\:,Y33YMNWH,/G*ZP`<LIAFPA0@D<'*"` +M#SK$(&T),:Q@;0<RP+"%*ZVP`FARKWP;J#XK1F7NN1%1P<,14*@+1`Q`[+## +M$#&T(=`A+#R2S[YM-*'%%DXX$8,.4$!1!+H()ZRP0G3\EL%+#"%`@!X+5VSQ +MN7_LT847/.GA11>/%,(''R%4\<476601"2B@4-)#`1QD,$+"4PE4!@!3))*# +M7P`,0,<3`-`QA5]T7.&4'@/PG#,`!@R``2([^S7`(4A+C3-!/?/\1"(#,)#( +M(0"8</$A9)BRQP$?=(%``07TE,@(D$#R114?-#"""0%`?'%"+4K_ZO??DU:* +MRZ6*K*&(,,!PZJF1HBJC##/.5`;E--14PUFKH'7C#6GCG&8.)V"@@0<>:'!R +M9CQJHJ(``R.$\$$(/_2`Q`PK4("``8R,J[NC+$)*G00N!%_!`FZ-8D$"-$BB +M1A2RN"`!7VHL0,0LC20P1RVU&+\`(+T(F8`22]"@P?AS,+.,&>8EX$![)VQR +MC35S3/!#YEJ2)LX2#OQ`JYBYNL-KFJA8@H56D((21.``@CA%*5I&AA',(`A. +MJ($.BK.["I+K48`#W"@D(0GO",X6N<B$(S;Q(V!LBDA'0L:HS&>?9WC"$I;H +M1#.B00W/;"-+X%#%:,:!#M>HPU9DTA4\_^21IGK\ZDW#,HXK'A"*4YB"#TN8 +MP0YT`(,'/.`,E)!!#"+@@3$$@A.H0$6X]/$*5'"""QXPPA!*P`5ZM")%Y=J; +M'!T"%:@0)!5_V%<JCO`"+&2A"5?H@R!>4((:U(`"B+!C09Z@!31H008"T\$. +M8E`"$A1"D7/,I"8/@DF!Z($*8:`"%:#``QZ(0`0[*$,A"K')5KJ2CFWHY"MG +M24N$_,$#A@A!!R!2!3A\@)6U#&;%]%`A,D1@#WLP!#(A@844C*`'(2B@4Q!! +M!P3L`0XIZ$`#9"G,;LH$$2'PPA]2\0@/+*(GJ2A#,LF0!!]$H0I12`("G)4! +M!1B`FS/I&08PX/\7BE6L#3A39,UHB0@F]$``!\C`!\H@@$?TY`A[@,0>D("% +M)9C@`0@8@`#\N3!]8L`$]AI:&_:Q#Q8`8!]WN8`4+B`&%K``I01PZ04`P`@` +MO'0?;@#`!5QJ4Y.2M*9N("E);4K2G#*"$``(A!1.*M2F.O6I4(WJ4S51!0N= +MP8EP>,$,%G$((?2`$I$0Q!>2$()L90`!FI"J6M<:1SH>@A&5X,MW;&&+N<Y" +M%K.812448:/MB$(1<2V>(C:QG;S^=1.ZT,4NUB*&5:PB&$0R1JB8\8QH-*,^ +MSSA59JRQ*AN^RGZ>,X<XIH`&-[""'>]@A`Q&(`+<Y*84D3!$%I"P!"3_I$`' +M1C`!HRRXN[8^I&_7,0,.VN,"&@1/`PG(Q%TS*)VY;L(,2UA`?(J+W!-8`E3' +MB!\-EJ`!%VS/$EN@07LT8%SQ3<`%>?B$:,E!#DYP`AWMZ,038M$'*]`#'JK@ +M@A4X<8]/B`$!'OC``U*PA"IDH08<(`1O+>A;AP!7.B_BRRC`X)9,Y`$'LJ#. +M!)8+!AJ<X`1YB(XCHN"""51A$[C8A?=^D;AAG&`!CEC&'!PP@4U@%DJ9H48> +M%M`?^HVF$^L#0SO.8:MUJ.,=\OC?/`@A"#-0(&9L&X$-EO"%,VC!"5JXLA-@ +MP(D%ZZ[!#7EP="+LED9DQRTRXLL<)'#>X)W`_P'9F=()@N<""T#`$:OP7J>( +M00Q/Y.@'RU@&?9PAC4^H87V6P$8>\A>:^H7C-#D*!#SXUP[_]>I7]J"'"4H" +M@A2<P10*O$054A"$(00L8%9XHY?AB,'ML.<$?94.@0+KEB](%PR`P`X8:I&) +MXX'8$7EPP2B$T8CU`<(1C@"#!#3@B68,`@(G`$0GIO%L,)##/VJ(SR!@.`@W +M;``"@3B'.FY%IEVASE=L"E826<$$05#@`1)\@0DH4`5*D&'`(\B=[E[QA#Z< +MH@]9R``G7,$<,#-$S,R%E'>^(Q[%\B)3+`:&,/@<*E$E0]"4>5(T**>JRV7N +M&UL:1SG,88Y:W:H=9?\:8A'3C43CC`$,L*#$%P3A(3@X89(PV($,3`"#%\BL +M!3`H`0B,8`0=9(`$)1`X*A@!1G&AR.`+07C"M4,I2^4"4^A)7*>P:_''91S' +MJ5H5YCX;*P31*AUC*C>OYF%&0KB!$$TG%@9R$`(LU&`')4``*ESQK:4_`00Q +ML!T%C+`"=@6^4:LV#M2]*<<V.'244$#E#@(&A!H`H01'&,)3.HF((LB@"5+> +M0A""0,DA',$)C$\]3%9IRE+R@)1MH(,>>A(R4;8+"D-H%Q5$,`35^_[WP`^^ +M\(>O>D3H(00"^`-#E$_\YD>$#EXX@P+HX)`_\,$#]G*^]FUY`THP0`!;2P3_ +M'6Q@`!.406\%N0(?=""#[;M_((CP@BDX8H(,)*$+9%A"#U8P@A8(G0#,EPB( +M8``L$0%E\'[N]P>&X#)=H`9]$#=>L`>1\`)U5ULS$`*$(A208%$4T``(J'V) +MQ`15L`4]\05>X%#IM`=?@`558#)9``>0X`5)<``,T`$&D'T?V'SQAP;[@@9= +M0'NI$`9=``ED$`51\!L-@``4$`$*T`$!0'T)LT_[!%(70P<8<(`#@0'A-TO& +MYP4U4`!I@`1'8`/H1`5"L0=%85$*M3I3@4\T,5`WDS.)4`93<`5Z@`ATF`AZ +M,`4YLX?VH@=7,`74APA34`9T@(5T>'Z>=`57$(=8_X,!;5"(>C@%]H*'<F@Q +M0D`)57``(<`$!G``&X""&@$)9Y`%2V`#,+`"!4`5%^-1_40'82-^87,S99`# +M35&+`'`(&:4'A\!/8`,`5W"(`)`#<P@`3P`T*6$"5S,01',(!I"+.W,(M'@Q +M/6`*F'`&D8"&R#=[J<`#>T`)AG`&4=``(6`"(Y`W>S-0`V$T90`=*$``LG`! +M9;$8\]@7**`(^*@(:]$6N5`89X&/E5`6HC`+?G`7RV6/LZ`+A7$8!+!24C`8 +MJ[!G7!<9@Z9Q.;89K/(9FO,-X?!HIZ$*1'8KYY`$L'`)9R`(EZ`%(I`%R"0( +M"Q@)9]`%P#$#/L<`J``GB?^G'%"GC@*!ASRC%K)0!W[Q5P!``-\Q"F7A%W5@ +MCVY!"X#A%VHA"DFY5&(0'6SQ%0!0!XDE!T7I6&QA#&71#%JA"(\#.1HW#92S +M&=G0*MS`#2`7*Z?A#8S0!VS`">P0#ZB`!G!0`W!P"I%P";F!":`0"IA@"&00 +M`B/@!$9``@B@;SFIDZTV=9+9E+0@'H/C"X4!`)NP"BU6)*&"#!2)6<^`*ATW +M=AM9=N-P5*CP"9:@!IQ@:>]`"`'``2[)!V3P`P<@94L@;R.0`0U@!03WF+PC +M$5+7",9YG,@9:Y(Y"Y5R"YG0",CF")6`;)L@D<:`#)XP"'DP!XWP"94%0^`9 +MGI__(!H<^6CD4`[E$`Z,,`;T53IKAVZL\`$$T((]\`(=``,PD`+VI&#">2*+ +MQS>0DFTGP!>98`8G<)!3QYQT=0NU4&SG(0R;,`<$X@/&D`S9E@>"Y@QNH`&# +M$`W/P`;(TPTBV@F6H`7F@02?\)%N$`AK@`=7$`N$P`B!H`8V8`.4``D#@`>< +M\`D>$`)90"&&``FA@`9"0`%=UI_#&1%2EV$+`"/%DPF3Z4&U<`NXH`N\X`CK +MPV+!0`S400/'D`<%@G&F`@A1<@U7\@,VM`V@H0ULX``.,`BS4@[HH`KT`"%( +M-@_Q,`8RD`4R\``Y@`<<('^A8`J@<`DT9PA-(`0F0`](_PJ9O>,B3<H7@/`\ +MDH`##K``8)``TB4+FZ`!6"`)<S`E(38+9J`!>8`=$G`"/(*EUC,'RN8"EI`, +MS.`(!*(!8)`'EN`)F%$Y;I`__R&B6M*1+I``2'`.XB8FE69N]:`*6``+I?`" +M#Y"?!P`''4(&&2`",9`",W!S^=:HR?&?"+&D7<I!DO`%$\`7P]-7F9`)#D`$ +M?"$)ERH+2I``C0`>N#"O<Q`DZ^-8PN`)MI8`@*`,SP`(:H`$=F8>+E`-W'"F +M'\<YYT`#F%HKK9$KNY(FOH(*2"`#16`$)7``!6`(UKA`9Q`$\K(#1O`$(1"< +MWGI!C[H=9"8+HP"E:)8`<C6NY/\*I;0P/'G@")*`;*/0"\"`I0NP=9(578!V +M8Y;Q">9A"=G@!CS6:)Q##D`V`>P`1)4&#T.D)IAV#ZW@"IR0`SF00)>`J,L2 +M`T&0GT"0`H%00>$2+GSGMD[7')$)89$:(S1+H`0R!]%A(UFP`!HP"@['"YX0 +M#*SJF<=@"1`P`<U@"2[@":>"#8Y@/=>@#6#Z`Z)A/^B0J6K0#D;F&F82#Y<& +M+&_R"JW0`AT!`C,P`S$``TOHL28P`S:`"KO#"$0P"9'`!U9&`6Z@LL@!K@>! +M<)(0!1I@`2>P!"'VKDI@`1J@!!16/&9@`<NF`6:`/;(@"4DR/C3@"+[`)!9@ +M`=1EO)?_M0R60`/$ZV$T$`C=L):!(`'=2P,T4`(:\`-ND*+H0&E"=&Y'I&[& +M\0I5<`J@\`4/P`$CT`$FP`$]P`>@8`,S\`&$($8IX@J$``1;L`4_P`BNP+O? +M.K>365C80Z67T@N]@![!P"F&JT*D0AF6(0V683D9V99:PI&R8@YG=W*[DK7H +M)KHXJ0]C\`6F,*BPY01#0'JJ^P`9RP$EH`,K0`(QT`+U%P$?$`%\T@`F,`0D +MT&5QFZ00L:0;C%=5-SB*!<)9!UF&>PR1@7$6F9:7HY&.)@[G*<,F%T1GLG(L +M)RQDQ`E5939&(`)`4`1PH`5#\"Y)QW,S0`$VT`1%4`9'%0AC_\`(C'S!KL`* +M&/QT&KS%E&FOE^(C(JPXV`6:9=D,F;5QU*`9G.$JW%`_7#)RZ%"_8^(.NA*Z +MZ88/=/P*.=`%I7`*6A`$'/``,P!&C*`#%$`!.4=Z"M``+1`#:Z0"G'#%O.6[ +M!H$'=O#,T!S-TCS-U#S-=V`'UWP'VKS-W'P'<7`'=1`'X5P'Y%S.YEP'<H#. +M<K#.[-S.>"`'[QS/);`(^_((94``.1`(@?`&&=`'2%``?$(!!A`(HU/0HS,& +M#=`#L_4"V1K$04`!!&W0$CW1%,W,.1@1>I`/Z01*5.`$?3`)?1#263`#(D`% +M1Y`2""$#658$37!S,*#$.T`"Z'?1M7QT"*\72J3$`SL0+S<'!#I``@&8"'_` +M`$6``#TP956@!5<P24!P!!WMAC1-4(AP!*5T!%0]!#M@2B^1!HFP+QJ="&$0 +M!J8F+SPP2C40U=I7"'J0>;U7"%33!D<@`JY7,`4S!$,`3&A]T6JM!V40!F6@ +.!W^@!WB=UX2M20$!`#N0 +` +end diff --git a/release/sysinstall/version.h b/release/sysinstall/version.h new file mode 100644 index 000000000000..b42c26e8937d --- /dev/null +++ b/release/sysinstall/version.h @@ -0,0 +1 @@ +#define RELEASE_NAME "__RELEASE" diff --git a/sbin/scsiformat/scsiformat.sh b/sbin/scsiformat/scsiformat.sh deleted file mode 100644 index 5c6dd88bf67c..000000000000 --- a/sbin/scsiformat/scsiformat.sh +++ /dev/null @@ -1,143 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 1995 Peter Dufault -# -# All rights reserved. -# -# This program is free software. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -# IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# $Id$ -# -# scsiformat [-wq] [-p page-control] raw-device-name -# - -PATH="/sbin:/usr/sbin:/bin:/usr/bin"; export PATH - -READONLY=yes -QUIET=no -RAW= -PAGE=0 - -usage() -{ - echo "Usage: scsiformat [-wq] [-p page-control] raw-device-name" 1>&2 - exit 2 -} - -while getopts "qwp:" option -do - case $option in - q) - QUIET=yes - ;; - w) - READONLY=no - ;; - p) - case $OPTARG in - c) - PAGE=0 - ;; - d) - PAGE=2 - ;; - s) - PAGE=3 - ;; - v) - PAGE=1 -echo "*** note: for variable parameters, 1-bit means 'can write here'" - ;; - *) - usage - ;; - esac - ;; - ?) - usage - ;; - esac -done - -shift $(($OPTIND - 1)) - -if [ $# -ne 1 ] ; then - usage -fi - -RAW=$1 - -if [ "x$RAW" = "x" ] ; then - usage -fi - -if expr "$RAW" : 'sd[0-9][0-9]*$' > /dev/null ; then - # generic disk name given, convert to control device name - RAW="/dev/r${RAW}.ctl" -fi - -scsi -f $RAW -v -c "12 0 0 0 v 0" 96 -i 96 "s8 z8 z16 z4" || exit $? - -if [ "$QUIET" = "no" ] ; then - scsi -f $RAW \ --v -c "1A 0 v:2 4:6 0 64 0" $PAGE \ --i 72 "{Mode data length} i1 \ -{Medium type} i1 \ -{Device Specific Parameter} i1 \ -{Block descriptor length} i1 \ -{Density code} i1 \ -{Number of blocks} i3 \ -{Reserved} i1 \ -{Block length} i3 \ -{PS} b1 \ -{Reserved} b1 \ -{Page code} b6 \ -{Page length} i1 \ -{Number of Cylinders} i3 \ -{Number of Heads} i1 \ -{Starting Cylinder-Write Precompensation} i3 \ -{Starting Cylinder-Reduced Write Current} i3 \ -{Drive Step Rate} i2 \ -{Landing Zone Cylinder} i3 \ -{Reserved} b6 \ -{RPL} b2 \ -{Rotational Offset} i1 \ -{Reserved} i1 \ -{Medium Rotation Rate} i2 \ -{Reserved} i1 \ -{Reserved} i1 " || exit $? -fi # !quiet - -if [ "$READONLY" = "no" ] -then - # grace period, last chance to hit INTR - echo -n "Three seconds until format begins." - sleep 1 - echo -n "." - sleep 1 - echo -n "." - sleep 1 - # formatting may take a huge amount of time, set timeout to 2 hours - echo " Formatting... this may take a while." - scsi -s 7200 -f $RAW -c "4 0 0 0 0 0" -fi diff --git a/share/examples/find_interface/Makefile b/share/examples/find_interface/Makefile deleted file mode 100644 index fcc330cc1949..000000000000 --- a/share/examples/find_interface/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# $Id$ - -PROG= find_interface -NOMAN= - -.include <bsd.prog.mk> diff --git a/share/examples/find_interface/README b/share/examples/find_interface/README deleted file mode 100644 index 4df4399cdbc7..000000000000 --- a/share/examples/find_interface/README +++ /dev/null @@ -1,9 +0,0 @@ -This is a simple program which demonstrates how to query the kernel -routing mechanism using only a UDP socket. Pass it a hostname on -the command line (sorry, it doesn't parse dotted decimal) and it will -print out an IP address which names the interface over which UDP -packets intended for that destination would be sent. -A more sophisticated program might use the list obtained from SIOCGIFCONF -to match the address with an interface name, but applications programmers -much more often need to know the address of the interface rather than -the name. diff --git a/share/examples/sliplogin/slip.login b/share/examples/sliplogin/slip.login deleted file mode 100644 index 3c70095a2fcc..000000000000 --- a/share/examples/sliplogin/slip.login +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -# -# @(#)slip.login 8.1 (Berkeley) 6/6/93 - -# -# generic login file for a slip line. sliplogin invokes this with -# the parameters: -# 1 2 3 4 5 6 7-n -# slipunit ttyspeed loginname local-addr remote-addr mask opt-args -# -/sbin/ifconfig sl$1 inet $4 $5 netmask $6 -exit diff --git a/sys/dev/aic7xxx/aicasm.c b/sys/dev/aic7xxx/aicasm.c deleted file mode 100644 index e2745f094023..000000000000 --- a/sys/dev/aic7xxx/aicasm.c +++ /dev/null @@ -1,643 +0,0 @@ -/*+M************************************************************************* - * Adaptec AIC7770/AIC7870 sequencer code assembler. - * - * Copyright (c) 1994 John Aycock - * The University of Calgary Department of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of Calgary - * Department of Computer Science and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Comments are started by `#' and continue to the end of the line; lines - * may be of the form: - * <label>* - * <label>* <undef-sym> = <value> - * <label>* <opcode> <operand>* - * - * A <label> is an <undef-sym> ending in a colon. Spaces, tabs, and commas - * are token separators. - * - *-M*************************************************************************/ -static char id[] = "$Id: aic7xxx_asm.c,v 1.8 1995/04/15 21:45:56 gibbs Exp $"; -#include <ctype.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> - -#define MEMORY 448 -#define MAXLINE 1024 -#define MAXTOKEN 32 -#define ADOTOUT "a.out" -#define NOVALUE -1 - -/* - * AIC-7770/AIC-7870 register definitions - */ -#define R_SINDEX 0x65 -#define R_ALLONES 0x69 -#define R_ALLZEROS 0x6a -#define R_NONE 0x6a - -int debug; -int lineno, LC; -char *filename; -FILE *ifp, *ofp; -unsigned char M[MEMORY][4]; - -void -error(char *s) -{ - fprintf(stderr, "%s: %s at line %d\n", filename, s, lineno); - exit(EXIT_FAILURE); -} - -void * -Malloc(size_t size) -{ - void *p = malloc(size); - if (!p) - error("out of memory"); - return(p); -} - -void * -Realloc(void *ptr, size_t size) -{ - void *p = realloc(ptr, size); - if (!p) - error("out of memory"); - return(p); -} - -char * -Strdup(char *s) -{ - char *p = (char *)Malloc(strlen(s) + 1); - strcpy(p, s); - return(p); -} - -typedef struct sym_t { - struct sym_t *next; /* MUST BE FIRST */ - char *name; - int value; - int npatch; - int *patch; -} sym_t; - -sym_t *head; - -void -define(char *name, int value) -{ - sym_t *p, *q; - - for (p = head, q = (sym_t *)&head; p; p = p->next) { - if (!strcmp(p->name, name)) - error("redefined symbol"); - q = p; - } - - p = q->next = (sym_t *)Malloc(sizeof(sym_t)); - p->next = NULL; - p->name = Strdup(name); - p->value = value; - p->npatch = 0; - p->patch = NULL; - - if (debug) { - fprintf(stderr, "\"%s\" ", p->name); - if (p->value != NOVALUE) - fprintf(stderr, "defined as 0x%x\n", p->value); - else - fprintf(stderr, "undefined\n"); - } -} - -sym_t * -lookup(char *name) -{ - sym_t *p; - - for (p = head; p; p = p->next) - if (!strcmp(p->name, name)) - return(p); - return(NULL); -} - -void -patch(sym_t *p, int location) -{ - p->npatch += 1; - p->patch = (int *)Realloc(p->patch, p->npatch * sizeof(int *)); - - p->patch[p->npatch - 1] = location; -} - -void backpatch(void) -{ - int i; - sym_t *p; - - for (p = head; p; p = p->next) { - - if (p->value == NOVALUE) { - fprintf(stderr, - "%s: undefined symbol \"%s\"\n", - filename, p->name); - exit(EXIT_FAILURE); - } - - if (p->npatch) { - if (debug) - fprintf(stderr, - "\"%s\" (0x%x) patched at", - p->name, p->value); - - for (i = 0; i < p->npatch; i++) { - M[p->patch[i]][0] &= ~1; - M[p->patch[i]][0] |= ((p->value >> 8) & 1); - M[p->patch[i]][1] = p->value & 0xff; - - if (debug) - fprintf(stderr, " 0x%x", p->patch[i]); - } - - if (debug) - fputc('\n', stderr); - } - } -} - -/* - * Output words in byte-reversed order (least significant first) - * since the sequencer RAM is loaded that way. - */ -void -output(FILE *fp) -{ - int i; - - for (i = 0; i < LC; i++) - fprintf(fp, "\t0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", - M[i][3], - M[i][2], - M[i][1], - M[i][0]); - printf("%d out of %d instructions used.\n", LC, MEMORY); -} - -char ** -getl(int *n) -{ - int i; - char *p, *quote; - static char buf[MAXLINE]; - static char *a[MAXTOKEN]; - - i = 0; - - while (fgets(buf, sizeof(buf), ifp)) { - - lineno += 1; - - if (buf[strlen(buf)-1] != '\n') - error("line too long"); - - p = strchr(buf, '#'); - if (p) - *p = '\0'; - p = buf; -rescan: - quote = strchr(p, '\"'); - if (quote) - *quote = '\0'; - for (p = strtok(p, ", \t\n"); p; p = strtok(NULL, ", \t\n")) - if (i < MAXTOKEN-1) - a[i++] = p; - else - error("too many tokens"); - if (quote) { - quote++; - p = strchr(quote, '\"'); - if (!p) - error("unterminated string constant"); - else if (i < MAXTOKEN-1) { - a[i++] = quote; - *p = '\0'; - p++; - } - else - error("too many tokens"); - goto rescan; - } - if (i) { - *n = i; - return(a); - } - } - return(NULL); -} - -#define A 0x8000 /* `A'ccumulator ok */ -#define I 0x4000 /* use as immediate value */ -#define SL 0x2000 /* shift left */ -#define SR 0x1000 /* shift right */ -#define RL 0x0800 /* rotate left */ -#define RR 0x0400 /* rotate right */ -#define LO 0x8000 /* lookup: ori-{jmp,jc,jnc,call} */ -#define LA 0x4000 /* lookup: and-{jz,jnz} */ -#define LX 0x2000 /* lookup: xor-{je,jne} */ -#define NA -1 /* not applicable */ - -struct { - char *name; - int n; /* number of operands, including opcode */ - unsigned int op; /* immediate or L?|pos_from_0 */ - unsigned int dest; /* NA, pos_from_0, or I|immediate */ - unsigned int src; /* NA, pos_from_0, or I|immediate */ - unsigned int imm; /* pos_from_0, A|pos_from_0, or I|immediate */ - unsigned int addr; /* NA or pos_from_0 */ - int fmt; /* instruction format - 1, 2, or 3 */ -} instr[] = { -/* - * N OP DEST SRC IMM ADDR FMT - */ - { "mov", 3, 1, 1, 2, I|0xff, NA, 1 }, - { "mov", 4, LO|2, NA, 1, I|0, 3, 3 }, - { "mvi", 3, 0, 1, I|R_ALLZEROS, A|2, NA, 1 }, - { "mvi", 4, LO|2, NA, I|R_ALLZEROS, 1, 3, 3 }, - { "not", 2, 2, 1, 1, I|0xff, NA, 1 }, - { "and", 3, 1, 1, 1, A|2, NA, 1 }, - { "and", 4, 1, 1, 3, A|2, NA, 1 }, - { "or", 3, 0, 1, 1, A|2, NA, 1 }, - { "or", 4, 0, 1, 3, A|2, NA, 1 }, - { "or", 5, LO|3, NA, 1, 2, 4, 3 }, - { "xor", 3, 2, 1, 1, A|2, NA, 1 }, - { "xor", 4, 2, 1, 3, A|2, NA, 1 }, - { "nop", 1, 1, I|R_NONE, I|R_ALLZEROS, I|0xff, NA, 1 }, - { "inc", 2, 3, 1, 1, I|1, NA, 1 }, - { "inc", 3, 3, 1, 2, I|1, NA, 1 }, - { "dec", 2, 3, 1, 1, I|0xff, NA, 1 }, - { "dec", 3, 3, 1, 2, I|0xff, NA, 1 }, - { "jmp", 2, LO|0, NA, I|R_SINDEX, I|0, 1, 3 }, - { "jc", 2, LO|0, NA, I|R_SINDEX, I|0, 1, 3 }, - { "jnc", 2, LO|0, NA, I|R_SINDEX, I|0, 1, 3 }, - { "call", 2, LO|0, NA, I|R_SINDEX, I|0, 1, 3 }, - { "test", 5, LA|3, NA, 1, A|2, 4, 3 }, - { "cmp", 5, LX|3, NA, 1, A|2, 4, 3 }, - { "ret", 1, 1, I|R_NONE, I|R_ALLZEROS, I|0xff, NA, 1 }, - { "ret", 1, 1, I|R_NONE, I|R_ALLZEROS, I|0xff, NA, 1 }, - { "clc", 1, 3, I|R_NONE, I|R_ALLZEROS, I|1, NA, 1 }, - { "clc", 4, 3, 2, I|R_ALLZEROS, A|3, NA, 1 }, - { "stc", 2, 3, 1, I|R_ALLONES, I|1, NA, 1 }, - { "add", 3, 3, 1, 1, A|2, NA, 1 }, - { "add", 4, 3, 1, 3, A|2, NA, 1 }, - { "adc", 3, 4, 1, 1, A|2, NA, 1 }, - { "adc", 4, 4, 1, 3, A|2, NA, 1 }, - { "shl", 3, 5, 1, 1, SL|2, NA, 2 }, - { "shl", 4, 5, 1, 2, SL|3, NA, 2 }, - { "shr", 3, 5, 1, 1, SR|2, NA, 2 }, - { "shr", 4, 5, 1, 2, SR|3, NA, 2 }, - { "rol", 3, 5, 1, 1, RL|2, NA, 2 }, - { "rol", 4, 5, 1, 2, RL|3, NA, 2 }, - { "ror", 3, 5, 1, 1, RR|2, NA, 2 }, - { "ror", 4, 5, 1, 2, RR|3, NA, 2 }, - /* - * Extensions (note also that mvi allows A) - */ - { "clr", 2, 1, 1, I|R_ALLZEROS, I|0xff, NA, 1 }, - { 0, 0, 0, 0, 0, 0, 0, 0 } -}; - -int -eval_operand(char **a, int spec) -{ - int i; - unsigned int want = spec & (LO|LA|LX); - - static struct { - unsigned int what; - char *name; - int value; - } jmptab[] = { - { LO, "jmp", 8 }, - { LO, "jc", 9 }, - { LO, "jnc", 10 }, - { LO, "call", 11 }, - { LA, "jz", 15 }, - { LA, "jnz", 13 }, - { LX, "je", 14 }, - { LX, "jne", 12 }, - }; - - spec &= ~(LO|LA|LX); - - for (i = 0; i < sizeof(jmptab)/sizeof(jmptab[0]); i++) - if (jmptab[i].what == want && - !strcmp(jmptab[i].name, a[spec])) - { - return(jmptab[i].value); - } - - if (want) - error("invalid jump"); - - return(spec); /* "case 0" - no flags set */ -} - -int -eval_sdi(char **a, int spec) -{ - sym_t *p; - unsigned val; - - if (spec == NA) - return(NA); - - switch (spec & (A|I|SL|SR|RL|RR)) { - case SL: - case SR: - case RL: - case RR: - if (isdigit(*a[spec &~ (SL|SR|RL|RR)])) - val = strtol(a[spec &~ (SL|SR|RL|RR)], NULL, 0); - else { - p = lookup(a[spec &~ (SL|SR|RL|RR)]); - if (!p) - error("undefined symbol used"); - val = p->value; - } - - switch (spec & (SL|SR|RL|RR)) { /* blech */ - case SL: - if (val > 7) - return(0xf0); - return(((val % 8) << 4) | - (val % 8)); - case SR: - if (val > 7) - return(0xf0); - return(((val % 8) << 4) | - (1 << 3) | - ((8 - (val % 8)) % 8)); - case RL: - return(val % 8); - case RR: - return((8 - (val % 8)) % 8); - } - case I: - return(spec &~ I); - case A: - /* - * An immediate field of zero selects - * the accumulator. Vigorously object - * if zero is given otherwise - it's - * most likely an error. - */ - spec &= ~A; - if (!strcmp("A", a[spec])) - return(0); - if (isdigit(*a[spec]) && - strtol(a[spec], NULL, 0) == 0) - { - error("immediate value of zero selects accumulator"); - } - /* falls through */ - case 0: - if (isdigit(*a[spec])) - return(strtol(a[spec], NULL, 0)); - p = lookup(a[spec]); - if (p) - return(p->value); - error("undefined symbol used"); - } - - return(NA); /* shut the compiler up */ -} - -int -eval_addr(char **a, int spec) -{ - sym_t *p; - - if (spec == NA) - return(NA); - if (isdigit(*a[spec])) - return(strtol(a[spec], NULL, 0)); - - p = lookup(a[spec]); - - if (p) { - if (p->value != NOVALUE) - return(p->value); - patch(p, LC); - } else { - define(a[spec], NOVALUE); - p = lookup(a[spec]); - patch(p, LC); - } - - return(NA); /* will be patched in later */ -} - -int -crack(char **a, int n) -{ - int i; - int I_imm, I_addr; - int I_op, I_dest, I_src, I_ret; - - /* - * Check for "ret" at the end of the line; remove - * it unless it's "ret" alone - we still want to - * look it up in the table. - */ - I_ret = (strcmp(a[n-1], "ret") ? 0 : !0); - if (I_ret && n > 1) - n -= 1; - - for (i = 0; instr[i].name; i++) { - /* - * Look for match in table given constraints, - * currently just the name and the number of - * operands. - */ - if (!strcmp(instr[i].name, *a) && instr[i].n == n) - break; - } - if (!instr[i].name) - error("unknown opcode or wrong number of operands"); - - I_op = eval_operand(a, instr[i].op); - I_src = eval_sdi(a, instr[i].src); - I_imm = eval_sdi(a, instr[i].imm); - I_dest = eval_sdi(a, instr[i].dest); - I_addr = eval_addr(a, instr[i].addr); - - if( LC >= MEMORY ) - error("Memory exhausted!\n"); - - switch (instr[i].fmt) { - case 1: - case 2: - M[LC][0] = (I_op << 1) | I_ret; - M[LC][1] = I_dest; - M[LC][2] = I_src; - M[LC][3] = I_imm; - break; - case 3: - if (I_ret) - error("illegal use of \"ret\""); - M[LC][0] = (I_op << 1) | ((I_addr >> 8) & 1); - M[LC][1] = I_addr & 0xff; - M[LC][2] = I_src; - M[LC][3] = I_imm; - break; - } - - return (1); /* no two-byte instructions yet */ -} - -#undef SL -#undef SR -#undef RL -#undef RR -#undef LX -#undef LA -#undef LO -#undef I -#undef A - -void -assemble(void) -{ - int n; - char **a; - sym_t *p; - - while ((a = getl(&n))) { - - while (a[0][strlen(*a)-1] == ':') { - a[0][strlen(*a)-1] = '\0'; - p = lookup(*a); - if (p) - p->value = LC; - else - define(*a, LC); - a += 1; - n -= 1; - } - - if (!n) /* line was all labels */ - continue; - - if (n == 3 && !strcmp("VERSION", *a)) - fprintf(ofp, "#define %s \"%s\"\n", a[1], a[2]); - else { - if (n == 3 && !strcmp("=", a[1])) - define(*a, strtol(a[2], NULL, 0)); - else - LC += crack(a, n); - } - } - - backpatch(); - output(ofp); - - if (debug) - output(stderr); -} - -int -main(int argc, char **argv) -{ - int c; - - while ((c = getopt(argc, argv, "dho:vD")) != EOF) { - switch (c) { - case 'd': - debug = !0; - break; - case 'D': - { - char *p; - if ((p = strchr(optarg, '=')) != NULL) { - *p = '\0'; - define(optarg, strtol(p + 1, NULL, 0)); - } - else - define(optarg, 1); - break; - } - case 'o': - ofp = fopen(optarg, "w"); - if (!ofp) { - perror(optarg); - exit(EXIT_FAILURE); - } - break; - case 'h': - printf("usage: %s [-d] [-Dname] [-ooutput] input\n", - *argv); - exit(EXIT_SUCCESS); - break; - case 'v': - printf("%s\n", id); - exit(EXIT_SUCCESS); - break; - default: - exit(EXIT_FAILURE); - break; - } - } - - if (argc - optind != 1) { - fprintf(stderr, "%s: must have one input file\n", *argv); - exit(EXIT_FAILURE); - } - filename = argv[optind]; - - ifp = fopen(filename, "r"); - if (!ifp) { - perror(filename); - exit(EXIT_FAILURE); - } - - if (!ofp) { - ofp = fopen(ADOTOUT, "w"); - if (!ofp) { - perror(ADOTOUT); - exit(EXIT_FAILURE); - } - } - - assemble(); - exit(EXIT_SUCCESS); -} diff --git a/sys/i386/isa/matcd/matcddrv.h b/sys/i386/isa/matcd/matcddrv.h new file mode 100644 index 000000000000..8802149d0803 --- /dev/null +++ b/sys/i386/isa/matcd/matcddrv.h @@ -0,0 +1,198 @@ +/*matcd.h--------------------------------------------------------------------- + + Matsushita(Panasonic) / Creative CD-ROM Driver (matcd) + Authored by Frank Durda IV + + Copyright 1994, 1995 Frank Durda IV. All rights reserved. + "FDIV" is a trademark of Frank Durda IV. + + + Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + 1. Redistributions of source code must retain the above copyright + notice positioned at the very beginning of this file without + modification, all copyright strings, all related programming + codes that display the copyright strings, this list of + conditions and the following disclaimer. + 2. Redistributions in binary form must contain all copyright strings + and related programming code that display the copyright strings. + 3. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 4. All advertising materials mentioning features or use of this + software must display the following acknowledgement: + "The Matsushita/Panasonic CD-ROM driver was developed + by Frank Durda IV for use with "FreeBSD" and similar + operating systems." + "Similar operating systems" includes mainly non-profit oriented + systems for research and education, including but not restricted + to "NetBSD", "386BSD", and "Mach" (by CMU). The wording of the + acknowledgement (in electronic form or printed text) may not be + changed without permission from the author. + 5. Absolutely no warranty of function, fitness or purpose is made + by the author Frank Durda IV. + 6. Neither the name of the author nor the name "FreeBSD" may + be used to endorse or promote products derived from this software + without specific prior written permission. + (The author can be reached at bsdmail@nemesis.lonestar.org) + 7. The product containing this software must meet all of these + conditions even if it is unsupported, not a complete system + and/or does not contain compiled code. + 8. These conditions will be in force for the full life of the + copyright. + 9. If all the above conditions are met, modifications to other + parts of this file may be freely made, although any person + or persons making changes do not receive the right to add their + name or names to the copyright strings and notices in this + software. Persons making changes are encouraged to insert edit + history in matcd.c and to put your name and details of the + change there. + 10. You must have prior written permission from the author to + deviate from these terms. + + Vendors who produce product(s) containing this code are encouraged + (but not required) to provide copies of the finished product(s) to + the author and to correspond with the author about development + activity relating to this code. Donations of development hardware + and/or software are also welcome. (This is one of the faster ways + to get a driver developed for a device.) + + THIS SOFTWARE IS PROVIDED BY THE DEVELOPER(S) ``AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER(S) BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-----No changes are allowed above this line------------------------------------ + +See matcd.c for Edit History information. + + + Matsushita CR562/CR563 Commands + This is not a complete list - just the ones this version uses +*/ + +#define NOP 0x05 /*No action - just return status*/ +#define DOOROPEN 0x06 /*Open tray*/ +#define DOORCLOSE 0x07 /*Close tray*/ +#define ABORT 0x08 /*Abort command*/ +#define MODESELECT 0x09 /*Set drive parameters*/ +#define LOCK 0x0c /*Prevent/Allow medium removal*/ +#define PAUSE 0x0d /*Pause/Resume playback*/ +#define PLAYBLOCKS 0x0e /*Play audio - block to block*/ +#define PLAYTRKS 0x0f /*Play audio - tracks & index*/ +#define READ 0x10 /*Read data*/ +#define READERROR 0x82 /*Read Error*/ +#define READID 0x83 /*Read Drive Type & Firmware Info*/ +#define MODESENSE 0x84 /*<12>Report drive settings*/ +#define READSUBQ 0x87 /*<14>Read Q channel information*/ +#define READDINFO 0x8b /*<13>Read TOC tracks & drive size*/ +#define READTOC 0x8c /*<13>Read entry from TOC*/ + +#define BLOCKPARAM 0x00 /*Used with MODESELECT command*/ +#define SPEEDPARM 0x03 /*<12>Adjust audio playback speed*/ +#define AUDIOPARM 0x05 /*<12>Set/read audio levels & routing*/ +#define RESUME 0x80 /*Used with PAUSE command*/ + +#define MAXCMDSIZ 12 /*Max command size with NULL*/ + +/* Possible data transfers for MODESELECT + BLOCKPARAM */ + +#define MODE_DATA 0x00 /*2048, 2340*/ +#define MODE_DA 0x82 /*2352*/ +#define MODE_USER 0x01 /*2048, 2052, 2336, 2340, 2352*/ +#define MODE_UNKNOWN 0xff /*Uninitialized state*/ + +/*<12>The following mode is not implemented in the driver at this time*/ + +#define MODE_XA 0x81 /*2048, 2060, 2324, 2336, 2340, 2352*/ + +#define DEFVOL 0xff /*<12>Default drive volume level, 100% + volume. Based on drive action.*/ +#define OUTLEFT 0x01 /*Output on Left*/ +#define OUTRIGHT 0x02 /*Output on Right*/ + +/* Matsushita CR562/CR563 Status bits*/ + +#define MATCD_ST_DOOROPEN 0x80 /*Door is open right now*/ +#define MATCD_ST_DSKIN 0x40 /*Disc in drive*/ +#define MATCD_ST_SPIN 0x20 /*Disc is spinning*/ +#define MATCD_ST_ERROR 0x10 /*Error on command*/ +#define MATCD_ST_AUDIOBSY 0x08 /*Drive is playing audio*/ +#define MATCD_ST_LOCK 0x04 /*<14>Drive is locked*/ +#define MATCD_ST_X2 0x02 /*<14>Media is at double-speed*/ +#define MATCD_ST_READY 0x01 /*<14>Drive is ready*/ + +#define MATCDAUDIOBSY MATCD_ST_AUDIOBSY +#define MATCDDSKCHNG MATCD_ST_DSKCHNG +#define MATCDDSKIN MATCD_ST_DSKIN +#define MATCDDOOROPEN MATCD_ST_DOOROPEN + + +/* Error codes returned from READERROR command.*/ + +#define NO_ERROR 0x00 +#define RECV_RETRY 0x01 +#define RECV_ECC 0x02 +#define NOT_READY 0x03 +#define TOC_ERROR 0x04 +#define UNRECV_ERROR 0x05 +#define SEEK_ERROR 0x06 +#define TRACK_ERROR 0x07 +#define RAM_ERROR 0x08 +#define DIAG_ERROR 0x09 +#define FOCUS_ERROR 0x0a +#define CLV_ERROR 0x0b +#define DATA_ERROR 0x0c +#define ADDRESS_ERROR 0x0d +#define CDB_ERROR 0x0e +#define END_ADDRESS 0x0f +#define MODE_ERROR 0x10 +#define MEDIA_CHANGED 0x11 +#define HARD_RESET 0x12 +#define ROM_ERROR 0x13 +#define CMD_ERROR 0x14 +#define DISC_OUT 0x15 +#define HARD_ERROR 0x16 +#define ILLEGAL_REQ 0x17 + + +/* Human-readable error messages - what a concept!*/ + +static unsigned char * matcderrors[]={"No error", /* 00 */ + "Soft read error after retry", /* 01 */ + "Soft read error after error-correction", /* 02 */ + "Not ready", /* 03 */ + "Unable to read TOC", /* 04 */ + "Hard read error of data track",/* 05 */ + "Seek did not complete", /* 06 */ + "Tracking servo failure", /* 07 */ + "Drive RAM failure", /* 08 */ + "Drive self-test failed", /* 09 */ + "Focusing servo failure", /* 0a */ + "Spindle servo failure", /* 0b */ + "Data path failure", /* 0c */ + "Illegal logical block address",/* 0d */ + "Illegal field in CDB", /* 0e */ + "End of user encountered on this track", /* 0f */ + "Illegal data mode for this track", /* 10 */ + "Media changed", /* 11 */ + "Power-on or drive reset occurred", /* 12 */ + "Drive ROM failure", /* 13 */ + "Illegal drive command received from host",/* 14 */ + "Disc removed during operation",/* 15 */ + "Drive Hardware error", /* 16 */ + "Illegal request from host"}; /* 17 */ + +/*End of matcd.h*/ + + diff --git a/usr.bin/at/LEGAL b/usr.bin/at/LEGAL deleted file mode 100644 index 92b1b4983110..000000000000 --- a/usr.bin/at/LEGAL +++ /dev/null @@ -1,29 +0,0 @@ ------BEGIN PGP SIGNED MESSAGE----- - -Sorry for the long wait, but there still were a few things to -be ironed out in at, which I've finally done :-) - -The FreeBSD team does have my permission to use at, version 2.9, -under the BSD license. - -You'll find it on sunsite.unc.edu's Incoming, hopefully; the -md5 checksum is - -3ba2ca3c0e87e1a04feae2c6c1376b0d at-2.9.tgz - -Best regards - Thomas -- -- -Thomas Koenig, Thomas.Koenig@ciw.uni-karlsruhe.de, ig25@dkauni2.bitnet. -The joy of engineering is to find a straight line on a double -logarithmic diagram. - ------BEGIN PGP SIGNATURE----- -Version: 2.6.2i - -iQCVAwUBMCjVrPBu+cbJcKCVAQFNiQP/dpWP57s/E8plVGUD3zfgOXDmKUvg8U7a -VwRzJrIMuSgnSJs0wkpvcomc3NLicipfX7hhWLh/xatPM2YbF7O5HZoNdvWvexD2 -1Y67zJ+0HFb1mPnSBOrS5RFiQAe3KqmGec6E14Rih/qNoFQZBVRFXZ4xxuwP+0Rs -e2U+TVTUz6A= -=TvyW ------END PGP SIGNATURE----- diff --git a/usr.bin/killall/Makefile b/usr.bin/killall/Makefile deleted file mode 100644 index 17cfc53c0e9a..000000000000 --- a/usr.bin/killall/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -MAN1= killall.1 - -beforeinstall: - ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \ - ${.CURDIR}/killall.pl ${DESTDIR}${BINDIR}/killall - -.include <bsd.prog.mk> diff --git a/usr.sbin/spkrtest/spkrtest.8 b/usr.sbin/spkrtest/spkrtest.8 deleted file mode 100644 index 056e0b4de28a..000000000000 --- a/usr.sbin/spkrtest/spkrtest.8 +++ /dev/null @@ -1,32 +0,0 @@ -.Dd May, 1995 -.Dt SPKRTEST 8 -.Os FreeBSD - -.Sh NAME -.Nm spkrtest -.Nd test script for the speaker driver - -.Sh DESCRIPTION -.Nm -is an easy to use test script for the speaker driver. - -.Sh FILES -.Bl -tag -width /dev/speakerxx -.It Pa /dev/speaker -speaker device file -.El - -.Sh SEE ALSO -.Xr spkr 4 , -.Xr dialog 1 , -.Xr perl 1 - -.\" only for the record -.\" .Sh AUTHOR -.\" Eric S. Raymond <esr@snark.thyrsus.com) June 1990; -.\" dialog+perl by Wolfram Schneider <wosch@cs.tu-berlin.de>, May 1995 - -.Sh HISTORY -The -.Nm -script appeared in FreeBSD 1.0 diff --git a/usr.sbin/spkrtest/spkrtest.pl b/usr.sbin/spkrtest/spkrtest.pl deleted file mode 100644 index d0fe260924ad..000000000000 --- a/usr.sbin/spkrtest/spkrtest.pl +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/perl -# -# Test script for the speaker driver -# -# v1.0 by Eric S. Raymond (Feb 1990) -# v1.1 rightstuff contributed by Eric S. Tiedemann (est@snark.thyrsus.com) -# v2.0 dialog+perl by Wolfram Schneider <wosch@cs.tu-berlin.de>, May 1995 -# -# NOTE for iso-* (latin1) fonts: use TERM=cons25-iso8859-1 -# - -$title = " -reveille -- Reveille -contact -- Contact theme from Close Encounters -dance -- Lord of the Dance (aka Simple Gifts) -loony -- Loony Toons theme -sinister -- standard villain's entrance music -rightstuff -- a trope from \"The Right Stuff\" score by Bill Conti -toccata -- opening bars of Bach's Toccata and Fugue in D Minor -startrek -- opening bars of the theme from Star Trek Classic -"; - -$music = " -reveille -- t255l8c.f.afc~c.f.afc~c.f.afc.f.a..f.~c.f.afc~c.f.afc~c.f.afc~c.f.. -contact -- <cd<a#~<a#>f -dance -- t240<cfcfgagaa#b#>dc<a#a.~fg.gaa#.agagegc.~cfcfgagaa#b#>dc<a#a.~fg.gga.agfgfgf. -loony -- t255cf8f8edc<a>~cf8f8edd#e~ce8cdce8cd.<a>c8c8c#def8af8 -sinister -- mst200o2ola.l8bc.~a.~>l2d# -rightstuff -- olcega.a8f>cd2bgc.c8dee2 -toccata -- msl16oldcd4mll8pcb-agf+4.g4p4<msl16dcd4mll8pa.a+f+4p16g4 -startrek -- l2b.f+.p16a.c+.p l4mn<b.>e8a2mspg+e8c+f+8b2 -"; - -$checklist = 'dialog \ ---title "Speaker test" \ ---checklist "Please select the melodies you wish to play (space for select)" \ --1 -1 10 \ -'; - - -sub Exit { - unlink $tmp if $tmp; -} - -$SIG{'INT'} = $SIG{'HUP'} = $SIG{'TRAP'} = $SIG{'QUIT'} = - $SIG{'TERM'} = '&Exit'; - - -# make assoc array from variable 'var' -# 'name -- description' -> $var{$name} = $description -sub splitconfig { - local(*var) = @_; - local($t, $name, $description); - - foreach $t (split('\n', $var)) { - ($name, $description) = split('--', $t); - - $name =~ s/^\s+//; $name =~ s/\s+$//; - $description =~ s/\s+//; $description =~ s/\s+$//; - - $var{$name} = $description if $name && $description; - } -} - -&splitconfig(*title); -&splitconfig(*music); - -foreach $e (sort keys %title) { - ($t = $title{$e}) =~ s/(\")/\\$1/g; # quote '"' - $checklist .= "\"$e\" \"$t\" OFF "; -} - -$tmp = ($ENV{'TMP'} || "/tmp") . "/_spkrtest$$"; -system("$checklist 2> $tmp"); # start dialog - -if (!$?) { # not cancel - open(SPEAKER, ">/dev/speaker") || die "/dev/speaker: $!\n"; - select(SPEAKER); $| = 1; - select(STDOUT); $| = 1; - - if (! -z $tmp) { # select melod(y/ies) - foreach $melody (split($", `cat $tmp`)) { - $melody =~ s/^"//; $melody =~ s/"$//; - print STDOUT "$title{$melody}\n"; - print SPEAKER "$music{$melody}"; - sleep 1; - } - } else { # use default melody - $melody = (sort keys %title)[0]; - print STDOUT "Use default melody: $title{$melody}\n"; - print SPEAKER "$music{$melody}"; - } - close SPEAKER; -} - -unlink $tmp; |