| #include <unistd.h> |
| #include <fcntl.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <sys/stat.h> |
| |
| #define BUFSIZE (1024*8) |
| static void to_unix(char* buf); |
| static void unix_to_dos(char* buf2, const char* buf); |
| |
| int usage() |
| { |
| fprintf(stderr, "usage: line_endings unix|dos FILES\n" |
| "\n" |
| "Convert FILES to either unix or dos line endings.\n"); |
| return 1; |
| } |
| |
| typedef struct Node { |
| struct Node *next; |
| char buf[BUFSIZE*2+3]; |
| } Node; |
| |
| int |
| main(int argc, char** argv) |
| { |
| enum { UNIX, DOS } ending; |
| int i; |
| |
| if (argc < 2) { |
| return usage(); |
| } |
| |
| if (0 == strcmp("unix", argv[1])) { |
| ending = UNIX; |
| } |
| else if (0 == strcmp("dos", argv[1])) { |
| ending = DOS; |
| } |
| else { |
| return usage(); |
| } |
| |
| for (i=2; i<argc; i++) { |
| int fd; |
| int len; |
| |
| // force implied |
| chmod(argv[i], S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP); |
| |
| fd = open(argv[i], O_RDWR); |
| if (fd < 0) { |
| fprintf(stderr, "unable to open file for read/write: %s\n", argv[i]); |
| return 1; |
| } |
| |
| len = lseek(fd, 0, SEEK_END); |
| lseek(fd, 0, SEEK_SET); |
| |
| if (len > 0) { |
| Node* root = malloc(sizeof(Node)); |
| Node* node = root; |
| node->buf[0] = 0; |
| |
| while (len > 0) { |
| node->next = malloc(sizeof(Node)); |
| node = node->next; |
| node->next = NULL; |
| |
| char buf[BUFSIZE+2]; |
| ssize_t amt; |
| ssize_t amt2 = len < BUFSIZE ? len : BUFSIZE; |
| amt = read(fd, buf, amt2); |
| if (amt != amt2) { |
| fprintf(stderr, "unable to read file: %s\n", argv[i]); |
| return 1; |
| } |
| buf[amt2] = '\0'; |
| to_unix(buf); |
| if (ending == UNIX) { |
| strcpy(node->buf, buf); |
| } else { |
| char buf2[(BUFSIZE*2)+3]; |
| unix_to_dos(buf2, buf); |
| strcpy(node->buf, buf2); |
| } |
| len -= amt2; |
| } |
| |
| ftruncate(fd, 0); |
| lseek(fd, 0, SEEK_SET); |
| while (root) { |
| ssize_t amt2 = strlen(root->buf); |
| if (amt2 > 0) { |
| ssize_t amt = write(fd, root->buf, amt2); |
| if (amt != amt2) { |
| fprintf(stderr, "unable to write file: %s\n", argv[i]); |
| return 1; |
| } |
| } |
| node = root; |
| root = root->next; |
| free(node); |
| } |
| } |
| close(fd); |
| } |
| return 0; |
| } |
| |
| void |
| to_unix(char* buf) |
| { |
| char* p = buf; |
| char* q = buf; |
| while (*p) { |
| if (p[0] == '\r' && p[1] == '\n') { |
| // dos |
| *q = '\n'; |
| p += 2; |
| q += 1; |
| } |
| else if (p[0] == '\r') { |
| // old mac |
| *q = '\n'; |
| p += 1; |
| q += 1; |
| } |
| else { |
| *q = *p; |
| p += 1; |
| q += 1; |
| } |
| } |
| *q = '\0'; |
| } |
| |
| void |
| unix_to_dos(char* buf2, const char* buf) |
| { |
| const char* p = buf; |
| char* q = buf2; |
| while (*p) { |
| if (*p == '\n') { |
| q[0] = '\r'; |
| q[1] = '\n'; |
| q += 2; |
| p += 1; |
| } else { |
| *q = *p; |
| p += 1; |
| q += 1; |
| } |
| } |
| *q = '\0'; |
| } |
| |