1995-05-17 15:40:00 +01:00
/*
* The new sysinstall program .
*
* This is probably the last attempt in the ` sysinstall ' line , the next
* generation being slated to essentially a complete rewrite .
*
1995-05-26 21:31:02 +01:00
* $ Id : media_strategy . c , v 1.27 1995 / 05 / 26 19 : 28 : 02 jkh Exp $
1995-05-17 15:40:00 +01:00
*
* Copyright ( c ) 1995
* Jordan Hubbard . All rights reserved .
1995-05-22 15:10:25 +01:00
* Copyright ( c ) 1995
* Gary J Palmer . All rights reserved .
1995-05-17 15:40:00 +01:00
*
* 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 "sysinstall.h"
1995-05-20 04:49:10 +01:00
# include <ctype.h>
# include <sys/stat.h>
# include <sys/errno.h>
# include <sys/file.h>
# include <sys/types.h>
# include <sys/wait.h>
# include <sys/param.h>
# include <sys/dkbad.h>
1995-05-20 19:38:39 +01:00
# include <sys/mman.h>
1995-05-24 02:27:15 +01:00
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
1995-05-23 03:41:18 +01:00
# include <netdb.h>
1995-05-23 19:06:16 +01:00
# include "ftp.h"
1995-05-20 04:49:10 +01:00
# define MSDOSFS
# define CD9660
# define NFS
# include <sys/mount.h>
# undef MSDOSFS
# undef CD9660
# undef NFS
1995-05-24 10:00:58 +01:00
# define MAX_ATTRIBS 200
1995-05-20 19:38:39 +01:00
# define MAX_NAME 511
# define MAX_VALUE 4095
struct attribs {
char * name ;
char * value ;
} ;
static int lno ;
static int num_attribs ;
static int
attr_parse ( struct attribs * * attr , char * file )
{
char hold_n [ MAX_NAME + 1 ] ;
char hold_v [ MAX_VALUE + 1 ] ;
int n , v , ch = 0 ;
enum { LOOK , COMMENT , NAME , VALUE , COMMIT } state ;
FILE * fp ;
num_attribs = n = v = lno = 0 ;
state = LOOK ;
if ( ( fp = fopen ( file , " r " ) ) = = NULL )
{
1995-05-21 16:40:54 +01:00
msgConfirm ( " Cannot open the information file `%s': %s (%d) " , file , strerror ( errno ) , errno ) ;
1995-05-20 19:38:39 +01:00
return 0 ;
}
while ( state = = COMMIT | | ( ch = fgetc ( fp ) ) ! = EOF ) {
/* Count lines */
if ( ch = = ' \n ' )
+ + lno ;
switch ( state ) {
case LOOK :
if ( isspace ( ch ) )
continue ;
/* Allow shell or lisp style comments */
else if ( ch = = ' # ' | | ch = = ' ; ' ) {
state = COMMENT ;
continue ;
}
else if ( isalpha ( ch ) ) {
hold_n [ n + + ] = ch ;
state = NAME ;
}
1995-05-21 16:40:54 +01:00
else
msgFatal ( " Invalid character '%c' at line %d \n " , ch , lno ) ;
1995-05-20 19:38:39 +01:00
break ;
case COMMENT :
if ( ch = = ' \n ' )
state = LOOK ;
break ;
case NAME :
if ( ch = = ' \n ' ) {
hold_n [ n ] = ' \0 ' ;
hold_v [ v = 0 ] = ' \0 ' ;
state = COMMIT ;
}
else if ( isspace ( ch ) )
continue ;
else if ( ch = = ' = ' ) {
hold_n [ n ] = ' \0 ' ;
state = VALUE ;
}
else
hold_n [ n + + ] = ch ;
break ;
case VALUE :
if ( v = = 0 & & isspace ( ch ) )
continue ;
else if ( ch = = ' { ' ) {
/* multiline value */
while ( ( ch = fgetc ( fp ) ) ! = ' } ' ) {
1995-05-21 16:40:54 +01:00
if ( ch = = EOF )
msgFatal ( " Unexpected EOF on line %d " , lno ) ;
1995-05-20 19:38:39 +01:00
else {
1995-05-21 16:40:54 +01:00
if ( v = = MAX_VALUE )
msgFatal ( " Value length overflow at line %d " , lno ) ;
1995-05-20 19:38:39 +01:00
hold_v [ v + + ] = ch ;
}
}
hold_v [ v ] = ' \0 ' ;
state = COMMIT ;
}
else if ( ch = = ' \n ' ) {
hold_v [ v ] = ' \0 ' ;
state = COMMIT ;
}
else {
1995-05-21 16:40:54 +01:00
if ( v = = MAX_VALUE )
msgFatal ( " Value length overflow at line %d " , lno ) ;
1995-05-20 19:38:39 +01:00
else
hold_v [ v + + ] = ch ;
}
break ;
case COMMIT :
1995-05-22 15:10:25 +01:00
( * attr ) [ num_attribs ] . name = strdup ( hold_n ) ;
( * attr ) [ num_attribs + + ] . value = strdup ( hold_v ) ;
1995-05-20 19:38:39 +01:00
state = LOOK ;
v = n = 0 ;
break ;
default :
1995-05-21 16:40:54 +01:00
msgFatal ( " Unknown state at line %d?? \n " , lno ) ;
1995-05-20 19:38:39 +01:00
}
}
1995-05-23 03:41:18 +01:00
fclose ( fp ) ;
1995-05-20 19:38:39 +01:00
return 1 ;
}
static const char *
attr_match ( struct attribs * attr , char * name )
1995-05-20 04:49:10 +01:00
{
1995-05-20 19:38:39 +01:00
int n = 0 ;
1995-05-24 10:00:58 +01:00
while ( ( strcasecmp ( attr [ n ] . name , name ) ! = 0 ) & & ( n < num_attribs ) & & ( n < 20 ) )
1995-05-20 19:38:39 +01:00
n + + ;
1995-05-24 10:00:58 +01:00
if ( strcasecmp ( attr [ n ] . name , name ) = = 0 )
1995-05-20 19:38:39 +01:00
return ( ( const char * ) attr [ n ] . value ) ;
1995-05-22 15:10:25 +01:00
1995-05-20 19:38:39 +01:00
return NULL ;
}
1995-05-24 19:21:49 +01:00
static pid_t getDistpid = 0 ;
1995-05-26 09:41:52 +01:00
static Device * floppyDev ;
1995-05-24 19:21:49 +01:00
1995-05-20 19:38:39 +01:00
static int
1995-05-26 09:41:52 +01:00
floppyChoiceHook ( char * str )
{
Device * * devs ;
/* Clip garbage off the ends */
string_prune ( str ) ;
str = string_skipwhite ( str ) ;
if ( ! * str )
return 0 ;
devs = deviceFind ( str , DEVICE_TYPE_FLOPPY ) ;
if ( devs )
floppyDev = devs [ 0 ] ;
return devs ? 1 : 0 ;
}
int
genericGetDist ( char * path , void * attrs , Boolean prompt )
1995-05-20 19:38:39 +01:00
{
int fd ;
char buf [ 512 ] ;
struct stat sb ;
1995-05-24 19:21:49 +01:00
int pfd [ 2 ] , numchunks ;
1995-05-22 15:10:25 +01:00
const char * tmp ;
1995-05-26 09:41:52 +01:00
Device * devp ;
struct attribs * dist_attrib = ( struct attribs * ) attrs ;
1995-05-20 19:38:39 +01:00
1995-05-26 11:20:47 +01:00
top :
fd = - 1 ;
1995-05-26 09:41:52 +01:00
/* Floppy is always last-ditch device */
1995-05-26 11:20:47 +01:00
while ( ! mediaDevice & & ( prompt & & floppyDev = = NULL ) ) {
1995-05-26 09:41:52 +01:00
Device * * devs ;
int cnt ;
devs = deviceFind ( NULL , DEVICE_TYPE_FLOPPY ) ;
cnt = deviceCount ( devs ) ;
if ( cnt = = 1 )
devp = devs [ 0 ] ;
else if ( cnt > 1 ) {
DMenu * menu ;
menu = deviceCreateMenu ( & MenuMediaFloppy , DEVICE_TYPE_FLOPPY , floppyChoiceHook ) ;
menu - > title = " Please insert the ROOT floppy " ;
dmenuOpenSimple ( menu ) ;
}
else {
msgConfirm ( " No floppy devices found! Something is seriously wrong! " ) ;
return - 1 ;
}
if ( ! floppyDev )
continue ;
fd = open ( floppyDev - > devname , O_RDONLY ) ;
1995-05-26 11:20:47 +01:00
if ( fd ! = - 1 )
return fd ;
else
floppyDev = NULL ;
1995-05-26 09:41:52 +01:00
}
if ( stat ( path , & sb ) = = 0 )
{
fd = open ( path , O_RDONLY , 0 ) ;
return ( fd ) ;
}
1995-05-20 19:38:39 +01:00
1995-05-26 09:41:52 +01:00
snprintf ( buf , 512 , " %s.tgz " , path ) ;
1995-05-20 19:38:39 +01:00
if ( stat ( buf , & sb ) = = 0 )
{
fd = open ( buf , O_RDONLY , 0 ) ;
return ( fd ) ;
}
snprintf ( buf , 512 , " %s.aa " , path ) ;
1995-05-26 11:20:47 +01:00
if ( stat ( buf , & sb ) ! = 0 & & ! prompt )
1995-05-20 19:38:39 +01:00
{
msgConfirm ( " Cannot find file(s) for distribution in ``%s''! \n " , path ) ;
1995-05-22 15:10:25 +01:00
return - 1 ;
1995-05-20 19:38:39 +01:00
}
1995-05-26 11:20:47 +01:00
if ( fd = = - 1 & & prompt ) {
if ( mediaDevice - > shutdown )
( * mediaDevice - > shutdown ) ( mediaDevice ) ;
if ( mediaDevice - > init )
if ( ! ( * mediaDevice - > init ) ( mediaDevice ) )
return - 1 ;
msgConfirm ( " Please put distribution files for %s \n in %s and press return " , path , mediaDevice - > description ) ;
goto top ;
}
1995-05-26 09:41:52 +01:00
if ( dist_attrib ) {
tmp = attr_match ( dist_attrib , " pieces " ) ;
numchunks = atoi ( tmp ) ;
}
else
numchunks = 1 ;
1995-05-24 19:21:49 +01:00
/* reap the previous child corpse - yuck! */
if ( getDistpid ) {
int i , j ;
i = waitpid ( getDistpid , & j , 0 ) ;
if ( i < 0 | | WEXITSTATUS ( j ) ) {
msgNotify ( " Warning: Previous extraction returned status code %d. " , WEXITSTATUS ( j ) ) ;
getDistpid = 0 ;
return - 1 ;
}
getDistpid = 0 ;
}
1995-05-24 23:37:44 +01:00
1995-05-26 09:41:52 +01:00
msgDebug ( " Attempting to concatenate %u chunks \n " , numchunks ) ;
1995-05-20 19:38:39 +01:00
pipe ( pfd ) ;
1995-05-24 19:21:49 +01:00
getDistpid = fork ( ) ;
if ( ! getDistpid ) {
1995-05-20 19:38:39 +01:00
caddr_t memory ;
1995-05-24 19:21:49 +01:00
int chunk ;
1995-05-22 15:10:25 +01:00
int retval ;
1995-05-20 19:38:39 +01:00
dup2 ( pfd [ 1 ] , 1 ) ; close ( pfd [ 1 ] ) ;
close ( pfd [ 0 ] ) ;
1995-05-25 19:48:33 +01:00
1995-05-24 19:21:49 +01:00
for ( chunk = 0 ; chunk < numchunks ; chunk + + ) {
1995-05-25 19:48:33 +01:00
int fd ;
unsigned long len , val ;
retval = stat ( buf , & sb ) ;
if ( ( retval ! = 0 ) & & ( prompt ! = TRUE ) )
{
msgConfirm ( " Cannot find file(s) for distribution in ``%s''! \n " , path ) ;
return - 1 ;
} else {
char * tmp = index ( buf , ' / ' ) ;
tmp + + ;
while ( retval ! = 0 )
{
msgConfirm ( " Please insert the disk with the `%s' file on it \n " , tmp ) ;
retval = stat ( buf , & sb ) ;
}
}
1995-05-22 15:10:25 +01:00
snprintf ( buf , 512 , " %s.%c%c " , path , ( chunk / 26 ) + ' a ' , ( chunk % 26 ) + ' a ' ) ;
if ( ( fd = open ( buf , O_RDONLY ) ) = = - 1 )
1995-05-24 19:21:49 +01:00
msgFatal ( " Cannot find file `%s'! " , buf ) ;
1995-05-25 19:48:33 +01:00
if ( prompt = = TRUE )
{
1995-05-26 09:41:52 +01:00
extern int crc ( int , unsigned long * , unsigned long * ) ;
1995-05-25 19:48:33 +01:00
crc ( fd , & val , & len ) ;
msgDebug ( " crc for %s is %lu %lu \n " , buf , val , len ) ;
}
1995-05-20 19:38:39 +01:00
fstat ( fd , & sb ) ;
1995-05-21 21:41:28 +01:00
msgDebug ( " mmap()ing %s (%d) \n " , buf , fd ) ;
1995-05-20 19:38:39 +01:00
memory = mmap ( 0 , sb . st_size , PROT_READ , MAP_SHARED , fd , ( off_t ) 0 ) ;
if ( memory = = ( caddr_t ) - 1 )
msgFatal ( " mmap error: %s \n " , strerror ( errno ) ) ;
1995-05-25 19:48:33 +01:00
retval = write ( 1 , memory , sb . st_size ) ;
1995-05-22 15:10:25 +01:00
if ( retval ! = sb . st_size )
{
1995-05-24 23:37:44 +01:00
msgConfirm ( " write didn't write out the complete file! \n (wrote %d bytes of %d bytes) " , retval ,
sb . st_size ) ;
1995-05-22 15:10:25 +01:00
exit ( 1 ) ;
}
1995-05-25 19:48:33 +01:00
1995-05-22 15:10:25 +01:00
retval = munmap ( memory , sb . st_size ) ;
if ( retval ! = 0 )
{
1995-05-24 19:21:49 +01:00
msgConfirm ( " munmap() returned %d " , retval ) ;
1995-05-22 15:10:25 +01:00
exit ( 1 ) ;
}
1995-05-21 18:56:13 +01:00
close ( fd ) ;
1995-05-20 19:38:39 +01:00
}
1995-05-22 15:10:25 +01:00
close ( 1 ) ;
msgDebug ( " Extract of %s finished!!! \n " , path ) ;
exit ( 0 ) ;
1995-05-20 19:38:39 +01:00
}
close ( pfd [ 1 ] ) ;
return ( pfd [ 0 ] ) ;
1995-05-20 04:49:10 +01:00
}
1995-05-17 15:40:00 +01:00
/* Various media "strategy" routines */
1995-05-22 15:10:25 +01:00
static Boolean cdromMounted ;
1995-05-17 15:40:00 +01:00
Boolean
mediaInitCDROM ( Device * dev )
{
1995-05-20 04:49:10 +01:00
struct iso_args args ;
struct stat sb ;
1995-05-22 15:10:25 +01:00
if ( cdromMounted )
return TRUE ;
if ( Mkdir ( " /cdrom " , NULL ) )
1995-05-20 04:49:10 +01:00
return FALSE ;
args . fspec = dev - > devname ;
1995-05-21 20:22:43 +01:00
args . flags = 0 ;
1995-05-22 15:10:25 +01:00
if ( mount ( MOUNT_CD9660 , " /cdrom " , MNT_RDONLY , ( caddr_t ) & args ) = = - 1 )
1995-05-20 04:49:10 +01:00
{
1995-05-26 09:41:52 +01:00
msgConfirm ( " Error mounting %s on /cdrom: %s (%u) \n " , dev , strerror ( errno ) , errno ) ;
1995-05-20 04:49:10 +01:00
return FALSE ;
}
/* Do a very simple check to see if this looks roughly like a 2.0.5 CDROM
Unfortunately FreeBSD won ' t let us read the ` ` label ' ' AFAIK , which is one
sure way of telling the disc version : - ( */
1995-05-22 15:10:25 +01:00
if ( stat ( " /cdrom/dists " , & sb ) )
1995-05-20 04:49:10 +01:00
{
if ( errno = = ENOENT )
{
1995-05-26 09:41:52 +01:00
msgConfirm ( " Couldn't locate the directory `dists' on the CD. \n Is this a 2.0.5 CDROM? \n " ) ;
1995-05-20 04:49:10 +01:00
return FALSE ;
} else {
1995-05-22 15:10:25 +01:00
msgConfirm ( " Couldn't stat directory %s: %s " , " /cdrom/dists " , strerror ( errno ) ) ;
1995-05-20 04:49:10 +01:00
return FALSE ;
}
}
1995-05-22 15:10:25 +01:00
cdromMounted = TRUE ;
1995-05-17 15:40:00 +01:00
return TRUE ;
}
1995-05-23 03:41:18 +01:00
int
1995-05-26 09:41:52 +01:00
mediaGetCDROM ( char * dist , char * path )
1995-05-17 15:40:00 +01:00
{
1995-05-20 19:38:39 +01:00
char buf [ PATH_MAX ] ;
struct attribs * dist_attr ;
1995-05-21 20:22:43 +01:00
int retval ;
1995-05-20 19:38:39 +01:00
dist_attr = safe_malloc ( sizeof ( struct attribs ) * MAX_ATTRIBS ) ;
1995-05-21 20:29:17 +01:00
snprintf ( buf , PATH_MAX , " /stand/info/%s.inf " , dist ) ;
1995-05-22 15:10:25 +01:00
1995-05-26 09:41:52 +01:00
if ( ! access ( buf , R_OK ) & & attr_parse ( & dist_attr , buf ) = = 0 )
1995-05-20 19:38:39 +01:00
{
1995-05-24 18:49:20 +01:00
msgConfirm ( " Cannot load information file for %s distribution! \n Please verify that your media is valid and try again. " , dist ) ;
1995-05-26 09:41:52 +01:00
free ( dist_attr ) ;
1995-05-20 19:38:39 +01:00
return FALSE ;
}
1995-05-26 09:41:52 +01:00
snprintf ( buf , PATH_MAX , " /cdrom/%s%s " , path ? path : " " , dist ) ;
1995-05-20 19:38:39 +01:00
1995-05-24 23:37:44 +01:00
retval = genericGetDist ( buf , dist_attr , FALSE ) ;
1995-05-21 20:22:43 +01:00
free ( dist_attr ) ;
return retval ;
1995-05-17 15:40:00 +01:00
}
void
1995-05-24 10:00:58 +01:00
mediaShutdownCDROM ( Device * dev )
1995-05-17 15:40:00 +01:00
{
1995-05-26 11:20:47 +01:00
1995-05-24 10:00:58 +01:00
msgDebug ( " In mediaShutdownCDROM \n " ) ;
1995-05-24 19:21:49 +01:00
if ( getDistpid ) {
int i , j ;
i = waitpid ( getDistpid , & j , 0 ) ;
if ( i < 0 | | WEXITSTATUS ( j ) ) {
msgConfirm ( " Warning: Last extraction returned status code %d. " , WEXITSTATUS ( j ) ) ;
getDistpid = 0 ;
}
getDistpid = 0 ;
}
1995-05-22 15:10:25 +01:00
if ( unmount ( " /cdrom " , 0 ) ! = 0 )
1995-05-20 19:38:39 +01:00
msgConfirm ( " Could not unmount the CDROM: %s \n " , strerror ( errno ) ) ;
1995-05-23 03:41:18 +01:00
msgDebug ( " Unmount returned \n " ) ;
1995-05-22 15:10:25 +01:00
cdromMounted = FALSE ;
1995-05-17 15:40:00 +01:00
return ;
}
1995-05-26 11:20:47 +01:00
static Boolean floppyMounted ;
1995-05-17 15:40:00 +01:00
Boolean
mediaInitFloppy ( Device * dev )
{
1995-05-26 11:20:47 +01:00
struct ufs_args ufsargs ;
char mountpoint [ FILENAME_MAX ] ;
1995-05-21 20:22:43 +01:00
1995-05-26 11:20:47 +01:00
if ( floppyMounted )
return TRUE ;
memset ( & ufsargs , 0 , sizeof ufsargs ) ;
if ( Mkdir ( " /mnt " , NULL ) ) {
msgConfirm ( " Unable to make directory mountpoint for %s! " , mountpoint ) ;
return FALSE ;
}
msgDebug ( " initFloppy: mount floppy %s on /mnt \n " , dev - > devname ) ;
ufsargs . fspec = dev - > devname ;
if ( mount ( MOUNT_MSDOS , " /mnt " , 0 , ( caddr_t ) & ufsargs ) = = - 1 ) {
msgConfirm ( " Error mounting floppy %s (%s) on /mnt : %s \n " , dev - > name ,
dev - > devname , mountpoint , strerror ( errno ) ) ;
return FALSE ;
}
floppyMounted = TRUE ;
1995-05-17 15:40:00 +01:00
return TRUE ;
}
1995-05-23 03:41:18 +01:00
int
1995-05-26 09:41:52 +01:00
mediaGetFloppy ( char * dist , char * path )
1995-05-17 15:40:00 +01:00
{
1995-05-21 20:22:43 +01:00
char buf [ PATH_MAX ] ;
1995-05-25 19:48:33 +01:00
char * fname ;
1995-05-21 20:22:43 +01:00
struct attribs * dist_attr ;
int retval ;
dist_attr = safe_malloc ( sizeof ( struct attribs ) * MAX_ATTRIBS ) ;
1995-05-21 20:29:17 +01:00
snprintf ( buf , PATH_MAX , " /stand/info/%s.inf " , dist ) ;
1995-05-26 09:41:52 +01:00
if ( ! access ( buf , R_OK ) & & attr_parse ( & dist_attr , buf ) = = 0 )
1995-05-21 20:22:43 +01:00
{
1995-05-24 18:49:20 +01:00
msgConfirm ( " Cannot load information file for %s distribution! \n Please verify that your media is valid and try again. " , dist ) ;
1995-05-26 09:41:52 +01:00
free ( dist_attr ) ;
1995-05-21 20:22:43 +01:00
return FALSE ;
}
1995-05-25 19:48:33 +01:00
fname = index ( dist , ' / ' ) + 1 ;
snprintf ( buf , PATH_MAX , " /mnt/%s " , fname ) ;
1995-05-21 20:22:43 +01:00
1995-05-24 23:37:44 +01:00
retval = genericGetDist ( buf , dist_attr , TRUE ) ;
1995-05-21 20:22:43 +01:00
free ( dist_attr ) ;
return retval ;
1995-05-17 15:40:00 +01:00
}
void
1995-05-24 10:00:58 +01:00
mediaShutdownFloppy ( Device * dev )
1995-05-17 15:40:00 +01:00
{
1995-05-26 11:20:47 +01:00
if ( floppyMounted ) {
if ( vsystem ( " umount /mnt " ) ! = 0 )
msgDebug ( " Umount of floppy on /mnt failed: %s (%d) \n " , strerror ( errno ) , errno ) ;
else
floppyMounted = FALSE ;
}
1995-05-17 15:40:00 +01:00
}
1995-05-20 11:33:14 +01:00
Boolean
1995-05-20 19:38:39 +01:00
mediaInitTape ( Device * dev )
1995-05-20 11:33:14 +01:00
{
return TRUE ;
}
1995-05-24 18:49:20 +01:00
static Boolean networkInitialized ;
1995-05-21 16:40:54 +01:00
Boolean
mediaInitNetwork ( Device * dev )
{
1995-05-23 19:06:16 +01:00
int i ;
1995-05-24 02:27:15 +01:00
char * rp ;
1995-05-23 19:06:16 +01:00
1995-05-24 18:49:20 +01:00
if ( networkInitialized )
return TRUE ;
1995-05-24 10:00:58 +01:00
configResolv ( ) ;
1995-05-23 19:06:16 +01:00
if ( ! strncmp ( " cuaa " , dev - > name , 4 ) ) {
1995-05-26 20:28:06 +01:00
if ( ! tcpStartPPP ( dev ) ) {
1995-05-23 19:06:16 +01:00
msgConfirm ( " Unable to start PPP! This installation method \n cannot be used. " ) ;
return FALSE ;
}
}
else {
char * cp , ifconfig [ 64 ] ;
1995-05-24 02:27:15 +01:00
snprintf ( ifconfig , 64 , " %s%s " , VAR_IFCONFIG , dev - > name ) ;
1995-05-23 19:06:16 +01:00
cp = getenv ( ifconfig ) ;
if ( ! cp ) {
msgConfirm ( " The %s device is not configured. You will need to do so \n in the Networking configuration menu before proceeding. " ) ;
return FALSE ;
}
1995-05-24 02:27:15 +01:00
i = vsystem ( " ifconfig %s %s " , dev - > name , cp ) ;
1995-05-23 19:06:16 +01:00
if ( i ) {
1995-05-24 02:27:15 +01:00
msgConfirm ( " Unable to configure the %s interface! \n This installation method cannot be used. " , dev - > name ) ;
1995-05-23 19:06:16 +01:00
return FALSE ;
}
}
1995-05-24 02:27:15 +01:00
rp = getenv ( VAR_GATEWAY ) ;
if ( ! rp )
1995-05-24 10:00:58 +01:00
msgConfirm ( " No gateway has been set. You will not be able to access hosts \n
1995-05-24 02:27:15 +01:00
not on the local network \ n " );
else
vsystem ( " route add default %s " , rp ) ;
1995-05-24 18:49:20 +01:00
networkInitialized = TRUE ;
1995-05-21 16:40:54 +01:00
return TRUE ;
}
1995-05-23 03:41:18 +01:00
int
1995-05-26 09:41:52 +01:00
mediaGetTape ( char * dist , char * path )
1995-05-20 11:33:14 +01:00
{
1995-05-23 03:41:18 +01:00
return - 1 ;
1995-05-20 11:33:14 +01:00
}
void
1995-05-24 10:00:58 +01:00
mediaShutdownTape ( Device * dev )
1995-05-20 11:33:14 +01:00
{
return ;
}
1995-05-21 16:40:54 +01:00
void
1995-05-24 10:00:58 +01:00
mediaShutdownNetwork ( Device * dev )
1995-05-21 16:40:54 +01:00
{
1995-05-24 18:49:20 +01:00
char * cp ;
if ( ! networkInitialized )
return ;
if ( ! strncmp ( " cuaa " , dev - > name , 4 ) ) {
msgConfirm ( " You may now go to the 3rd screen (ALT-F3) and shut down \n your PPP connection. It shouldn't be needed any longer \n (unless you wish to create a shell by typing ESC and \n experiment with it further, in which case go right ahead!) " ) ;
return ;
}
else {
int i ;
char ifconfig [ 64 ] ;
snprintf ( ifconfig , 64 , " %s%s " , VAR_IFCONFIG , dev - > name ) ;
cp = getenv ( ifconfig ) ;
if ( ! cp )
return ;
i = vsystem ( " ifconfig %s down " , dev - > name ) ;
if ( i )
msgConfirm ( " Warning: Unable to down the %s interface properly " , dev - > name ) ;
}
cp = getenv ( VAR_GATEWAY ) ;
if ( cp )
vsystem ( " route delete default " ) ;
networkInitialized = FALSE ;
1995-05-21 16:40:54 +01:00
}
1995-05-23 03:41:18 +01:00
static FTP_t ftp ;
1995-05-17 15:40:00 +01:00
Boolean
1995-05-21 16:40:54 +01:00
mediaInitFTP ( Device * dev )
1995-05-17 15:40:00 +01:00
{
1995-05-23 03:41:18 +01:00
int i ;
1995-05-24 10:00:58 +01:00
char * url , * hostname , * dir ;
1995-05-23 03:41:18 +01:00
char * my_name , email [ BUFSIZ ] ;
1995-05-24 02:27:15 +01:00
Device * netDevice = ( Device * ) dev - > private ;
if ( netDevice - > init )
1995-05-26 09:41:52 +01:00
if ( ! ( * netDevice - > init ) ( netDevice ) )
return FALSE ;
1995-05-23 03:41:18 +01:00
if ( ( ftp = FtpInit ( ) ) = = NULL ) {
msgConfirm ( " FTP initialisation failed! " ) ;
return FALSE ;
}
url = getenv ( " ftp " ) ;
if ( ! url )
return FALSE ;
my_name = getenv ( VAR_HOSTNAME ) ;
if ( strncmp ( " ftp:// " , url , 6 ) ! = NULL ) {
msgConfirm ( " Invalid URL (`%s') passed to FTP routines! \n (must start with `ftp://') " , url ) ;
return FALSE ;
}
1995-05-24 02:27:15 +01:00
msgDebug ( " Using URL `%s' \n " , url ) ;
1995-05-23 03:41:18 +01:00
hostname = url + 6 ;
1995-05-26 09:41:52 +01:00
if ( ( dir = index ( hostname , ' / ' ) ) ! = NULL )
* ( dir + + ) = ' \0 ' ;
1995-05-26 11:20:47 +01:00
strcpy ( dev - > name , hostname ) ;
1995-05-24 02:27:15 +01:00
msgDebug ( " hostname = `%s' \n " , hostname ) ;
1995-05-26 11:20:47 +01:00
msgDebug ( " dir = `%s' \n " , dir ? dir : " / " ) ;
1995-05-24 18:49:20 +01:00
msgNotify ( " Looking up host %s.. " , hostname ) ;
1995-05-24 02:27:15 +01:00
if ( ( gethostbyname ( hostname ) = = NULL ) & & ( inet_addr ( hostname ) = = INADDR_NONE ) ) {
1995-05-24 18:49:20 +01:00
msgConfirm ( " Cannot resolve hostname `%s'! Are you sure your name server \n and/or gateway values are set properly? " , hostname ) ;
1995-05-23 03:41:18 +01:00
return FALSE ;
}
snprintf ( email , BUFSIZ , " installer@%s " , my_name ) ;
1995-05-24 02:27:15 +01:00
msgDebug ( " Using fake e-mail `%s' \n " , email ) ;
1995-05-23 03:41:18 +01:00
1995-05-24 10:00:58 +01:00
msgNotify ( " Logging in as anonymous. " ) ;
1995-05-23 03:41:18 +01:00
if ( ( i = FtpOpen ( ftp , hostname , " anonymous " , email ) ) ! = 0 ) {
1995-05-24 02:27:15 +01:00
msgConfirm ( " Couldn't open FTP connection to %s: %s (%u) \n " , hostname , strerror ( i ) , i ) ;
1995-05-23 03:41:18 +01:00
return FALSE ;
}
if ( getenv ( " ftpPassive " ) )
FtpPassive ( ftp , 1 ) ;
FtpBinary ( ftp , 1 ) ;
1995-05-26 09:41:52 +01:00
if ( dir & & * dir ! = ' \0 ' ) {
1995-05-24 18:49:20 +01:00
msgNotify ( " CD to distribution in ~ftp/%s " , dir ) ;
1995-05-23 03:41:18 +01:00
FtpChdir ( ftp , dir ) ;
1995-05-24 18:49:20 +01:00
}
1995-05-24 10:00:58 +01:00
msgDebug ( " leaving mediaInitFTP! \n " ) ;
1995-05-17 15:40:00 +01:00
return TRUE ;
}
1995-05-24 19:21:49 +01:00
static pid_t ftppid = 0 ;
1995-05-23 03:41:18 +01:00
int
1995-05-26 09:41:52 +01:00
mediaGetFTP ( char * dist , char * path )
1995-05-17 15:40:00 +01:00
{
1995-05-24 02:27:15 +01:00
int fd ;
char buf [ 512 ] ;
1995-05-24 18:49:20 +01:00
int pfd [ 2 ] , numchunks ;
1995-05-24 02:27:15 +01:00
const char * tmp ;
struct attribs * dist_attr ;
1995-05-24 18:49:20 +01:00
1995-05-26 12:21:53 +01:00
if ( ! path )
path = " " ;
1995-05-26 09:41:52 +01:00
msgNotify ( " Attempting to retreive `%s' over FTP " , dist ) ;
1995-05-26 12:21:53 +01:00
snprintf ( buf , PATH_MAX , " /stand/info/%s%s.inf " , path , dist ) ;
1995-05-26 09:41:52 +01:00
if ( ! access ( buf , R_OK ) ) {
msgDebug ( " Parsing attributes file for %s \n " , dist ) ;
dist_attr = safe_malloc ( sizeof ( struct attribs ) * MAX_ATTRIBS ) ;
if ( attr_parse ( & dist_attr , buf ) = = 0 ) {
msgConfirm ( " Cannot load information file for %s distribution! \n Please verify that your media is valid and try again. " , dist ) ;
return - 1 ;
}
1995-05-24 02:27:15 +01:00
1995-05-26 09:41:52 +01:00
msgDebug ( " Looking for attribute `pieces' \n " ) ;
tmp = attr_match ( dist_attr , " pieces " ) ;
numchunks = atoi ( tmp ) ;
}
else
numchunks = 0 ;
msgDebug ( " Attempting to extract distribution from %u files \n " , numchunks ? numchunks : 1 ) ;
1995-05-24 02:27:15 +01:00
1995-05-26 09:41:52 +01:00
/* Take the lack of an info file to mean we're a fully qualified name */
if ( ! numchunks ) {
1995-05-26 12:21:53 +01:00
sprintf ( buf , " %s%s " , path , dist ) ;
1995-05-26 09:41:52 +01:00
return ( FtpGet ( ftp , buf ) ) ;
}
else if ( numchunks = = 1 ) {
1995-05-26 12:21:53 +01:00
snprintf ( buf , 512 , " %s%s.aa " , path , dist ) ;
1995-05-24 02:27:15 +01:00
return ( FtpGet ( ftp , buf ) ) ;
}
1995-05-24 18:49:20 +01:00
/* reap the previous child corpse - yuck! */
1995-05-24 19:21:49 +01:00
if ( ftppid ) {
1995-05-24 18:49:20 +01:00
int i , j ;
1995-05-24 19:21:49 +01:00
i = waitpid ( ftppid , & j , 0 ) ;
1995-05-24 18:49:20 +01:00
if ( i < 0 | | WEXITSTATUS ( j ) ) {
msgConfirm ( " Previous FTP transaction returned status code %d - aborting \n transfer. " , WEXITSTATUS ( j ) ) ;
1995-05-24 19:21:49 +01:00
ftppid = 0 ;
1995-05-24 18:49:20 +01:00
return - 1 ;
}
1995-05-24 19:21:49 +01:00
ftppid = 0 ;
1995-05-24 18:49:20 +01:00
}
1995-05-24 02:27:15 +01:00
pipe ( pfd ) ;
1995-05-24 19:21:49 +01:00
ftppid = fork ( ) ;
if ( ! ftppid ) {
1995-05-24 18:49:20 +01:00
int chunk ;
1995-05-24 02:27:15 +01:00
int retval ;
1995-05-24 18:49:20 +01:00
1995-05-24 02:27:15 +01:00
dup2 ( pfd [ 1 ] , 1 ) ; close ( pfd [ 1 ] ) ;
close ( pfd [ 0 ] ) ;
1995-05-24 18:49:20 +01:00
for ( chunk = 0 ; chunk < numchunks ; chunk + + ) {
char buffer [ 10240 ] ;
1995-05-24 02:27:15 +01:00
int n ;
1995-05-26 12:21:53 +01:00
snprintf ( buf , 512 , " %s%s.%c%c " , path , dist , ( chunk / 26 ) + ' a ' , ( chunk % 26 ) + ' a ' ) ;
1995-05-24 02:27:15 +01:00
fd = FtpGet ( ftp , buf ) ;
1995-05-24 12:19:11 +01:00
if ( fd < 0 )
{
1995-05-24 18:49:20 +01:00
msgConfirm ( " FtpGet failed to retreive piece `%s' in the %s distribution! \n Aborting the transfer " , chunk , dist ) ;
1995-05-24 12:19:11 +01:00
exit ( 1 ) ;
}
1995-05-24 02:27:15 +01:00
1995-05-24 12:19:11 +01:00
while ( ( n = read ( fd , buffer , 10240 ) ) > 0 )
1995-05-24 02:27:15 +01:00
{
retval = write ( 1 , buffer , n ) ;
if ( retval ! = n )
{
1995-05-24 18:49:20 +01:00
msgConfirm ( " Write failure on transfer! (wrote %d bytes of %d bytes) " , retval , n ) ;
1995-05-24 02:27:15 +01:00
exit ( 1 ) ;
}
}
FtpEOF ( ftp ) ;
}
close ( 1 ) ;
1995-05-24 18:49:20 +01:00
msgDebug ( " Extract of %s finished with success!!! \n " , dist ) ;
1995-05-24 02:27:15 +01:00
exit ( 0 ) ;
}
close ( pfd [ 1 ] ) ;
return ( pfd [ 0 ] ) ;
1995-05-17 15:40:00 +01:00
}
void
1995-05-24 10:00:58 +01:00
mediaShutdownFTP ( Device * dev )
1995-05-17 15:40:00 +01:00
{
1995-05-24 18:49:20 +01:00
Device * netdev = ( Device * ) dev - > private ;
if ( ftp ! = NULL ) {
FtpClose ( ftp ) ;
ftp = NULL ;
}
1995-05-24 19:21:49 +01:00
if ( ftppid ) {
int i , j ;
i = waitpid ( ftppid , & j , 0 ) ;
if ( i < 0 | | WEXITSTATUS ( j ) )
msgConfirm ( " Warning: Last FTP transaction returned status code %d. " , WEXITSTATUS ( j ) ) ;
ftppid = 0 ;
}
1995-05-24 18:49:20 +01:00
if ( netdev - > shutdown )
( * netdev - > shutdown ) ( netdev ) ;
1995-05-17 15:40:00 +01:00
}
Boolean
1995-05-20 19:38:39 +01:00
mediaInitUFS ( Device * dev )
1995-05-17 15:40:00 +01:00
{
return TRUE ;
}
1995-05-23 03:41:18 +01:00
int
1995-05-26 09:41:52 +01:00
mediaGetUFS ( char * dist , char * path )
1995-05-17 15:40:00 +01:00
{
1995-05-23 03:41:18 +01:00
return - 1 ;
1995-05-17 15:40:00 +01:00
}
1995-05-24 10:00:58 +01:00
/* UFS has no Shutdown routine since this is handled at the device level */
1995-05-20 19:38:39 +01:00
1995-05-17 15:40:00 +01:00
Boolean
1995-05-20 19:38:39 +01:00
mediaInitDOS ( Device * dev )
1995-05-17 15:40:00 +01:00
{
return TRUE ;
}
1995-05-23 03:41:18 +01:00
int
1995-05-26 09:41:52 +01:00
mediaGetDOS ( char * dist , char * path )
1995-05-17 15:40:00 +01:00
{
1995-05-23 03:41:18 +01:00
return - 1 ;
1995-05-17 15:40:00 +01:00
}
1995-05-20 19:38:39 +01:00
void
1995-05-24 10:00:58 +01:00
mediaShutdownDOS ( Device * dev )
1995-05-20 19:38:39 +01:00
{
}