1 #include <unistd.h> 2 #include <fcntl.h> 3 #include <stdio.h> 4 #include <string.h> 5 #include <stdlib.h> 6 #include <sys/stat.h> 7 8 #define BUFSIZE (1024*8) 9 static void to_unix(char* buf); 10 static void unix_to_dos(char* buf2, const char* buf); 11 12 int usage() 13 { 14 fprintf(stderr, "usage: line_endings unix|dos FILES\n" 15 "\n" 16 "Convert FILES to either unix or dos line endings.\n"); 17 return 1; 18 } 19 20 typedef struct Node { 21 struct Node *next; 22 char buf[BUFSIZE*2+3]; 23 } Node; 24 25 int 26 main(int argc, char** argv) 27 { 28 enum { UNIX, DOS } ending; 29 int i; 30 31 if (argc < 2) { 32 return usage(); 33 } 34 35 if (0 == strcmp("unix", argv[1])) { 36 ending = UNIX; 37 } 38 else if (0 == strcmp("dos", argv[1])) { 39 ending = DOS; 40 } 41 else { 42 return usage(); 43 } 44 45 for (i=2; i<argc; i++) { 46 int fd; 47 int len; 48 49 // force implied 50 chmod(argv[i], S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP); 51 52 fd = open(argv[i], O_RDWR); 53 if (fd < 0) { 54 fprintf(stderr, "unable to open file for read/write: %s\n", argv[i]); 55 return 1; 56 } 57 58 len = lseek(fd, 0, SEEK_END); 59 lseek(fd, 0, SEEK_SET); 60 61 if (len > 0) { 62 Node* root = malloc(sizeof(Node)); 63 Node* node = root; 64 node->buf[0] = 0; 65 66 while (len > 0) { 67 node->next = malloc(sizeof(Node)); 68 node = node->next; 69 node->next = NULL; 70 71 char buf[BUFSIZE+2]; 72 ssize_t amt; 73 ssize_t amt2 = len < BUFSIZE ? len : BUFSIZE; 74 amt = read(fd, buf, amt2); 75 if (amt != amt2) { 76 fprintf(stderr, "unable to read file: %s\n", argv[i]); 77 return 1; 78 } 79 buf[amt2] = '\0'; 80 to_unix(buf); 81 if (ending == UNIX) { 82 strcpy(node->buf, buf); 83 } else { 84 char buf2[(BUFSIZE*2)+3]; 85 unix_to_dos(buf2, buf); 86 strcpy(node->buf, buf2); 87 } 88 len -= amt2; 89 } 90 91 ftruncate(fd, 0); 92 lseek(fd, 0, SEEK_SET); 93 while (root) { 94 ssize_t amt2 = strlen(root->buf); 95 if (amt2 > 0) { 96 ssize_t amt = write(fd, root->buf, amt2); 97 if (amt != amt2) { 98 fprintf(stderr, "unable to write file: %s\n", argv[i]); 99 return 1; 100 } 101 } 102 node = root; 103 root = root->next; 104 free(node); 105 } 106 } 107 close(fd); 108 } 109 return 0; 110 } 111 112 void 113 to_unix(char* buf) 114 { 115 char* p = buf; 116 char* q = buf; 117 while (*p) { 118 if (p[0] == '\r' && p[1] == '\n') { 119 // dos 120 *q = '\n'; 121 p += 2; 122 q += 1; 123 } 124 else if (p[0] == '\r') { 125 // old mac 126 *q = '\n'; 127 p += 1; 128 q += 1; 129 } 130 else { 131 *q = *p; 132 p += 1; 133 q += 1; 134 } 135 } 136 *q = '\0'; 137 } 138 139 void 140 unix_to_dos(char* buf2, const char* buf) 141 { 142 const char* p = buf; 143 char* q = buf2; 144 while (*p) { 145 if (*p == '\n') { 146 q[0] = '\r'; 147 q[1] = '\n'; 148 q += 2; 149 p += 1; 150 } else { 151 *q = *p; 152 p += 1; 153 q += 1; 154 } 155 } 156 *q = '\0'; 157 } 158 159