#include <errno.h>
#include <stdio.h>
#include <string.h>
-#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>
-#include <utime.h>
+#include <time.h>
#include "getopt_.h"
#include "cpmfs.h"
-
-#ifdef USE_DMALLOC
-#include <dmalloc.h>
-#endif
/*}}}*/
const char cmd[]="cpmcp";
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;
}
/*}}}*/
{
int crpending=0;
int ohno=0;
- int res;
+ ssize_t res;
char buf[4096];
- while ((res=cpmRead(&file,buf,sizeof(buf)))!=0)
+ while ((res=cpmRead(&file,buf,sizeof(buf)))>0)
{
int j;
}
}
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))
{
/* variables */ /*{{{*/
const char *err;
const char *image;
- const char *format=FORMAT;
+ const char *format;
const char *devopts=NULL;
+ int uppercase=0;
int c,readcpm=-1,todir=-1;
struct cpmInode root;
struct cpmSuperBlock super;
/*}}}*/
/* parse options */ /*{{{*/
- while ((c=getopt(argc,argv,"T:f:h?pt"))!=EOF) switch(c)
+ if (!(format=getenv("CPMTOOLSFMT"))) format=FORMAT;
+ while ((c=getopt(argc,argv,"T:f:ptuh?"))!=EOF) switch(c)
{
case 'T': devopts=optarg; break;
case 'f': format=optarg; break;
- case 'h':
- case '?': usage(); break;
case 'p': preserve=1; break;
case 't': text=1; break;
+ case 'u': uppercase=1; break;
+ case 'h':
+ case '?': usage(); break;
}
/*}}}*/
/* parse arguments */ /*{{{*/
/* 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,uppercase)==-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 */ /*{{{*/
{
if (todir)
{
+ char *translate;
+
strcpy(dest,last);
strcat(dest,"/");
+ translate=dest+strlen(dest);
strcat(dest,gargv[i]+2);
+ while ((translate=strchr(translate,'/'))) *translate=',';
}
else strcpy(dest,last);
if (cpmToUnix(&root,gargv[i],dest)) exitcode=1;
{
struct cpmInode ino;
char cpmname[2+8+1+3+1]; /* 00foobarxy.zzy\0 */
+ char *translate;
+ 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);
}
+
+ translate=cpmname;
+ while ((translate=strchr(translate,','))) *translate='/';
+
if (cpmCreat(&root,cpmname,&ino,0666)==-1) /* just cry */ /*{{{*/
{
fprintf(stderr,"%s: can not create %s: %s\n",cmd,cpmname,boo);
cpmOpen(&ino,&file,O_WRONLY);
do
{
- int j;
+ ssize_t j;
- for (j=0; j<(sizeof(buf)/2) && (c=getc(ufp))!=EOF; ++j)
+ for (j=0; j<((ssize_t)sizeof(buf)/2) && (c=getc(ufp))!=EOF; ++j)
{
if (text && c=='\n') buf[j++]='\r';
buf[j]=c;
exitcode=1;
}
/*}}}*/
+ if (preserve && !ohno)
+ {
+ struct utimbuf times;
+ times.actime=st.st_atime;
+ times.modtime=st.st_mtime;
+ cpmUtime(&ino,×);
+ }
+ }
+ if (fclose(ufp)==EOF)
+ {
+ fprintf(stderr,"%s: can not close %s: %s\n",cmd,dest,strerror(errno));
+ exitcode=1;
}
- fclose(ufp);
}
}
}
/*}}}*/
- cpmUmount(&super);
+ if (cpmUmount(&super)==-1)
+ {
+ fprintf(stderr,"%s: can not umount device: %s\n",cmd,boo);
+ exitcode=1;
+ }
exit(exitcode);
}