summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/sysinstall/Makefile10
-rw-r--r--sbin/sysinstall/dev2c.sh80
-rw-r--r--sbin/sysinstall/exec.c11
-rw-r--r--sbin/sysinstall/main.c8
-rw-r--r--sbin/sysinstall/stage2.c53
-rw-r--r--sbin/sysinstall/stage3.c102
-rw-r--r--sbin/sysinstall/stage4.c79
-rw-r--r--sbin/sysinstall/stage5.c32
-rw-r--r--sbin/sysinstall/sysinstall.h12
-rw-r--r--sbin/sysinstall/utils.c53
10 files changed, 316 insertions, 124 deletions
diff --git a/sbin/sysinstall/Makefile b/sbin/sysinstall/Makefile
index 6407067..677bb62 100644
--- a/sbin/sysinstall/Makefile
+++ b/sbin/sysinstall/Makefile
@@ -4,12 +4,16 @@ NOMAN= yet
.PATH: /usr/src/sbin/disklabel
-SRCS = bootarea.c exec.c dkcksum.c label.c \
- main.c mbr.c stage0.c stage1.c \
- stage2.c stage3.c termcap.c utils.c
+SRCS = bootarea.c exec.c dkcksum.c label.c main.c mbr.c \
+ stage0.c stage1.c stage2.c stage3.c stage4.c stage5.c \
+ termcap.c utils.c makedevs.c
CFLAGS += -Wall
LDADD = -ldialog -lncurses -lmytinfo
DPADD = ${LIBDIALOG} ${LIBNCURSES} ${LIBMYTINFO}
+makedevs.c: dev2c.sh
+ sh ${.CURDIR}/dev2c.sh ${DESTDIR}/dev > makedevs.c ; \
+
.include <bsd.prog.mk>
+
diff --git a/sbin/sysinstall/dev2c.sh b/sbin/sysinstall/dev2c.sh
new file mode 100644
index 0000000..d395810
--- /dev/null
+++ b/sbin/sysinstall/dev2c.sh
@@ -0,0 +1,80 @@
+:
+#
+# ----------------------------------------------------------------------------
+# "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: stage3.c,v 1.4 1994/10/21 02:14:52 phk Exp $
+#
+# During installation, we suffer badly of we have to run MAKEDEV. MAKEDEV
+# need sh, ln, chown, mknod, awk, rm, test and probably emacs too when
+# we come down to it. So instead this script will make a C-procedure which
+# makes all the B & C nodes of a specified directory.
+#
+# Poul-Henning
+
+(cd $1; ls -li ) | sed 's/,//' | awk '
+BEGIN {
+ while (getline < "/etc/passwd") {
+ split($0,a,":")
+ uid[a[1]] = a[3]
+ }
+ while (getline < "/etc/group") {
+ split($0,a,":")
+ gid[a[1]] = a[3]
+ }
+ printf("/*\n");
+ printf(" * This file is generated from the contents of /dev\n");
+ printf(" */\n");
+ printf("#define CHK(foo) {i = foo;}\n");
+ printf("#include <unistd.h>\n");
+ printf("#include <sys/types.h>\n");
+ printf("#include <sys/stat.h>\n");
+ printf("int makedevs()\n{\n\tint i=0;\n");
+ }
+ {
+ printf ("/* %s */\n",$0)
+ $4 = uid[$4]
+ $5 = gid[$5]
+ if (substr($2,1,1) == "b") {
+ k="S_IFBLK"
+ } else if (substr($2,1,1) == "c") {
+ k="S_IFCHR"
+ } else if (substr($2,1,1) == "d") {
+ next
+ } else if (substr($2,1,1) == "-") {
+ next
+ } else {
+ next
+ }
+ m = 0;
+ if (substr($2,2,1) == "r") m += 400;
+ if (substr($2,3,1) == "w") m += 200;
+ if (substr($2,4,1) == "x") m += 100;
+ if (substr($2,5,1) == "r") m += 40;
+ if (substr($2,6,1) == "w") m += 20;
+ if (substr($2,7,1) == "x") m += 10;
+ if (substr($2,8,1) == "r") m += 4;
+ if (substr($2,9,1) == "w") m += 2;
+ if (substr($2,10,1) == "x") m += 1;
+
+ if (a[$1] != 0) {
+ printf ("\tCHK(link(\"%s\",\"%s\"));\n", \
+ a[$1],$11)
+ } else {
+ printf ("\tCHK(mknod(\"%s\",%s,makedev(%d,%d)));\n", \
+ $11, k, $6, $7)
+ printf ("\tCHK(chmod(\"%s\",0%d));\n", \
+ $11, m)
+ printf ("\tCHK(chown(\"%s\",%d,%d));\n", \
+ $11, $4,$5)
+ a[$1] = $11
+ }
+ }
+END {
+ printf("\treturn i;\n}\n");
+ }
+'
diff --git a/sbin/sysinstall/exec.c b/sbin/sysinstall/exec.c
index 793ff30..b4d6780 100644
--- a/sbin/sysinstall/exec.c
+++ b/sbin/sysinstall/exec.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: exec.c,v 1.1 1994/10/21 02:14:49 phk Exp $
+ * $Id: exec.c,v 1.2 1994/10/21 05:36:42 phk Exp $
*
*/
@@ -35,7 +35,6 @@ exec(int magic, char *cmd, char *args, ...)
int arg = 0;
va_list ap;
struct stat dummy;
- int i;
if (stat(cmd, &dummy) == -1) {
sprintf(errmsg, "Executable %s does not exist\n", cmd);
@@ -58,14 +57,8 @@ exec(int magic, char *cmd, char *args, ...)
close(2); open("/dev/null",O_WRONLY);
break;
case 1:
- close(0);
- i = open("/file.list",O_RDONLY);
- if (i != 0) {
- perror("Couldn't open /etc/file.list");
- }
- close(1); open("/dev/null",O_WRONLY);
- close(2); open("/dev/null",O_WRONLY);
break;
+ close(2); open("/dev/null",O_WRONLY);
default:
break;
}
diff --git a/sbin/sysinstall/main.c b/sbin/sysinstall/main.c
index 05cb167..20b3b94 100644
--- a/sbin/sysinstall/main.c
+++ b/sbin/sysinstall/main.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: main.c,v 1.6 1994/10/21 02:14:50 phk Exp $
+ * $Id: main.c,v 1.7 1994/10/24 03:30:55 paul Exp $
*
*/
@@ -98,10 +98,10 @@ main(int argc, char **argv)
stage1();
stage2();
reboot(RB_AUTOBOOT);
- } else if (getenv("STAGE3") || !access("/this_is_hd",R_OK)) {
- stage3();
} else {
- Fatal("Must setenv STAGE0 or STAGE3");
+ stage3();
+ stage4();
+ stage5();
}
return 0;
}
diff --git a/sbin/sysinstall/stage2.c b/sbin/sysinstall/stage2.c
index f48b8e1..5624632 100644
--- a/sbin/sysinstall/stage2.c
+++ b/sbin/sysinstall/stage2.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: stage2.c,v 1.4 1994/10/21 02:14:51 phk Exp $
+ * $Id: stage2.c,v 1.5 1994/10/21 05:36:43 phk Exp $
*
*/
@@ -33,7 +33,7 @@ stage2()
char **p,**q;
char pbuf[90];
char dbuf[90];
- FILE *f1, *f2;
+ FILE *f1;
int i;
for(q=mountpoint,p = devicename; *p; p++,q++) {
@@ -42,37 +42,45 @@ stage2()
TellEm("newfs /dev/r%s",*p);
strcpy(pbuf, "/dev/r");
strcat(pbuf, *p);
- i = exec(0, "/bin/newfs", "/bin/newfs", pbuf, 0);
+ i = exec(0, "/stand/newfs", "/stand/newfs", pbuf, 0);
if (i)
- TellEm("Exec(/bin/newfs) failed, code=%d.",i);
+ Fatal("Exec(/stand/newfs) failed, code=%d.",i);
}
for(q=mountpoint,p = devicename; *p; p++,q++) {
if(!strcmp(*q,"swap"))
continue;
- MountUfs(*p, "/mnt", *q, 1);
+ strcpy(dbuf,"/mnt");
+ if(strcmp(*q,"/"))
+ strcat(dbuf,*q);
+ MountUfs(*p, dbuf, 1, 0);
}
- TellEm("cpio -dumpv /mnt < file.list");
- i = exec(1, "/bin/cpio", "/bin/cpio", "-dumpv", "/mnt", 0);
- if (i)
- Fatal("Exec(/bin/cpio) failed, code=%d.",i);
+ Mkdir("/mnt/etc");
+ Mkdir("/mnt/dev");
+ Mkdir("/mnt/mnt");
+ Mkdir("/mnt/stand");
+
+ CopyFile("/stand/sysinstall","/mnt/stand/sysinstall");
+ link("/mnt/stand/sysinstall","/mnt/stand/cpio");
+ link("/mnt/stand/sysinstall","/mnt/stand/gunzip");
+ link("/mnt/stand/sysinstall","/mnt/stand/newfs");
+ link("/mnt/stand/sysinstall","/mnt/stand/fsck");
+ CopyFile("/kernel","/mnt/kernel");
+ TellEm("make /dev entries");
+ chdir("/mnt/dev");
+ makedevs();
+ chdir("/");
TellEm("Making /mnt/etc/fstab");
f1 = fopen("/mnt/etc/fstab","w");
if(!f1)
Fatal("Couldn't open /mnt/etc/fstab for writing.");
- /* This file is our own. It serves several jobs */
- f2 = fopen("/mnt/this_is_hd","w");
- if(!f2)
- Fatal("Couldn't open /mnt/this_is_hd for writing.");
-
TellEm("Writing filesystems");
for(q=mountpoint,p = devicename; *p; p++,q++) {
if(!strcmp(*q,"swap"))
continue;
- fprintf(f2,"%s\n%s\n",*p,*q);
fprintf(f1,"/dev/%s\t\t%s\tufs rw 1 1\n",*p,*q);
}
TellEm("Writing swap-devs");
@@ -84,21 +92,26 @@ stage2()
TellEm("Writing procfs");
fprintf(f1,"proc\t\t/proc\tprocfs rw 0 0\n");
fclose(f1);
- fclose(f2);
+ sync();
+ TellEm("Make marker-file");
+ i = open("/mnt/stand/need_cpio_floppy",O_CREAT|O_WRONLY|O_TRUNC);
+ close(i);
+
/* we have to unmount in reverse order */
for(p = mountpoint; *p; p++)
continue;
+
TellEm("Unmount disks");
-
for(p--;p >= mountpoint;p--) {
if(!strcmp(*p,"swap"))
continue;
strcpy(dbuf,"/mnt");
- strcat(dbuf,*p);
+ if(strcmp(*p,"/"))
+ strcat(dbuf,*p);
TellEm("unmount %s",dbuf);
- if (unmount(dbuf, 0) == -1)
- Fatal("Error unmounting %s.",dbuf);
+ /* Don't do error-check, we reboot anyway... */
+ unmount(dbuf, 0);
}
dialog_msgbox(TITLE,"Remove the floppydisk from the drive, and hit return to reboot from the harddisk",6, 75, 1);
}
diff --git a/sbin/sysinstall/stage3.c b/sbin/sysinstall/stage3.c
index be6b267..5cb46e9 100644
--- a/sbin/sysinstall/stage3.c
+++ b/sbin/sysinstall/stage3.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: stage3.c,v 1.3 1994/10/20 19:30:53 ache Exp $
+ * $Id: stage3.c,v 1.4 1994/10/21 02:14:52 phk Exp $
*
*/
@@ -17,91 +17,49 @@
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
+#include <fstab.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/stat.h>
-#if 0
-#include <sys/types.h>
-#include <sys/disklabel.h>
-#include <sys/ioctl.h>
-#include <sys/reboot.h>
-#include <sys/wait.h>
-#include "bootarea.h"
-#include <ufs/ffs/fs.h>
-#endif
-
#include "sysinstall.h"
void
stage3()
{
- char pbuf[90];
- char dbuf[90];
- FILE *f;
+ char pbuf[90],*p;
+ int mountflags;
+ struct fstab *fs;
/*
- * Extract the disk-name from /etc/fstab, we wrote it ourselves,
- * so we know how to read it :-)
- * XXX: Multidisk installs. We need to mount all partitions.
+ * Mount things in /etc/fstab we like.
*/
- f = fopen("/this_is_hd","r");
- if (!f) {
- Fatal("Couldn't open /this_is_hd");
- }
- while(fgets(dbuf,sizeof pbuf, f)) {
- dbuf[strlen(dbuf)-1] = 0;
- fgets(pbuf,sizeof pbuf, f);
- pbuf[strlen(pbuf)-1] = 0;
- MountUfs(dbuf,0,pbuf,0);
- }
- fclose(f);
-
- Mkdir("/proc");
- Mkdir("/root");
- Mkdir("/var");
- Mkdir("/var/run");
-
- sprintf(scratch, "Insert CPIO floppy in floppy drive 0\n");
- dialog_msgbox("Stage 2 installation", scratch, 6, 75, 1);
+ mountflags = MNT_UPDATE;
+ while((fs = getfsent()) != NULL) {
+ if (strcmp(fs->fs_vfstype,"ufs")) continue;
+ p = fs->fs_spec;
+ if (*p++ != '/') continue;
+ if (*p++ != 'd') continue;
+ if (*p++ != 'e') continue;
+ if (*p++ != 'v') continue;
+ if (*p++ != '/') continue;
+ if (!strcmp(fs->fs_type,"ro"))
+ mountflags |= MNT_RDONLY;
+ else if (!strcmp(fs->fs_type,"rw"))
+ ;
+ else
+ continue;
+ strcpy(pbuf,"/dev/r");
+ strcat(pbuf,p);
+ TellEm("fsck -y %s",pbuf);
+ if (exec(0, "/stand/fsck",
+ "/stand/fsck", "-y", pbuf, 0) == -1)
+ Fatal(errmsg);
- MountUfs("/dev/fd0a",0,"/mnt",0);
- TellEm("sh -c 'cd / ; gunzip < /mnt/inst2.cpio.gz | cpio -idum'");
-
- if (exec(0, "/bin/sh",
- "/bin/sh", "-e", "-c",
- "cd / ; gunzip < /mnt/inst2.cpio.gz | cpio -idum", 0) == -1)
- Fatal(errmsg);
-
- TellEm("sh -c 'cd /mnt ; ls install magic | cpio -dump /'");
-
- if (exec(0, "/bin/sh",
- "/bin/sh", "-e", "-c",
- "cd /mnt ; ls magic | cpio -dump /", 0) == -1)
- Fatal(errmsg);
-
- TellEm("unmount /mnt");
- if (unmount("/mnt", 0) == -1) {
- sprintf(errmsg, "Error unmounting /mnt: %s\n", strerror(errno));
- Fatal(errmsg);
+ MountUfs(p,fs->fs_file,0,mountflags);
+ mountflags = 0;
}
- TellEm("sh -c 'cd /dev ; sh MAKEDEV all'");
- if (exec(0, "/bin/sh",
- "/bin/sh", "-e", "-c",
- "PATH=/bin:/sbin:/usr/bin:/usr/sbin; export PATH ; cd /dev ; sh MAKEDEV all", 0) == -1)
- Fatal(errmsg);
-
- TellEm("unlink /sbin/oinit");
- unlink("/sbin/oinit");
- TellEm("link /stand/sysinstall /sbin/init");
- link("/stand/sysinstall", "/sbin/init");
- dialog_clear();
- dialog_update();
- end_dialog();
- close(0);
- close(1);
- close(2);
- execl(0,"/sbin/init", "init", 0);
+ endfsent();
}
diff --git a/sbin/sysinstall/stage4.c b/sbin/sysinstall/stage4.c
new file mode 100644
index 0000000..b3af167
--- /dev/null
+++ b/sbin/sysinstall/stage4.c
@@ -0,0 +1,79 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "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: stage3.c,v 1.4 1994/10/21 02:14:52 phk Exp $
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dialog.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "sysinstall.h"
+
+void
+stage4()
+{
+ int ffd,pfd[2];
+ int zpid,cpid;
+ int i,j;
+
+ if (access("/stand/need_cpio_floppy",R_OK))
+ return;
+
+ while (1) {
+ dialog_msgbox(TITLE,
+ "Insert CPIO floppy in floppy drive 0", 6, 75, 1);
+ ffd = open("/dev/fd0a",O_RDONLY);
+ if(ffd > 0)
+ break;
+ }
+ TellEm("cd /stand ; gunzip < /dev/fd0 | cpio -icdum");
+ pipe(pfd);
+ zpid = fork();
+ if(!zpid) {
+ close(0); dup(ffd); close(ffd);
+ close(1); dup(pfd[1]); close(pfd[1]);
+ close(pfd[0]);
+ i = exec (1,"/stand/gunzip","/stand/gunzip", 0);
+ exit(i);
+ }
+ cpid = fork();
+ if(!cpid) {
+ close(0); dup(pfd[0]); close(pfd[0]);
+ close(ffd);
+ close(pfd[1]);
+ close(1); open("/dev/null",O_WRONLY);
+ chdir("/stand");
+ i = exec (1,"/stand/cpio","/stand/cpio","-icdum", 0);
+ exit(i);
+ }
+ close(pfd[0]);
+ close(pfd[1]);
+ close(ffd);
+ i = wait(&j);
+ if(i < 0 || j)
+ Fatal("Pid %d, status %d, cpio=%d, gunzip=%d.\nerror:%s",
+ i,j,cpid,zpid,strerror(errno));
+ i = wait(&j);
+ if(i < 0 || j)
+ Fatal("Pid %d, status %d, cpio=%d, gunzip=%d.\nerror:%s",
+ i,j,cpid,zpid,strerror(errno));
+
+ unlink("/stand/need_cpio_floppy");
+}
diff --git a/sbin/sysinstall/stage5.c b/sbin/sysinstall/stage5.c
new file mode 100644
index 0000000..d6f9c3f
--- /dev/null
+++ b/sbin/sysinstall/stage5.c
@@ -0,0 +1,32 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "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: stage3.c,v 1.4 1994/10/21 02:14:52 phk Exp $
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dialog.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+
+#include "sysinstall.h"
+
+void
+stage5()
+{
+ for(;;)
+ exec (1,"/stand/sh","/stand/-sh", 0);
+}
diff --git a/sbin/sysinstall/sysinstall.h b/sbin/sysinstall/sysinstall.h
index a1efd3f..9cb44b4 100644
--- a/sbin/sysinstall/sysinstall.h
+++ b/sbin/sysinstall/sysinstall.h
@@ -54,8 +54,9 @@ void *Malloc __P((size_t size));
char *StrAlloc __P((char *str));
void Fatal __P((char *fmt, ...));
void AskAbort __P((char *fmt, ...));
-void MountUfs __P((char *device, char *prefix, char *mountpoint, int do_mkdir));
+void MountUfs __P((char *device, char *mountpoint, int do_mkdir,int flags));
void Mkdir __P((char *path));
+void CopyFile __P((char *p1, char *p2));
/* exec.c */
int exec __P((int magic, char *cmd, char *args, ...));
@@ -73,5 +74,14 @@ void stage2 __P((void));
/* stage3.c */
void stage3 __P((void));
+/* stage4.c */
+void stage4 __P((void));
+
+/* stage5.c */
+void stage5 __P((void));
+
/* termcap.c */
int set_termcap __P((void));
+
+/* makedevs.c */
+int makedevs __P((void));
diff --git a/sbin/sysinstall/utils.c b/sbin/sysinstall/utils.c
index 16f2964..d81dfd7 100644
--- a/sbin/sysinstall/utils.c
+++ b/sbin/sysinstall/utils.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: utils.c,v 1.10 1994/10/22 02:37:24 ache Exp $
+ * $Id: utils.c,v 1.11 1994/10/24 03:55:25 ache Exp $
*
*/
@@ -18,6 +18,7 @@
#include <dialog.h>
#include <errno.h>
+#include <sys/file.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -134,33 +135,25 @@ StrAlloc(char *str)
}
void
-MountUfs(char *device, char *prefix, char *mountpoint, int do_mkdir)
+MountUfs(char *device, char *mountpoint, int do_mkdir, int flags)
{
struct ufs_args ufsargs;
char dbuf[90];
- char pbuf[90];
memset(&ufsargs,0,sizeof ufsargs);
- if (prefix)
- strcpy(pbuf,prefix);
- else
- strcpy(pbuf,"");
-
- strcat(pbuf,mountpoint);
-
- if(do_mkdir && access(pbuf,R_OK)) {
- Mkdir(pbuf);
+ if(do_mkdir && access(mountpoint,R_OK)) {
+ Mkdir(mountpoint);
}
strcpy(dbuf,"/dev/");
strcat(dbuf,device);
- TellEm("mount /dev/%s /mnt%s",dbuf,pbuf);
+ TellEm("mount %s %s",dbuf,mountpoint);
ufsargs.fspec = dbuf;
- if (mount(MOUNT_UFS,pbuf, 0, (caddr_t) &ufsargs) == -1) {
+ if (mount(MOUNT_UFS, mountpoint, flags, (caddr_t) &ufsargs) == -1) {
Fatal("Error mounting %s on %s : %s\n",
- dbuf, pbuf, strerror(errno));
+ dbuf, mountpoint, strerror(errno));
}
}
@@ -173,3 +166,33 @@ Mkdir(char *path)
path,strerror(errno));
}
}
+
+void
+CopyFile(char *p1, char *p2)
+{
+ char buf[BUFSIZ];
+ int fd1,fd2;
+ int i;
+ struct stat st;
+
+ TellEm("Copy %s to %s",p1,p2);
+ fd1 = open(p1,O_RDONLY);
+ if (fd1 < 0) Fatal("Couldn't open %s: %s\n",p1,strerror(errno));
+ fd2 = open(p2,O_TRUNC|O_CREAT|O_WRONLY,0200);
+ if (fd2 < 0) Fatal("Couldn't open %s: %s\n",p2,strerror(errno));
+ for(;;) {
+ i = read(fd1,buf,sizeof buf);
+ if (i > 0)
+ if (i != write(fd2,buf,i)) {
+ Fatal("Write errror on %s: %s\n",
+ p2,strerror(errno));
+ }
+ if (i != sizeof buf)
+ break;
+ }
+ fstat(fd1,&st);
+ fchmod(fd2,st.st_mode & 07777);
+ fchown(fd2,st.st_uid,st.st_gid);
+ close(fd1);
+ close(fd2);
+}
OpenPOWER on IntegriCloud