static char rcsid[] = "@(#)$Id: elmcharset.c,v 1.34 2006/04/09 07:37:30 hurtta Exp $"; /****************************************************************************** * The Elm (ME+) Mail System - $Revision: 1.34 $ $State: Exp $ * * Author: Kari Hurtta (was hurtta+elm@ozone.FMI.FI) *****************************************************************************/ #include "elmutil.h" #include "s_me.h" #include "s_elm.h" #include "cs_imp.h" #include "misclib.h" #include "reghelper.h" DEBUG_VAR(Debug,__FILE__,"util"); extern char *optarg; extern int optind; char * program_name = "elmcharset"; int register_fd = -1; char * register_module = NULL; #include "charmapcopy.h" int main P_((int argc, char *argv[])); int main(argc, argv) int argc; char *argv[]; { int err = 0; int c,i; int global = 0; struct charset_map_item * MAP = NULL; char *targetfile = NULL; int MIB = 0; int config_merge = 0; #if DEBUG init_debugfile("ELMCHARSET"); /* HACK .... USER may want enable debug output for locale_init() This gives wrong result if some options value start with "-d" */ for (i = 1; i < argc; i++) { if ('-' == argv[i][0] && 'd' == argv[i][1] && argv[i][2]) { set_debugging(& (argv[i][2])); } } #endif locale_init(); REGHELPER_INIT(argv[0]); user_init(); init_defaults(); while ((c = getopt(argc, argv, "Gd:w:I:S:Mc")) != EOF) { FILE *X; char buf[LONG_STRING]; switch(c) { case 'G': global++; break; case 'c': config_merge++; break; case 'M': MIB++; break; case 'S': copydirs = safe_realloc(copydirs,(copydir_count+1) * sizeof (*copydirs)); copydirs[copydir_count++] = optarg; break; case 'd': #if DEBUG set_debugging(optarg); #else lib_error(CATGETS(elm_msg_cat, ElmSet, ElmArgsIngoringDebug, "Warning: system created without debugging enabled - request ignored\n")); #endif break; case 'w' : targetfile = optarg; if (0 != access(targetfile,WRITE_ACCESS)) { int errcode = errno; if (errcode != ENOENT) { lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotWriteable, "File %.50s is not writeable: %s"), targetfile, error_description(errcode)); err++; goto fail; } } break; case 'I' : if (0 != access(optarg,READ_ACCESS)) { int errcode = errno; lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotReadable, "File %.50s is not readable: %s"), optarg, error_description(errcode)); err++; goto fail; } X = fopen(optarg,"r"); if (!X) { int errcode = errno; lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotReadable, "File %.50s is not readable: %s"), optarg, error_description(errcode)); err++; goto fail; } while(fgets(buf,sizeof buf, X) != NULL) { char *c; int l1 = strlen(buf); charset_t N; if ('\n' == buf[l1 -1]) buf[l1 - 1] = '\0'; else { lib_error(CATGETS(elm_msg_cat, MeSet, MeTooLongLine, "%30s: Too long line: %.30s..."), optarg,buf); err++; break; } l1--; while (l1-- > 0 && whitespace(buf[l1])) buf[l1] = '\0'; c = buf; while (*c && whitespace (*c)) /* skip leading whitespace */ c++; if ('#' == *c) continue; if (!*c) continue; N = MIME_name_to_charset(c,0); if (N && 0 == istrcmp(N->MIME_name,c)) { N->flags &= ~SET_valid; SIGDPRINT(Debug,1, (&Debug, "Ignoring charset %s\n", N->MIME_name)); } else { SIGDPRINT(Debug,5, (&Debug, "No charset %s to ignore%s%s\n", c,N ? " -- was " : "",N->MIME_name)); } } fclose(X); break; case '?': err = 1; goto fail; } } elm_sfprintf(version_buff, sizeof version_buff, FRM("%s PL%s"), VERSION, PATCHLEVEL); #ifdef DEBUG { int d = panic_dprint("\n\ ======================================================\n\ Debug output of the ELMCHARSET program (version %s).\n", version_buff); if (d >= 50) { #if 0 panic_dprint("WARNING: Edit manually out sensitive information from that file!\n"); lower_prompt("WARNING: Debug file may include passwords -- edit it!"); sleep(5+sleepmsg); #endif } } #endif if (copydir_count) set_charmap_copy_callback(charmap_copy); if (!global) read_rc_file(0); else post_init_check(0); if (optind < argc) { int errcount = 0; MAP = load_charset_map(argv[optind],&errcount); if (!MAP || errcount) { err = 1; goto fail; } } if (config_merge) { if (!MAP) { lib_error(CATGETS(elm_msg_cat, MeSet, MeConfigMergeMap, "Config merge (-c) requires map as argument")); err++; goto fail; } if (targetfile) { lib_error(CATGETS(elm_msg_cat, MeSet, MeConfigMergeNoW, "Config merge (-c) Can not used with -w")); err++; goto fail; } if (global) { change_charset_map(& system_charset_map, MAP); free_charset_map(&MAP); MAP = system_charset_map; targetfile = system_mime_charsets; } else { change_charset_map(& user_charset_map, MAP); free_charset_map(&MAP); MAP = user_charset_map; targetfile = user_mime_charsets; } if (0 != access(targetfile,WRITE_ACCESS)) { int errcode = errno; if (errcode != ENOENT) { lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotWriteable, "File %.50s is not writeable: %s"), targetfile, error_description(errcode)); err++; goto fail; } } } if (!MAP && !MIB) { if (global) MAP = system_charset_map; else MAP = user_charset_map; } if (targetfile) { char * tmp = elm_message(FRM("%s.N"),targetfile); int errcode = can_open(tmp,"w"); FILE *f; if (errcode) { lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotWriteable, "File %.50s is not writeable: %s"), tmp, error_description(errcode)); err++; free(tmp); goto fail; } f = fopen(tmp,"w"); if (!f) { int errcode = errno; lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotWriteable, "File %.50s is not writeable: %s"), tmp, error_description(errcode)); err++; free(tmp); goto fail; } if (MIB) dump_by_MIBenum(f); if (MAP) dump_charset_map(f,MAP); if (EOF == fclose(f)) { int errcode = errno; lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotWriteable, "File %.50s is not writeable: %s"), tmp, error_description(errcode)); err++; free(tmp); goto fail; } if (0 != rename(tmp,targetfile)) { int errcode = errno; lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotRenamed, "Failed to rename temporary file to %.50s: %.30s"), targetfile, error_description(errcode)); err++; free(tmp); goto fail; } log_config(targetfile); free(tmp); } else { if (MIB) dump_by_MIBenum(stdout); if (MAP) dump_charset_map(stdout,MAP); } fail: if (err) lib_error(CATGETS(elm_msg_cat, MeSet, MeProgFailed, "%s failed; exit code=%d"), argv[0],err); return err; } /* * Local Variables: * mode:c * c-basic-offset:4 * buffer-file-coding-system: iso-8859-1 * End: */