home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d0xx / d050 / unixarc.lha / UnixArc / arcunix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-01-17  |  6.7 KB  |  302 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <sys/errno.h>
  6. #include <time.h>
  7. #include "arc.h"
  8.  
  9. char *index(), *rindex(), *xalloc(), *malloc(), *realloc();
  10. extern char *Progname;
  11. extern int nerrs;
  12.  
  13. #if m68000
  14. typedef long int dos_long_t;
  15. typedef short int dos_int_t;
  16. #define doshdrsize (FNLEN + sizeof(dos_long_t) + sizeof(dos_int_t) + \
  17.         sizeof(dos_int_t) + sizeof(dos_int_t) + sizeof(dos_long_t))
  18. #define odoshdrsize (doshdrsize - sizeof(dos_long_t))
  19. #define dos2long(x) ((unsigned char)(x)[0] + ((unsigned char)(x)[1]<<8) + \
  20.         ((unsigned char)(x)[2]<<16) + ((unsigned char)(x)[3]<<24))
  21. #define dos2int(x) (0xffff & ((unsigned char)(x)[0]+((unsigned char)(x)[1]<<8)))
  22. #define long2dos(x,l) ((x)[0]=(char)((l)&0xff), (x)[1]=(char)((l)>>8&0xff),\
  23.         (x)[2]=(char)((l)>>16&0xff), (x)[3]=(char)((l)>>24&0xff))
  24. #define int2dos(x,i) ((x)[0]=(char)((i)&0xff), (x)[1]=(char)((i)>>8&0xff))
  25.  
  26. /* urdhdr -- read a new-style dos header; munge to unix header */
  27. urdhdr(hdr,f)
  28. struct heads *hdr;
  29. FILE *f;
  30. {
  31.     _urdhdr(hdr,f,doshdrsize);
  32. }
  33. /* urdohdr -- read an old-style dos header; munge to unix header */
  34. urdohdr(hdr,f)
  35. struct heads *hdr;
  36. FILE *f;
  37. {
  38.     _urdhdr(hdr,f,odoshdrsize);
  39. }
  40. static _urdhdr(hdr,f,size)
  41. struct heads *hdr;
  42. FILE *f;
  43. int size;
  44. {
  45.     char doshdr[doshdrsize];
  46.     char *s = doshdr;
  47.  
  48.     fread(doshdr,size,1,f);
  49.     memcpy(hdr->name,s,sizeof(hdr->name)); s += FNLEN;
  50. /*printf("\nurdhdr: name=0x%x,'%.12s'0x%x",doshdr,hdr->name,s);*/
  51.     hdr->size = dos2long(s);    s += sizeof(dos_long_t);
  52. /*printf(" size=%ld,0x%x",hdr->size,s);*/
  53.     hdr->date = dos2int(s);        s += sizeof(dos_int_t);
  54. /*printf(" date=%d,0x%x",hdr->date,s);*/
  55.     hdr->time = dos2int(s);        s += sizeof(dos_int_t);
  56. /*printf(" time=%d,0x%x",hdr->time,s);*/
  57.     hdr->crc = dos2int(s);        s += sizeof(dos_int_t);
  58. /*printf(" crc=%d,0x%x",hdr->crc,s);*/
  59.     if(size == doshdrsize)        hdr->length = dos2long(s);
  60. /*if(size == doshdrsize) printf(" length=%d\n",hdr->length);*/
  61. }
  62. /* uwrhdr -- write a dos header; munge from unix header */
  63. uwrhdr(hdr,f)
  64. struct heads *hdr;
  65. FILE *f;
  66. {
  67.     char doshdr[doshdrsize];
  68.     char *s = doshdr;
  69.  
  70.     memcpy(s,hdr->name,FNLEN);    s += FNLEN;
  71.     long2dos(s, hdr->size);        s += sizeof(dos_long_t);
  72.     int2dos(s, hdr->date);        s += sizeof(dos_int_t);
  73.     int2dos(s, hdr->time);        s += sizeof(dos_int_t);
  74.     int2dos(s, hdr->crc);        s += sizeof(dos_int_t);
  75.     long2dos(s, hdr->length);    s += sizeof(dos_long_t);
  76.     fwrite(doshdr,sizeof(doshdr),1,f);
  77. }
  78. #endif
  79.  
  80. /*
  81.  * makefnam -- replace any extension in base with extension in ext, save in buf
  82.  */
  83. char *makefnam(base,ext,buf)
  84. char *base,*ext,*buf;
  85. {
  86.     char *s;
  87.     strcpy(buf, base);
  88.     if((base = rindex(buf, '/')) == NULL)
  89.         base = buf;
  90.     if((s = index(base,'.')) != NULL) *s = '\0';
  91.     if((s = rindex(ext,'.')) != NULL) strcat(buf,s);
  92.     else {
  93.         strcat(buf,".");strcat(buf,ext);
  94.     }
  95.     return(buf);
  96. }
  97.  
  98. char *lower(str)
  99. char *str;
  100. {
  101.     char *s;
  102.     for(s = str; *s; ++s)
  103.         if(isupper(*s)) *s = tolower(*s);
  104.     return(str);
  105. }
  106.  
  107. char *upper(str)
  108. char *str;
  109. {
  110.     char *s;
  111.     for(s = str; *s; ++s)
  112.         if(islower(*s)) *s = toupper(*s);
  113.     return(str);
  114. }
  115.  
  116. /*
  117.  * kludge; assume we wont run out of memory
  118.  */
  119. unsigned coreleft()
  120. {
  121.     return(5120);    /* always enough */
  122. }
  123.  
  124. /*
  125.  * dir -- glob pattern, if speced, and repeatedly return matches
  126.  * NOTE: return nulstr, NOT NULL, on no match
  127.  */
  128. char *dir(pattern,mode)               /* get files, one by one */
  129. char *pattern;                        /* template, or NULL */
  130. int mode;                              /* search mode bits */
  131. {
  132.     static FILE *fp = NULL;
  133.     static char nulstr[] = "";
  134.     static char buf[1025];
  135.     char *s, *fgets();
  136.     extern FILE *popen();
  137.  
  138.     if(fp == NULL && pattern == NULL)
  139.         return(nulstr);
  140.     if (pattern) {
  141.         if(fp) pclose(fp);
  142.         sprintf(buf,"echo %s | tr ' ' '\012'",pattern);
  143.         fp = popen(buf,"r");
  144.         if (fp == NULL)
  145.             abort("dir(): cant glob %s",pattern);
  146.     }
  147.     if(fgets(buf,sizeof(buf),fp) == NULL) {
  148.         pclose(fp);
  149.         fp = NULL;
  150.         return(nulstr);
  151.     }
  152.     if((s = index(buf,'\n')) != NULL) *s = '\0';
  153.     if((s = rindex(buf,'/')) == NULL)
  154.         s = buf;
  155.     else
  156.         ++s;
  157.     if(legalize(s))
  158.         return(nulstr);
  159.     pattern = xalloc(strlen(s)+1);
  160.     strcpy(pattern, s);
  161.     return(pattern);
  162. }
  163.  
  164. static legalize(name)
  165. char *name;
  166. {
  167.     char *dot = index(name,'.');
  168.     if(dot && ((dot-name > 8) || index(dot+1,'.'))) {
  169.         fprintf(stderr,"%s: unix name '%s' not legal as dos name; skipping this pattern\n",Progname,name);
  170.         ++nerrs;
  171.         return(1);
  172.     }
  173.     if((dot && strlen(dot+1) > 3) ||
  174.       (!dot && strlen(name) > 12)) {
  175. truncate:
  176.         fprintf(stderr,"%s: Warning: truncating name '%s' to ",Progname,name);
  177.         if(dot) dot[4] = '\0';
  178.         else name[12] = '\0';
  179.         fprintf(stderr,"'%s'\n",name);
  180.     }
  181.     return(0);
  182. }
  183.  
  184. setmem(buf,len,c)
  185. char *buf,c;
  186. int len;
  187. {
  188.     while(len--)
  189.         *buf++ = c;
  190. }
  191.  
  192. rename(from, to)
  193. char *from, *to;
  194. {
  195.     if(link(from, to))
  196.         return(-1);
  197.     return(unlink(from));
  198. }
  199.  
  200. /*
  201.  * setstamp -- convert dos time to unix tm and update access, modify times
  202.  */
  203. setstamp(path,date,time)                  /* set a file's date/time stamp */
  204. char *path;                               /* file to set stamp on */
  205. unsigned int date, time;               /* desired date, time */
  206. {
  207.     extern time_t tm_to_time ();
  208.     struct tm t;
  209.     struct {
  210.     time_t a,m;
  211.     } ut;
  212.  
  213.     int yr = (date >> 9) & 0x7f;      /* dissect the date */
  214.     int mo = (date >> 5) & 0x0f;
  215.     int dy = date & 0x1f;
  216.  
  217.     int hr = (time >> 11) & 0x1f;     /* dissect the time */
  218.     int mm = (time >> 5) & 0x3f;
  219.     int ss = (time & 0x1f) * 2;
  220.  
  221.     t.tm_year = (yr + 80) % 100;
  222.     t.tm_mon = mo - 1;
  223.     t.tm_mday = dy;
  224.     t.tm_hour = hr;
  225.     t.tm_min = mm;
  226.     t.tm_sec = ss;
  227.     ut.a = ut.m = tm_to_time(&t);
  228.     if(utime(path, &ut)) {
  229.         fprintf(stderr, "%s: cant set utime ",Progname);
  230.         perror(path);
  231.     }
  232. }
  233.  
  234. /*
  235.  * setstamp -- get modify time and convert dos time
  236.  */
  237. getstamp(path,date,time)                  /* get a file's date/time stamp */
  238. char *path;                               /* file to get stamp from */
  239. unsigned int *date, *time;                /* storage for the stamp */
  240. {
  241.     struct stat sbuf;
  242.     if(stat(path, &sbuf)) {
  243.         fprintf(stderr, "%s: cant stat ",Progname);
  244.         perror(path);
  245.         *date = *time = 0;
  246.     }
  247.     else {
  248.         struct tm *localtime();
  249.         struct tm *t = localtime(&sbuf.st_mtime);
  250.         int yr = t->tm_year - 80;
  251.         int mo = t->tm_mon + 1;
  252.         int dy = t->tm_mday;
  253.         int hr = t->tm_hour;
  254.         int mm = t->tm_min;
  255.         int ss = t->tm_sec;
  256.         *date = (yr<<9)+(mo<<5)+dy;
  257.         *time = (hr<<11)+(mm<<5)+ss;
  258.     }
  259. }
  260.  
  261. /*
  262.  * xalloc -- malloc with error checking
  263.  */
  264. char *xalloc(n)
  265. unsigned n;
  266. {
  267.     char *s = malloc(n);
  268.     if(s == NULL)
  269.         outofmem();
  270.     return(s);
  271. }
  272.  
  273. /*
  274.  * xrealloc -- realloc with error checking
  275.  */
  276. char *xrealloc(s,n)
  277. char *s;
  278. unsigned n;
  279. {
  280.     s = realloc(s,n);
  281.     if(s == NULL)
  282.         outofmem();
  283.     return(s);
  284. }
  285. static outofmem()
  286. {
  287.     Fatal("out of memory",ENOMEM);
  288. }
  289. static Fatal(s,code)
  290. char *s;
  291. int code;
  292. {
  293.     fprintf(stderr,"\n%s: fatal error\n%s\n",Progname,s);
  294.     exit(code);
  295. }
  296. abort(a,b,c,d,e)
  297. {
  298.     char buf[100];
  299.     sprintf(buf,a,b,c,d,e);
  300.     Fatal(buf,1);
  301. }
  302.