home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / CLISP / CLISPSRC.TAR / clisp-1995-01-01 / utils / charset / fromdos.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-23  |  4.8 KB  |  160 lines

  1. /* Conversion utility CR/LF -> NL */
  2. /* multiple files, in place, restores write date */
  3. /* Bruno Haible 23.1.1994 */
  4. /* Make:  gcc -O2 -fomit-frame-pointer -N -o fromdos fromdos.c  */
  5.  
  6. #include <sys/types.h>
  7. #include <unistd.h> /* open, read, write, close, lseek, ftruncate */
  8. #include <fcntl.h> /* O_RDONLY, O_RDWR */
  9. #include <sys/stat.h> /* fstat */
  10. #include <sys/time.h> /* struct timeval, utimes */
  11. #include <errno.h> /* EINTR, perror */
  12.  
  13. #define CR 13
  14. #define LF 10
  15. #define NL 10
  16. #define BUFLEN 4096
  17.  
  18. int full_read (int fd, char* buf, size_t nbyte);
  19. int full_write (int fd, char* buf, size_t nbyte);
  20.  
  21. int main (int argc, char* argv[])
  22. { int i;
  23.   for (i=1; i<argc; i++)
  24.     { char* filename = argv[i];
  25.       /* open filename twice so that there is no need to lseek */
  26.       int rfd = open(filename,O_RDONLY);
  27.       if (rfd<0) { perror(filename); goto next; }
  28.      {struct stat statbuf;
  29.       if (fstat(rfd,&statbuf)<0) { perror(filename); goto next; }
  30.       { int wfd = open(filename,O_RDWR);
  31.         if (wfd<0) { perror(filename); close(rfd); goto next; }
  32.         { char buffer[BUFLEN];
  33.           char* bufend = &buffer[BUFLEN];
  34.           register char* srcptr = &buffer[0];
  35.           register char* destptr;
  36.           while (1) /* srcptr is either &buffer[0] or &buffer[1] here */
  37.             { register int count = full_read(rfd,srcptr,bufend-srcptr);
  38.               if (count < 0)
  39.                 { perror(filename); close(wfd); close(rfd); goto next; }
  40.               if (count == 0) break; /* EOF */
  41.               count += (srcptr - &buffer[0]);
  42.               destptr = srcptr = &buffer[0];
  43.               do /* srcptr + count remains constant, destptr<=srcptr, count>0 */
  44.                  { if (*srcptr == CR)
  45.                      { if (count > 1)
  46.                          { if (srcptr[1] == LF)
  47.                              { *destptr++ = NL; srcptr += 2; count -= 2; }
  48.                              else
  49.                              { *destptr++ = *srcptr++; count--; }
  50.                          }
  51.                          else
  52.                          break; /* CR at the end of the buffer -> finish loop */
  53.                      }
  54.                      else
  55.                      { *destptr++ = *srcptr++; count--; }
  56.                  }
  57.                  while (count > 0);
  58.               /* count = 0 or = 1 here */
  59.               if (full_write(wfd,buffer,destptr-buffer) < 0)
  60.                 { perror(filename); close(wfd); close(rfd); goto next; }
  61.               if (count > 0)
  62.                 { buffer[0] = *srcptr; srcptr = &buffer[1]; }
  63.                 else
  64.                 { srcptr = &buffer[0]; }
  65.             }
  66.           if (srcptr!=buffer)
  67.             { if (full_write(wfd,buffer,srcptr-buffer) < 0)
  68.                 { perror(filename); close(wfd); close(rfd); goto next; }
  69.             }
  70.         }
  71.         { off_t length = lseek(wfd,0,SEEK_CUR);
  72.           if (length < 0)
  73.             { perror(filename); close(wfd); close(rfd); goto next; }
  74.           if (ftruncate(wfd,length) < 0)
  75.             { perror(filename); close(wfd); close(rfd); goto next; }
  76.         }
  77.         close(wfd);
  78.       }
  79.       close(rfd);
  80.       /* reset the access and modification times */
  81.       { struct timeval tv[2];
  82.         tv[0].tv_sec = statbuf.st_atime; tv[0].tv_usec = 0;
  83.         tv[1].tv_sec = statbuf.st_mtime; tv[1].tv_usec = 0;
  84.         if (utimes(filename,tv) < 0) { perror(filename); goto next; }
  85.       }
  86.      }
  87.       next: ;
  88.     }
  89.   exit(0);
  90. }
  91.  
  92. /* On POSIX systems, read() and write() may return partial results without
  93.    failing.  Redefine the functions read() and write() such that they retry
  94.    whenever a partial result is received or the system call is interrupted
  95.    by a signal.
  96.    The function full_read and full_write behave like BSD read() and write():
  97.      on success, they return nbyte;
  98.      on EOF, they return 0;
  99.      on failure, they return a negative value and set errno.
  100. */
  101.  
  102. int full_read (fd, buf, nbyte)
  103.   int fd;
  104.   char *buf;
  105.   size_t nbyte;
  106. {
  107.   register int retval;
  108.   size_t done = 0;
  109.   while (nbyte > 0)
  110.     {
  111.       retval = read (fd, buf, nbyte);
  112.       if (retval == 0)
  113.         break;
  114.       else if (retval < 0)
  115.         {
  116. #ifdef EINTR
  117.           if (errno != EINTR)
  118. #endif
  119.             return retval;
  120.         }
  121.       else
  122.         {
  123.           buf += retval;
  124.           done += (size_t) retval;
  125.           nbyte -= (size_t) retval;
  126.         }
  127.     }
  128.   return done;
  129. }
  130.  
  131. int full_write (fd, buf, nbyte)
  132.   int fd;
  133.   char *buf;
  134.   size_t nbyte;
  135. {
  136.   register int retval;
  137.   size_t done = 0;
  138.   while (nbyte > 0)
  139.     {
  140.       retval = write (fd, buf, nbyte);
  141.       if (retval == 0)
  142.         break;
  143.       else if (retval < 0)
  144.         {
  145. #ifdef EINTR
  146.           if (errno != EINTR)
  147. #endif
  148.             return retval;
  149.         }
  150.       else
  151.         {
  152.           buf += retval;
  153.           done += (size_t) retval;
  154.           nbyte -= (size_t) retval;
  155.         }
  156.     }
  157.   return done;
  158. }
  159.  
  160.