[comp.os.minix] MINIX -> DOS from DOS

goodloe@b11.ingr.com (Tony Goodloe) (11/02/90)

Does someone have a utility for reading a MINIX file system from DOS. I
know that there are those that run under MINIX, but MINIX won't run on
my machine. Any help is greatly appreciated.
tony

Markku.Savela@tel.vtt.fi (Markku Savela) (11/02/90)

In article <9287@b11.ingr.com> goodloe@b11.ingr.com (Tony Goodloe) writes:
>Does someone have a utility for reading a MINIX file system from DOS. I

  Well, while back, a year ago or so, when I wanted to examine
the minix code, I wrote a crude program under MS-DOS (Microsoft
C) that once started, copied the whole minix filesystem from a
floppy drive into close equivalent of MS-DOS file tree. [Close
equivalent meaning, that it copied linked files twice and brutally
truncated filenames to MS-DOS limits...

  I bet there exists more robust programs, I don't know. I didn't
use it much after that.
--
Markku Savela                         | savela@tel.vtt.fi
Technical Research Centre of Finland  |
Telecommunications Laboratory         | Markku.Savela@vtt.fi
Otakaari 7 B, SF-02150 ESPOO, Finland | savela%vtttel@router.funet.fi 

epames@eos.ericsson.se (Michael Salmon) (11/05/90)

In article <9287@b11.ingr.com> Tony Goodloe writes:
>Does someone have a utility for reading a MINIX file system from DOS. I
>know that there are those that run under MINIX, but MINIX won't run on
>my machine. Any help is greatly appreciated.

I had this problem when I first bought MINIX and the way that I solved it
was to write a short Turbo Pascal programme that read the entire disk into
a DOS file using BIOS calls and a similar one to write it out. I then went
on to write a programme to explore the file system, this was a little
harder but a good way to learn the file system. I would happily send you
copies but unfortunately the code is in Australia and I am in Sweden.

Good luck
    Michael

feustel@netcom.UUCP (David Feustel) (11/06/90)

The Minix readfs program can be slightly modified to read files from
the Minix file system and copy them to the dos file system.
-- 
David Feustel, 1930 Curdes Ave, Fort Wayne, IN 46805, (219) 482-9631

Markku.Savela@tel.vtt.fi (Markku Savela) (11/07/90)

In article <9287@b11.ingr.com> goodloe@b11.ingr.com (Tony Goodloe) writes:

>Does someone have a utility for reading a MINIX file system from DOS. I
>know that there are those that run under MINIX, but MINIX won't run on
>my machine. Any help is greatly appreciated.
>tony

   Here is a simple program I wrote to transfer the MINIX
file system to MSDOS files. As this is rather short, I decided
to post it...

 - it reads from floppy drive 0 (hard coded ;-) (easy to change,
   if one really wants to)
 - I compiled the code with Microsoft 4.0
 - the MAKEFILE is for NDMAKE (not Microsoft Make!)
 - apologies for the uppercase filenames, I did the shar under
   MSDOS.
---------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  DISKIO.ASM DISKIO.H MAKEFILE MINIXFS.C
# Wrapped by ibmpc@laphroig.UUCP on Tue Nov 06 22:26:58 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f DISKIO.ASM -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"DISKIO.ASM\"
else
echo shar: Extracting \"DISKIO.ASM\" \(853 characters\)
sed "s/^X//" >DISKIO.ASM <<'END_OF_DISKIO.ASM'
X	TITLE   diskio
X	PUBLIC	DISKREAD
X
XDISKIO_TEXT	SEGMENT  BYTE PUBLIC 'CODE'
X	ASSUME  CS: DISKIO_TEXT
X
XDISKREAD	proc far
X
X	push	bp
X	mov	bp,sp
X
X	push	bx		; save all registers
X	push	cx
X	push	dx
X	push	bp
X	push	di
X	push	si
X	push	ds
X
X;	drive = 14
X;	buffer = 10
X;	sectors = 8
X;	first = 6
X
X	mov	al,[bp+14]	;drive
X	mov	cx,[bp+8]	;sectors
X	mov	dx,[bp+6]	;first
X	lds	bx,[bp+10]	;buffer
X	int	25h
X	jnb	readok		; if CF=0, it was a success...
X
X	;
X	;	Error detected -- make sure, that AX is non-zero
X	;
X	cmp	ax,0		;
X	jne	readex		;
X	or	ah,01h		; Add "bad command flag"
X	jmp	readex		;
X
X	;
X	;	Read succeeded -- make sure that AX is zero
X	;
Xreadok:	xor	ax,ax
X
Xreadex:
X	popf			; ...because int 25h leaves flags on stack!!!
X
X	pop	ds		; ...restore saved registers
X	pop	si
X	pop	di
X	pop	bp
X	pop	dx
X	pop	cx
X	pop	bx
X
X	mov	sp,bp
X	pop	bp
X	ret	10
X
XDISKREAD	ENDP
X
XDISKIO_TEXT	ENDS
XEND
X
END_OF_DISKIO.ASM
if test 853 -ne `wc -c <DISKIO.ASM`; then
    echo shar: \"DISKIO.ASM\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f DISKIO.H -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"DISKIO.H\"
else
echo shar: Extracting \"DISKIO.H\" \(679 characters\)
sed "s/^X//" >DISKIO.H <<'END_OF_DISKIO.H'
X/*
X**	C-callable assembler routines for reading and writing
X**	from/to absolute disk blocks. (These are just calling
X**	the corresponding MS-DOS-functions--very primitive).
X*/
X
Xunsigned int far pascal diskread(
X#if MSC
X    int,		/* Drive number (0=A, 1=B, etc) */
X    char far *,		/* Destination Memory Address */
X    unsigned int,	/* Number of sectors to read */
X    unsigned int	/* First Relative Sector to read */
X#endif
X);
X
X
Xunsigned int far pascal diskwrite(
X#if MSC
X    int,		/* Drive number (0=A, 1=B, etc) */
X    char far *,		/* Source Memory Address */
X    unsigned int,	/* Number of sectors to write */
X    unsigned int	/* First Relative Sector to write */
X#endif
X);
X
X
END_OF_DISKIO.H
if test 679 -ne `wc -c <DISKIO.H`; then
    echo shar: \"DISKIO.H\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f MAKEFILE -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"MAKEFILE\"
else
echo shar: Extracting \"MAKEFILE\" \(254 characters\)
sed "s/^X//" >MAKEFILE <<'END_OF_MAKEFILE'
X#
X# 	Makefile
X# 
XVPATH= .
X
XCFLAGS= -AL -DLINT_ARGS -DMSC=1 -Gs -Oat -W3
XDEBUG=
X
X.c.obj:; msc $(CFLAGS) $(DEBUG) $*.c;
X
X# All object modules
X
Xminixfs : minixfs.exe
X
Xminixfs.exe : minixfs.obj diskio.obj
X	link minixfs+diskio, $* /NOIG /STACK:0x3000, $* ;
X	
END_OF_MAKEFILE
if test 254 -ne `wc -c <MAKEFILE`; then
    echo shar: \"MAKEFILE\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f MINIXFS.C -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"MINIXFS.C\"
else
echo shar: Extracting \"MINIXFS.C\" \(15141 characters\)
sed "s/^X//" >MINIXFS.C <<'END_OF_MINIXFS.C'
X/*	*******
X**	minixfs
X**	*******
X**	November 1988,	Markku Savela
X**
X**	A very simple program to transfer all files from a MINIX
X**	file system (on floppy) to a corresponding MS-DOS file
X**	structure (sub directories and all...).
X**
X**	The copy loop terminates on any detected error condition.
X**
X**	This module should be compiled into LARGE MODEL (-AL).
X**	(Directory scanning is implemented by simple recursion,
X**	which allocates a new buffer for each level.)
X**
X**	NOTE 1	Files are copied in binary. No special LF->CR/LF
X**		conversions. (Vernon D. Buerg LIST and uEmacs
X**		accept LF-format happily -- so, who cares...?)
X**
X**	NOTE 2	This program works only because of the (lucky?)
X**		coincidence that both MINIX and MS-DOS seem to
X**		use the same logical block/sector -> physical
X**		(cyl,head,sector) mapping. (Watch out, if someone
X**		enables the software interleaving or other exotic
X**		reorderings...). Disk I/O is done with INT 25 in
X**		module "diskio.asm".
X**
X**	NOTE 3	Because MINIX uses 9 sectors/track and BIOS/MSDOS is
X**		defaulted to 8 sectors/track (?), there might be some
X**		problems reading the floppy. With my AT clone it was
X**		sufficient to once use properly MS-DOS formatted
X**		360Kb floppy on the drive and give "DIR"-command.
X**		After that MS-DOS/BIOS seemed to agree on 9 sectors/
X**		track.
X**
X**	NOTE 4	This program is coded for MSC 4.0 and it's "near-ANSI-
X**		prototypes" are included, if symbol "MSC" is defined.
X**		(MSC 4.0 doesn't accept prototypes with identifiers.)
X**
X**	NOTE 5	Although some parts of the code seem to account for
X**		the situation BLOCK_SIZE != ZONE_SIZE, this program
X**		really cannot handle it. Some static buffers should
X**		be allocated dynamically and NR_INDIRECTS cannot be
X**		a define constant(?).
X*/
X#include <string.h>
X#include <stdio.h>
X#include <direct.h>
X#include <malloc.h>
X
X#include "diskio.h"
X
X#define TRUE	1
X#define FALSE	0
X
X#define SECTOR_SIZE	512	/* MS-DOS sector Size on floppy (for INT 25) */
X
X#define SECTORS		2	/* Sectors in MINIX block */
X#define BLOCK_SIZE	(SECTORS*SECTOR_SIZE)
X
X/*
X**	Definitions from the MINIX book (same structures used because
X**	this makes it possible to use the original MINIX .h-files in
X**	some later stage...)
X*/
Xtypedef unsigned short unshort;
Xtypedef unshort block_nr;
Xtypedef unshort inode_nr;
Xtypedef unshort zone_nr;
Xtypedef long file_pos;
Xtypedef unshort mask_bits;
Xtypedef long real_time;
Xtypedef short int uid;
Xtypedef char gid;
Xtypedef char links;
X
X#define NO_BLOCK	(block_nr)0
X#define MAX_BLOCK_NR	(block_nr)0177777
X#define NO_ENTRY	(inode_nr)0
X#define MAX_INODE_NR	(inode_nr)0177777
X#define NO_ZONE		(zone_nr)0
X#define HIGHEST_ZONE	(zone_nr)0177777
X
X#define MAX_LINKS	0177
X#define SUPER_MAGIC	0x137F
X
X#define NR_ZONE_NUMS	9
X#define NAME_SIZE	14
X
X#define BOOT_BLOCK	(block_nr)0
X#define SUPER_BLOCK	(block_nr)1
X#define ROOT_INODE	(inode_nr)1
X
X#define ZONE_NUM_SIZE	(sizeof(zone_nr))
X#define NR_INDIRECTS	(BLOCK_SIZE/ZONE_NUM_SIZE)
X#define NR_DIR_ENTRIES	(BLOCK_SIZE/sizeof(dir_struct))
X
Xtypedef struct super_block
X{
X	inode_nr s_ninodes;
X	zone_nr	s_nzones;
X	unshort s_imap_blocks;
X	unshort s_zmap_blocks;
X	zone_nr s_firstdatazone;
X	short int s_log_zone_size;
X	file_pos s_max_size;
X	int s_magic;
X} super_block;
X
Xtypedef struct
X{
X	inode_nr d_inum;
X	char d_name[NAME_SIZE];
X} dir_struct;
X
Xtypedef struct
X{
X	mask_bits i_mode;
X	uid i_uid;
X	file_pos i_size;
X	real_time i_modtime;
X	gid i_gid;
X	links i_nlinks;
X	zone_nr i_zone[NR_ZONE_NUMS];
X} d_inode;
X
X#define INODE_SIZE	(sizeof(d_inode))
X#define INODES_PER_BLOCK (BLOCK_SIZE/INODE_SIZE)
X
X#define I_TYPE		0170000
X#define I_REGULAR	0100000
X#define I_BLOCK_SPECIAL	0060000
X#define I_DIRECTORY	0040000
X#define	I_CHAR_SPECIAL	0020000
X#define	I_SET_UID_BIT	0004000
X#define I_SET_GID_BIT	0002000
X#define I_ALL_MODES	0006777
X#define	I_RWX_MODES	0000777
X#define R_BIT		0000004
X#define W_BIT		0000002
X#define X_BIT		0000001
X
X/*
X**	End of MINIX definitions
X*/
X#define SINGLE_INDIRECT	7
X#define DOUBLE_INDIRECT 8
X
Xstatic int Drive = 0;		/* Current Drive Number, 0 = A, 1 = B, ... */
Xstatic super_block sb;		/* Current Super Block */
X
Xstatic d_inode root;	/* i-node of root directory */
X
X/*
X**	Current (if any) block of i-nodes
X*/
X
Xstatic block_nr ib_block = NO_BLOCK;
Xstatic d_inode ib[INODES_PER_BLOCK];
X
X/*
X**	Current (if any) block of any directory
X*/
Xstatic block_nr db_block = NO_BLOCK;
Xstatic dir_struct db[NR_DIR_ENTRIES];
X
X/*
X**	Raw Disk Block Buffer
X*/
Xstatic char buffer[BLOCK_SIZE];
X
X/*
X**	Raw Zone Number Buffer
X*/
Xstatic zone_nr zb_zone = NO_ZONE;
Xstatic zone_nr zb[NR_INDIRECTS];
X
X/*
X**	Track of processed i-nodes (needed in detecting links).
X**	(Allocated dynamically the number of i-nodes is know --
X**	actually, for MINIX an allocation of 8Kb would always be
X**	enough...)
X*/
Xstatic char *imap = NULL;
X
X
Xstatic int ReadBlocks(
X#if MSC
X    block_nr,
X    char *,
X    int
X#endif
X);
X
X/*
X**	Read one Minix Block from the current drive.
X**	(Assuming the simplest (or same as MS-DOS uses) possible
X**	mapping from logical blocks into physical blocks).
X*/
Xstatic int ReadBlocks(block,buffer,count)
Xblock_nr block;		/* Minix Block number to read */
Xchar *buffer;		/* Destination buffer */
Xint count;		/* Number of blocks to read */
X{
X    int error;
X
X    if ((error = diskread(Drive,buffer,count * SECTORS, block * SECTORS)) != 0)
X    	{
X    	printf("MS-DOS I/O (INT 25) reports error AX=%xh\n",error);	
X    	return 0;
X    	}
X    else
X    	return count;
X}
X
X
Xvoid DumpSuperBlock(sb)
Xsuper_block *sb;
X{
X	printf("s_ninodes       = %u\n", (int)sb->s_ninodes);
X	printf("s_nzones        = %u\n", (int)sb->s_nzones);
X	printf("s_imap_blocks   = %u\n", (int)sb->s_imap_blocks);
X	printf("s_zmap_blocks   = %u\n", (int)sb->s_zmap_blocks);
X	printf("s_firstdatazone = %u\n", (int)sb->s_firstdatazone);
X	printf("s_log_zone_size = %u\n", (int)sb->s_log_zone_size);
X	printf("s_max_size      = %ld\n",(long)sb->s_max_size);
X	printf("s_magic         = %u\n", (int)sb->s_magic);
X
X}
X
X/*
X**	Get pointer to i-node in ib. (Note: Only one such
X**	pointer can be valid at time -- if several i-nodes
X**	are needed at the same time, a copy must be made
X**	before calling this again.
X*/
Xstatic d_inode *get_inode(
X#if MSC
X     inode_nr
X#endif
X);
X
Xstatic d_inode *get_inode(inode)
Xinode_nr inode;
X{
X	block_nr block;
X
X	--inode;	/* i-nodes are numbered from 1, but i-nodes are
X			** indexed from 0. I wish the BOOK had been more
X			** clear about this; by quick reading I got the
X			** impression (p. 301), that 0'th i-node IS NOT
X			** used and that root i-node is at 1! Only after
X			** getting strange results I found out this from
X			** program listings... (arrghh!)
X			*/
X	block = 1 			/* boot block */
X		+ 1			/* super block */
X		+ sb.s_imap_blocks	/* i-node bitmap */
X		+ sb.s_zmap_blocks	/* zone bitmap */
X		+ (inode / INODES_PER_BLOCK);
X	if (ib_block != block)
X		{
X		if (ReadBlocks(block,(char *)ib,1) != 1)
X			{
X			ib_block = NO_BLOCK;
X			return NULL;
X			}
X		ib_block = block;
X		}
X	return &ib[inode % INODES_PER_BLOCK];
X}
X
X
X/*
X**	Read zone array into zb (if required). For large files
X**	there should be at least two buffers to handle the "Double
X**	Indirect"-situations (Double Indirect works, but you surely
X**	get tired of waiting the results and nervous about the noise
X**	your floppy is making...)
X*/
Xstatic int ReadZone(
X#if MSC
X    zone_nr
X#endif
X);
Xstatic int ReadZone(z)
Xzone_nr z;
X{
X	if (z != zb_zone)
X		{
X		if (ReadBlocks(
X				(block_nr)z << sb.s_log_zone_size,
X				(char *)zb,
X				1 << sb.s_log_zone_size) > 0)
X			zb_zone = z;
X		else
X			zb_zone = NO_ZONE;
X		}
X	return (int)zb_zone;
X		
X}
X
X
X/*
X**	Convert file block number into logical disk block number.
X**	(This code is straight from the BOOK, because I was lazy)
X*/
Xstatic block_nr disk_block(
X#if MSC
X   zone_nr *,
X   block_nr
X#endif
X);
X
Xstatic block_nr disk_block(zones,block)
Xzone_nr *zones;
Xblock_nr block;
X{
X	long zone, excess;
X	int boff;
X	zone_nr z;
X
X	zone = block >> sb.s_log_zone_size;
X	boff = (int)(block - (zone << sb.s_log_zone_size));
X	if (zone < SINGLE_INDIRECT)
X		{
X		if ((z = zones[zone]) == NO_ZONE)
X			return NO_BLOCK;
X		return ((block_nr)z << sb.s_log_zone_size) + boff;
X		}
X	excess = zone - SINGLE_INDIRECT;
X	if (excess < NR_INDIRECTS)
X		{
X		z = zones[SINGLE_INDIRECT];
X		}
X	else
X		{
X		if ((z = zones[DOUBLE_INDIRECT]) == NO_ZONE)
X			return NO_BLOCK;
X		excess -= NR_INDIRECTS;
X		ReadZone(z);
X		z = zb[excess/NR_INDIRECTS];
X		excess %= NR_INDIRECTS;
X		}
X	if (z == NO_ZONE)
X		return NO_BLOCK;
X	ReadZone(z);
X	z = zb[excess];
X	if (z == NO_ZONE)
X		return NO_BLOCK;
X	return ((block_nr)z << sb.s_log_zone_size) + boff;
X}
X
X
X/*
X**	Read a block from a file specified by the i-node.
X*/
Xstatic int get_block(
X#if MSC
X     d_inode *,
X     block_nr,
X     char *
X#endif
X);
X
Xstatic int get_block(inode,block,buffer)
Xd_inode *inode;	/* i-node of the file */
Xblock_nr block;
Xchar *buffer;
X{
X	if ((block = disk_block(inode->i_zone,block)) == NO_BLOCK)
X		return FALSE;
X	return (ReadBlocks(block,buffer,1) == 1);
X}
X
X
X/*
X**	Do some simple consistency checks on i-node. Return TRUE (!),
X**	bad things are detected.
X*/
Xstatic int BadNode(
X#if MSC
X    d_inode *
X#endif
X);
Xstatic int BadNode(inode)
Xd_inode *inode;
X{
X	register int z;
X
X	if (inode->i_nlinks == 0)
X		{
X		printf("i-node has zero link field\n");
X		return TRUE;
X		}
X
X	for (z = 0; z < NR_ZONE_NUMS; ++z)
X		if (inode->i_zone[z] >= sb.s_nzones)
X			{
X			printf("i-node contains bad zone block (%u)\n",
X				inode->i_zone[z]);
X			return TRUE;
X			}
X	return FALSE;
X}
X
X
X/*
X**	"mount" MINIX file system volume
X*/
Xstatic int mount()
X{
X	d_inode *inode;
X	register int i;
X
X	if (ReadBlocks(SUPER_BLOCK,buffer,1) != 1)
X		{
X		printf("Failed in reading super block\n");
X		return FALSE;
X		}
X	sb = *(super_block *)buffer;
X	DumpSuperBlock(&sb);
X	if (sb.s_magic != SUPER_MAGIC)
X		{
X		printf("SUPER MAGIC doesn't match -- non-minix volume\n");
X		return FALSE;
X		}
X	if (sb.s_log_zone_size != 0)
X		{
X		printf("Sorry, really can't handle zonesize != blocksize\n");
X		printf("...perhaps you should add the capability?\n");
X		return FALSE;
X		}
X	if ((inode = get_inode(ROOT_INODE)) == NULL)
X		{
X		printf("Failed in accessing ROOT I-node\n");
X		return FALSE;
X		}
X	/*
X	**	Allocate and initialize i-node "tracing map"
X	**	for link detection
X	*/
X	i = sb.s_ninodes / 8 + 1;
X	if ((imap = (char *)malloc(i)) == NULL)
X		{
X		printf("Couldn't allocate for i-node map\n");
X		return FALSE;
X		}
X	while (--i >= 0)
X		imap[i] = '\0';
X	imap[ROOT_INODE / 8] |= 1 << (ROOT_INODE % 8);
X
X	root = *inode;
X	return !BadNode(inode);
X}
X
X/*
X**	A quick hack to convert Minix Filename into MS-DOS Name
X*/
Xstatic void MessDosName(char *, char *);
Xstatic void MessDosName(Dos,Minix)
Xchar *Dos;
Xchar *Minix;
X{
X	register int i, Dot;
X
X	for (i = 0; i < NAME_SIZE && Minix[i] != '\0'; ++i)
X		Dos[i] = Minix[i];
X	Dos[i] = '\0';
X
X	/*
X	**	Convert dot in the name into "~", if it's followed
X	**	by more than 3 name characters or if there exists
X	**	another dot closer to end (who would use names like
X	**	"x..y", but just to be complete...?). Also, convert
X	**	dot anyway, if it begins the name.
X	*/
X	Dot = 0;
X	while (--i >= 0)
X		{
X		if (Dos[i] == '.')
X			if (Dot > 3 || i == 0)
X				Dos[i] = '~';
X			else
X				Dot = 3; /* This takes care of "x..y" */
X		++Dot;
X		}
X}
X
Xstatic int CopyFile(
X#if MSC
X    char *,
X    d_inode *
X#endif
X);
Xstatic int CopyFile(name,inp)
Xchar *name;
Xd_inode *inp;
X{
X	d_inode inode;
X	FILE *f;
X	file_pos length = 0;
X	block_nr block;
X	int size;
X
X	inode = *inp;
X	if ((f = fopen(name,"wb")) == NULL)
X		{
X		printf("Cannot create %s\n",name);
X		return FALSE;
X		}
X	block = 0;
X	length = inode.i_size;
X	size = BLOCK_SIZE;
X	while (length > 0)
X		{
X		if (get_block(&inode,block,buffer) == NO_BLOCK)
X			{
X			printf("Unexpected EOF on '%s'\n",name);
X			break;
X			}
X		if (length < BLOCK_SIZE)
X			size = (int)length;
X		if (fwrite(buffer,size,1,f) != 1)
X			{
X			printf("Write error on '%s'\n",name);
X			break;
X			}
X		block++;
X		length -= BLOCK_SIZE;
X		}
X	fclose(f);
X	return TRUE;
X}
X
Xstatic int CopyAllFiles(
X#if MSC
X    inode_nr
X#endif
X);
X
X
Xstatic int CopyDirectory(
X#if MSC
X    inode_nr,
X    char *
X#endif
X);
X
Xstatic int CopyDirectory(inr,name)
Xinode_nr inr;
Xchar *name;
X{
X	int result;
X
X	printf("\n--> new directory %s <---\n\n",name);
X	mkdir(name);
X	if (chdir(name) != 0)
X		{
X		printf("Cannot chdir(\"%s\")\n",name);
X		return FALSE;
X		}
X	result = CopyAllFiles(inr);
X	printf("\n--> done with %s <--\n\n",name);
X	chdir("..");
X	return result;
X}
X
X
Xstatic int CopyEntry(
X#if MSC
X    dir_struct *
X#endif
X);
Xstatic int CopyEntry(d)
Xdir_struct *d;
X{
X	d_inode *inode;
X	mask_bits t;
X	char name[NAME_SIZE+1];
X	register int inr = d->d_inum;
X
X	if (inr == NO_ENTRY)
X		return TRUE;		/* ...or should this be an-error? */
X
X	if (inr > sb.s_ninodes)
X		{
X		printf("Bad i-node number (%d)\n",(int)d->d_inum);
X		return FALSE;
X		}
X
X	/*
X	**	This "links" test takes care of the ".." and "."
X	**	entries, too!
X	*/
X	if ( (1 << (inr % 8)) & imap[(inr /8)] )
X		{
X		printf("Linked i-node: '%s' already handled\n",d->d_name);
X		return TRUE;
X		}
X	imap[(inr / 8)] |= 1 << (inr % 8);
X
X	if ((inode = get_inode(inr)) == NULL)	
X		return FALSE;
X
X	t = inode->i_mode & I_TYPE;
X	if (t == I_BLOCK_SPECIAL || t == I_CHAR_SPECIAL)
X		{
X		printf("Special file: '%s' not copied\n",d->d_name);
X		return TRUE;		/* ...skip specials */
X		}
X	if (BadNode(inode))		/* Checks other types for consistency */
X		return FALSE;
X	MessDosName(name,d->d_name);
X	if (t == I_REGULAR)
X		{
X		printf("Copying file: '%s' --> '%s'\n",d->d_name,name);
X		return CopyFile(name,inode);
X		}
X	else if (t == I_DIRECTORY)
X		return CopyDirectory(inr, name);
X	else
X		return TRUE;
X}
X
Xstatic int CopyAllFiles(inr)
Xinode_nr inr;
X{
X	dir_struct *dir;
X	d_inode inode, *inod;
X	int last_entry, entry, index, result;
X
X        dir = (dir_struct *)malloc(NR_DIR_ENTRIES*sizeof(dir_struct));
X	if (dir == NULL)
X		{
X		printf("Failed in allocating the directory buffer\n");
X		return FALSE;
X		}
X	if ((inod = get_inode(inr)) == NULL)
X		return FALSE;
X	inode = *inod;
X	last_entry = (int)(inode.i_size / sizeof(dir_struct));
X	result = TRUE;
X	for (entry = 0; entry < last_entry; ++entry)
X		{
X		if ((index = entry % NR_DIR_ENTRIES) == 0)
X			{
X			result = get_block(&inode,entry / NR_DIR_ENTRIES,(char *)dir);
X			if (!result)
X				{
X				printf("Unexpected EOF on directory\n");
X				break;
X				}
X			}
X		if ((result = CopyEntry(&dir[index])) == FALSE)
X			break;
X		}
X	free((char *)dir);
X	return result;
X}
X
Xvoid main(argc, argv)
Xint argc;
Xchar *argv[];
X{
X	register int i;
X	char *s;
X
X	if (argc != 2)
X		{
X		printf("Usage: minixfs msdos-directory-name\n");
X		return;
X		}
X	/*
X	**	Can copy only to default directory and drive (try to
X	**	check against attempts doomed to fail and confuse...)
X	*/
X	for (s = argv[1], i = 0; s[i] != '\0'; ++i)
X		if (s[i] == ':' || s[i] == '\\' || s[i] == '/')
X			{
X			printf("Directory name must be simple--no paths or disk drives\n");
X			return;
X			}
X
X	if (mount() && CopyDirectory(ROOT_INODE,s))
X		return;
X
X    	printf("\nTrouble detected; maybe you have a corrupted file system\n");
X    	printf("or you were hit by the 9/8-sectors/track-problem. Try inserting\n");
X    	printf("a MS-DOS formatted 360Kb disk into the drive, give a DIR-\n");
X    	printf("command and try again with this program and a minix floppy.\n");
X}
END_OF_MINIXFS.C
if test 15141 -ne `wc -c <MINIXFS.C`; then
    echo shar: \"MINIXFS.C\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
--
Markku Savela (savela@tel.vtt.fi), Technical Research Centre of Finland
Telecommunications Laboratory, Otakaari 7 B, SF-02150 ESPOO, Finland