New upstream version 2.20
[debian/cpmtools] / cpmcp.c
diff --git a/cpmcp.c b/cpmcp.c
index 7f1ff34a8184e446132a8c0d817a124dc4156355..561c451f51a439d4134e4a42b37d42a027965c9a 100644 (file)
--- a/cpmcp.c
+++ b/cpmcp.c
@@ -7,7 +7,6 @@
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
-#include <fcntl.h>
 #include <limits.h>
 #include <stdlib.h>
 #include <utime.h>
@@ -32,7 +31,7 @@ static int preserve=0;
 static int userNumber(const char *s) /*{{{*/
 {
   if (isdigit(*s) && *(s+1)==':') return (*s-'0');
-  if (isdigit(*s) && isdigit(*(s+1)) && *(s+2)==':') return (10*(*s-'0')+(*(s+1)));
+  if (isdigit(*s) && isdigit(*(s+1)) && *(s+2)==':') return (10*(*s-'0')+(*(s+1)-'0'));
   return -1;
 }
 /*}}}*/
@@ -64,7 +63,7 @@ static int cpmToUnix(const struct cpmInode *root, const char *src, const char *d
       int res;
       char buf[4096];
 
-      while ((res=cpmRead(&file,buf,sizeof(buf)))!=0)
+      while ((res=cpmRead(&file,buf,sizeof(buf)))>0)
       {
         int j;
 
@@ -93,6 +92,7 @@ static int cpmToUnix(const struct cpmInode *root, const char *src, const char *d
         }
       }
       endwhile:
+      if (res==-1 && !ohno) { fprintf(stderr,"%s: can not read %s (%s)\n",cmd,src,boo); exitcode=1; ohno=1; }
       if (fclose(ufp)==EOF && !ohno) { fprintf(stderr,"%s: can not close %s: %s\n",cmd,dest,strerror(errno)); exitcode=1; ohno=1; }
       if (preserve && !ohno && (ino.atime || ino.mtime))
       {
@@ -124,7 +124,7 @@ int main(int argc, char *argv[])
   /* variables */ /*{{{*/
   const char *err;
   const char *image;
-  const char *format=FORMAT;
+  const char *format;
   const char *devopts=NULL;
   int c,readcpm=-1,todir=-1;
   struct cpmInode root;
@@ -135,6 +135,7 @@ int main(int argc, char *argv[])
   /*}}}*/
 
   /* parse options */ /*{{{*/
+  if (!(format=getenv("CPMTOOLSFMT"))) format=FORMAT;
   while ((c=getopt(argc,argv,"T:f:h?pt"))!=EOF) switch(c)
   {
     case 'T': devopts=optarg; break;
@@ -177,10 +178,14 @@ int main(int argc, char *argv[])
   /* open image file */ /*{{{*/
   if ((err=Device_open(&super.dev,image,readcpm ? O_RDONLY : O_RDWR, devopts)))
   {
-    fprintf(stderr,"%s: can not open %s (%s)\n",cmd,image,err);
+    fprintf(stderr,"%s: cannot open %s (%s)\n",cmd,image,err);
+    exit(1);
+  }
+  if (cpmReadSuper(&super,&root,format)==-1)
+  {
+    fprintf(stderr,"%s: cannot read superblock (%s)\n",cmd,boo);
     exit(1);
   }
-  cpmReadSuper(&super,&root,format);
   /*}}}*/
   if (readcpm) /* copy from CP/M to UNIX */ /*{{{*/
   {
@@ -216,7 +221,7 @@ int main(int argc, char *argv[])
       FILE *ufp;
       /*}}}*/
 
-      if ((ufp=fopen(argv[i],"r"))==(FILE*)0) /* cry a little */ /*{{{*/
+      if ((ufp=fopen(argv[i],"rb"))==(FILE*)0) /* cry a little */ /*{{{*/
       {
         fprintf(stderr,"%s: can not open %s: %s\n",cmd,argv[i],strerror(errno));
         exitcode=1;
@@ -225,16 +230,19 @@ int main(int argc, char *argv[])
       else
       {
         struct cpmInode ino;
-        char cpmname[2+8+3+1]; /* 00foobarxy.zzy\0 */
+        char cpmname[2+8+1+3+1]; /* 00foobarxy.zzy\0 */
+        struct stat st;
+
+        stat(argv[i],&st);
 
         if (todir)
         {
           if ((dest=strrchr(argv[i],'/'))!=(char*)0) ++dest; else dest=argv[i];
-          sprintf(cpmname,"%02d%s",userNumber(argv[argc-1]),dest);
+          snprintf(cpmname,sizeof(cpmname),"%02d%s",userNumber(argv[argc-1]),dest);
         }
         else
         {
-          sprintf(cpmname,"%02d%s",userNumber(argv[argc-1]),strchr(argv[argc-1],':')+1);
+          snprintf(cpmname,sizeof(cpmname),"%02d%s",userNumber(argv[argc-1]),strchr(argv[argc-1],':')+1);
         }
         if (cpmCreat(&root,cpmname,&ino,0666)==-1) /* just cry */ /*{{{*/
         {
@@ -251,7 +259,7 @@ int main(int argc, char *argv[])
           cpmOpen(&ino,&file,O_WRONLY);
           do
           {
-            int j;
+            unsigned int j;
 
             for (j=0; j<(sizeof(buf)/2) && (c=getc(ufp))!=EOF; ++j)
             {
@@ -259,7 +267,7 @@ int main(int argc, char *argv[])
               buf[j]=c;
             }
             if (text && c==EOF) buf[j++]='\032';
-            if (cpmWrite(&file,buf,j)!=j)
+            if (cpmWrite(&file,buf,j)!=(ssize_t)j)
             {
               fprintf(stderr,"%s: can not write %s: %s\n",cmd,dest,boo);
               ohno=1;
@@ -273,6 +281,13 @@ int main(int argc, char *argv[])
             exitcode=1;
           }
           /*}}}*/
+          if (preserve && !ohno)
+          {
+            struct utimbuf times;
+            times.actime=st.st_atime;
+            times.modtime=st.st_mtime;
+            cpmUtime(&ino,&times);
+          }
         }
         fclose(ufp);
       }