Use _dos_allocmem for OW, similar to the Turbo C technique.

Split copy function into readfile and writefile functions.
Preserve time and date of kernel.sys and command.com.


git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@1354 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2007-08-29 14:17:21 +00:00
parent 69d767be50
commit 953e7b2007

217
sys/sys.c
View File

@ -40,7 +40,6 @@
#include <mem.h>
#else
#include <memory.h>
#include <malloc.h> /* fmalloc() in open watcom */
#endif
#include <string.h>
#ifdef __TURBOC__
@ -158,12 +157,23 @@ char *getenv(const char *name)
}
#endif
#ifdef __TURBOC__
typedef struct ftime ftime;
#else
typedef struct
{
unsigned short date, time;
} ftime;
#endif
BYTE pgm[] = "SYS";
void put_boot(int, char *, char *, int, int);
BOOL check_space(COUNT, ULONG);
BYTE far * copy(COUNT drive, BYTE * srcPath, BYTE * rootPath,
BYTE * file, BYTE far * buffer, ULONG * filesize);
BYTE far * readfile(COUNT drive, BYTE * srcPath, BYTE * rootPath,
BYTE * file, ULONG * filesize, ftime *filetime);
BOOL writefile(COUNT drive, BYTE * rootPath,
BYTE * file, BYTE far * buffer, ULONG filesize, ftime *filetime);
#define SEC_SIZE 512
#define COPY_SIZE 0x7e00
@ -242,51 +252,6 @@ struct VerifyBootSectorSize {
int FDKrnConfigMain(int argc, char **argv);
#ifndef __TURBOC__
#ifdef __WATCOMC__
/* int 21.48 takes a paragraph (16 byte units) count as input in bx */
/* ... int 21.48 returns the segment after the allocated MCB in ax */
void far * farmalloc( ULONG __size );
#pragma aux farmalloc = \
"shr cx, 1" \
"rcr bx, 1" \
"shr cx, 1" \
"rcr bx, 1" \
"shr cx, 1" \
"rcr bx, 1" \
"shr cx, 1" \
"rcr bx, 1" \
"inc bx" \
"xor dx, dx" \
"or cx, cx" \
"jnz nomalloc" \
"mov ax, 0x4800" \
"int 0x21" \
"jc nomalloc" \
"mov dx, ax" \
"nomalloc:" \
"xor ax, ax" \
parm [cx bx] \
modify [bx] \
value [dx ax];
void initalloc( void );
#pragma aux initalloc = \
"push es" \
"mov ax, cs" \
"mov es, ax" \
"mov bx, 0x1000" \
"mov ax, 0x4a00" \
"int 0x21" \
"pop es" \
modify [ax bx];
#endif
#endif
int main(int argc, char **argv)
{
COUNT drive; /* destination drive */
@ -294,8 +259,10 @@ int main(int argc, char **argv)
COUNT srcarg = 0; /* source argument position */
BYTE *bsFile = NULL; /* user specified destination boot sector */
ULONG kernelsize = 0; /* size of the kernel to be copied */
ftime kerneltime; /* time of the kernel to be copied */
BYTE far *kernelbuf = NULL; /* kernel to be copied */
ULONG shellsize = 0; /* size of the shell to be copied */
ftime shelltime; /* time of the shell to be copied */
BYTE far *shellbuf = NULL; /* shell to be copied */
unsigned srcDrive; /* source drive */
BYTE srcPath[SYS_MAXPATH]; /* user specified source drive and/or path */
@ -307,10 +274,6 @@ int main(int argc, char **argv)
char *kernel_name = "KERNEL.SYS";
int load_segment = 0x60;
#ifdef __WATCOMC__
initalloc(); /* reduce main MCB of .com file to 64 kB */
#endif
printf("FreeDOS System Installer " SYS_VERSION ", " __DATE__ "\n\n");
if (argc > 1 && memicmp(argv[1], "CONFIG", 6) == 0)
@ -426,21 +389,24 @@ int main(int argc, char **argv)
if (!bootonly)
{
printf("Reading %s...\n", kernel_name);
kernelbuf = copy(drive, srcPath, rootPath, kernel_name, NULL, &kernelsize);
kernelbuf = readfile(drive, srcPath, rootPath, kernel_name, &kernelsize,
&kerneltime);
if (kernelbuf == NULL)
{
printf("\n%s: cannot read \"%s\"\n", pgm, kernel_name);
exit(1);
} /* fetch kernel */
printf("\nReading COMMAND.COM...\n");
shellbuf = copy(drive, srcPath, rootPath, "COMMAND.COM", NULL, &shellsize);
shellbuf = readfile(drive, srcPath, rootPath, "COMMAND.COM", &shellsize,
&shelltime);
if (shellbuf == NULL)
{
char *comspec = getenv("COMSPEC");
if (comspec != NULL)
{
printf("%s: Trying \"%s\"\n", pgm, comspec);
shellbuf = copy(drive, comspec, NULL, "COMMAND.COM", NULL, &shellsize);
shellbuf = readfile(drive, comspec, NULL, "COMMAND.COM", &shellsize,
&shelltime);
if (shellbuf == NULL)
comspec = NULL;
}
@ -458,14 +424,16 @@ int main(int argc, char **argv)
if (!bootonly)
{
printf("\nWriting %s...\n", kernel_name);
if (copy(drive, NULL, rootPath, kernel_name, kernelbuf, &kernelsize)==NULL)
if (!writefile(drive, rootPath, kernel_name, kernelbuf, kernelsize,
&kerneltime))
{
printf("\n%s: cannot write \"%s\"\n", pgm, kernel_name);
exit(1);
} /* write kernel */
printf("\nWriting COMMAND.COM...\n");
if (copy(drive, NULL, rootPath, "COMMAND.COM", shellbuf, &shellsize)==NULL)
if (!writefile(drive, rootPath, "COMMAND.COM", shellbuf, shellsize,
&shelltime))
{
printf("\n%s: cannot write \"COMMAND.COM\"\n", pgm);
exit(1);
@ -1006,30 +974,24 @@ BOOL check_space(COUNT drive, ULONG bytes)
BYTE copybuffer[COPY_SIZE];
/* if buffer is NULL, read the file, set filesize, and return a buffer */
/* if buffer is not NULL, write, according to filesize, from buffer... */
BYTE far * copy(COUNT drive, BYTE * srcPath, BYTE * rootPath,
BYTE * file, BYTE far * buffer, ULONG * filesize)
/* read the file, set filesize, and return a buffer */
BYTE far * readfile(COUNT drive, BYTE * srcPath, BYTE * rootPath,
BYTE * file, ULONG * filesize, ftime *filetime)
{
static BYTE dest[SYS_MAXPATH], source[SYS_MAXPATH];
UWORD ret;
int fdin, fdout;
int fdin;
ULONG copied = 0;
struct stat fstatbuf;
BOOL reading = (buffer==NULL);
BYTE far *bufptr;
BYTE far *buffer;
UWORD theseg;
strcpy(source, srcPath);
if (rootPath != NULL) /* trick for comspec */
strcat(source, file);
if (!reading && *filesize==0) /* write mode but no writing needed */
{
printf("%s: source and destination were identical: skipping \"%s\"\n",
pgm, source);
return buffer;
}
if (reading && stat(source, &fstatbuf)) /* read mode */
if (stat(source, &fstatbuf)) /* read mode */
{
printf("%s: \"%s\" not found\n", pgm, source);
@ -1047,8 +1009,6 @@ BYTE far * copy(COUNT drive, BYTE * srcPath, BYTE * rootPath,
return NULL;
}
if (reading) /* if reading */
{
truename(dest, source); /* use dest as buffer for truename(source) */
strcpy(source, dest); /* write updated source string */
sprintf(dest, "%c:\\%s", 'A' + drive, file);
@ -1066,47 +1026,18 @@ BYTE far * copy(COUNT drive, BYTE * srcPath, BYTE * rootPath,
return NULL;
}
*filesize = filelength(fdin); /* return size */
} /* reading */
if (!reading) /* writing */
{
if (!check_space(drive, *filesize))
{
printf("%s: Not enough space to transfer %s\n", pgm, file);
/* close(fdin); */
/* exit(1); too pessimistic? we might overwrite a pre-existing file */
return NULL; /* still pessimistic, did not even try to overwrite... */
}
sprintf(dest, "%c:\\%s", 'A' + drive, file);
if ((fdout =
open(dest, O_RDWR | O_TRUNC | O_CREAT | O_BINARY,
S_IREAD | S_IWRITE)) < 0)
{
printf(" %s: can't create\"%s\"\nDOS errnum %d", pgm, dest, errno);
/* close(fdin); */
return NULL;
}
} /* writing */
if (reading) /* reading */
{
BYTE far *bufptr;
#ifdef __TURBOC__ /* workaround: farmalloc is nearmalloc if tiny model in TC2 ?? */
UWORD theseg;
if (allocmem((*filesize+15)>>4, &theseg)!=-1) /* allocate dos memory */
/* allocate dos memory */
#ifdef __TURBOC__
if (allocmem((unsigned)((*filesize+15)>>4), &theseg)!=-1)
#else
buffer = (BYTE far *)farmalloc(*filesize);
if (buffer==NULL)
if (_dos_allocmem((unsigned)((*filesize+15)>>4), &theseg)!=0)
#endif
{
printf("Not enough memory to buffer %lu bytes for %s\n", *filesize, source);
return NULL;
}
#ifdef __TURBOC__
buffer = MK_FP(theseg, 0);
#endif
bufptr = buffer;
bufptr = buffer = MK_FP(theseg, 0);
while ((ret = read(fdin, copybuffer, COPY_SIZE)) > 0)
{
UWORD offs;
@ -1127,15 +1058,57 @@ BYTE far * copy(COUNT drive, BYTE * srcPath, BYTE * rootPath,
}
copied += ret;
}
} /* reading */
if (!reading) /* writing */
{
#if defined __WATCOMC__ || defined _MSC_VER /* || defined __BORLANDC__ */
_dos_getftime(fdin, &filetime->date, &filetime->time);
#elif defined __TURBOC__
getftime(fdin, filetime);
#endif
close(fdin);
printf("%lu Bytes transferred", copied);
return buffer;
} /* readfile */
/* write, according to filesize, from buffer... */
BOOL writefile(COUNT drive, BYTE * rootPath,
BYTE * file, BYTE far * buffer, ULONG filesize, ftime *filetime)
{
static BYTE dest[SYS_MAXPATH], source[SYS_MAXPATH];
UWORD ret;
int fdout;
ULONG copied = 0;
BYTE far * bufptr = buffer;
if (filesize==0) /* write mode but no writing needed */
{
printf("%s: source and destination were identical: skipping \"%s\"\n",
pgm, source);
return TRUE;
}
if (!check_space(drive, filesize))
{
printf("%s: Not enough space to transfer %s\n", pgm, file);
/* exit(1); too pessimistic? we might overwrite a pre-existing file */
return FALSE; /* still pessimistic, did not even try to overwrite... */
}
sprintf(dest, "%c:\\%s", 'A' + drive, file);
if ((fdout =
open(dest, O_RDWR | O_TRUNC | O_CREAT | O_BINARY,
S_IREAD | S_IWRITE)) < 0)
{
printf(" %s: can't create\"%s\"\nDOS errnum %d", pgm, dest, errno);
return FALSE;
}
while (TRUE)
{
UWORD offs;
ULONG tocopy = *filesize - copied;
ULONG tocopy = filesize - copied;
if (tocopy==0)
break; /* done */
if (tocopy > (ULONG)COPY_SIZE)
@ -1159,28 +1132,15 @@ BYTE far * copy(COUNT drive, BYTE * srcPath, BYTE * rootPath,
}
copied += ret;
}
} /* writing */
#if 0 /* TODO: Clone file timestamps even in 2 pass copy mode... */
{
#if defined __WATCOMC__ || defined _MSC_VER /* || defined __BORLANDC__ */
unsigned short date, time;
_dos_getftime(fdin, &date, &time);
_dos_setftime(fdout, date, time);
_dos_setftime(fdout, filetime->date, filetime->time);
#elif defined __TURBOC__
struct ftime ftime;
getftime(fdin, &ftime);
setftime(fdout, &ftime);
setftime(fdout, filetime);
#endif
}
#endif /* timestamps */
if (reading)
close(fdin);
if (!reading)
close(fdout);
#if 0 /* no way :-p */
#ifdef __SOME_OTHER_COMPILER__
{
#include <utime.h>
@ -1190,11 +1150,10 @@ BYTE far * copy(COUNT drive, BYTE * srcPath, BYTE * rootPath,
utimb.modtime = fstatbuf.st_mtime; /* modification time */
utime(dest, &utimb);
};
#endif
#endif
printf("%lu Bytes transferred", copied);
return buffer;
} /* copy */
return TRUE;
} /* writefile */