/*
*  m2u v1.0  Converts Mac text files to Unix
*
*  Copyright (C) 2000 Mats Peterson
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; see the file COPYING.  If not, write to
*  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
*  Boston, MA 02111-1307, USA.
*
*  Please send any comments/bug reports to
*  [email protected]  (Mats Peterson)
*/

#define _POSIX_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <utime.h>

#define FALSE   0
#define TRUE    1

int translate = FALSE;

static unsigned char mac2latin1[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 0,
196, 197, 199, 201, 209, 214, 220, 225, 224, 226, 228, 227, 229, 231, 233, 232,
234, 235, 237, 236, 238, 239, 241, 243, 242, 244, 246, 245, 250, 249, 251, 252,
0, 176, 162, 163, 167, 0, 182, 223, 174, 169, 0, 180, 168, 0, 198, 216,
0, 177, 0, 0, 165, 181, 0, 0, 0, 0, 0, 170, 186, 0, 230, 248,
191, 161, 172, 0, 0, 0, 0, 171, 187, 0, 32, 192, 195, 213, 0, 0,
0, 0, 0, 0, 0, 0, 247, 0, 255, 0, 0, 164, 0, 0, 0, 0,
0, 183, 0, 0, 0, 194, 202, 193, 203, 200, 205, 206, 207, 204, 211, 212,
0, 210, 218, 219, 217, 0, 0, 0, 175, 0, 0, 0, 184, 0, 0, 0
};


void convert(char *fname)
{
   struct stat statbuf;
   struct utimbuf tb;
   FILE* f_in;
   FILE* f_tmp;
   char *tmpname;
   int c, r, fd;

   if (stat(fname, &statbuf) < 0) {
       perror("stat");
       fprintf(stderr, "problem with file '%s'\n", fname);
       return;
   }

   if (! (f_in = fopen(fname, "r"))) {
       perror("fopen");
       fprintf(stderr, "problem with file '%s'\n", fname);
       return;
   }

   tmpname = malloc(strlen(fname) + 15);

   if (tmpname) {
       int fd;
       strcpy(tmpname, fname);
       strcat(tmpname, "m2uXXXXXX");
       fd = mkstemp(tmpname);
       if (fd < 0) {
           free(tmpname);
           tmpname = NULL;
       } else {
           if (! (f_tmp = fdopen(fd, "wb"))) {
               perror("fdopen");
               free(tmpname);
               tmpname = NULL;
           }
       }
   }

   if (! tmpname) {
       fprintf(stderr, "Error: unable to generate temporary file\n");
       fclose(f_in);
       return;
   }

   printf("Converting %s...\n", fname);

   while (1) {
       c = fgetc(f_in);
       if (feof(f_in))
           break;
       if (ferror(f_in)) {
           fprintf(stderr, "Read error\n");
           goto error;
       }
       if ((translate) && (c >= 32)) {
           c = mac2latin1[c];
           if (c == 0)
               c = 32;
       }
       if (c == 13)
           c = 10;
       fputc(c, f_tmp);
       if (ferror(f_tmp)) {
           fprintf(stderr, "Write error\n");
           goto error;
       }
   }

   fclose(f_in);
   fclose(f_tmp);

   if (rename(tmpname, fname) < 0) {
       perror("rename");
       fprintf(stderr, "problem with file '%s'\n", fname);
       goto error2;
   }

   free(tmpname);

   if (chown(fname, statbuf.st_uid, statbuf.st_gid) < 0) {
       perror("chown");
       fprintf(stderr, "problem with file '%s'\n", fname);
       return;
   }

   if (chmod(fname, statbuf.st_mode) < 0) {
       perror("chmod");
       fprintf(stderr, "problem with file '%s'\n", fname);
       return;
   }

   tb.actime = statbuf.st_atime;
   tb.modtime = statbuf.st_mtime;
   if (utime(fname, &tb) < 0) {
       perror("utime");
       fprintf(stderr, "problem with file '%s'\n", fname);
   }

   return;

error:
   fclose(f_in);
   fclose(f_tmp);
error2:
   remove(tmpname);
   free(tmpname);
}

int getopts(int argc, char **argv)
{
   int c;
   opterr = 0;

   while ((c = getopt(argc, argv, "t")) != -1) {
       switch(c) {
           case 't':
               translate = TRUE;
               break;
           case '?':
               if (isprint(optopt))
                   fprintf(stderr, "Unknown option '-%c'.\n", optopt);
               else
                   fprintf(stderr, "Unknown option character '\\x%x'.\n",
                           optopt);
               return 0;
           default:
               abort();
       }
   }
   return 1;
}

void usage(void)
{
   fprintf(stderr, "usage: m2u [-t] file ...\n");
   exit(1);
}

int main(int argc, char **argv)
{
   int i;

   if (! getopts(argc, argv))
       exit(1);

   if (argc == 1)
       usage();

   for (i = optind; i < argc ; i++)
       convert(argv[i]);

   printf("\nConversion finished.\n\n");
   exit(0);
}