static char rcsid[] = "@(#)$Id: write_rc.c,v 1.4 2006/04/09 07:37:08 hurtta Exp $";

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.4 $   $State: Exp $
 *
 *  Author: Kari Hurtta <hurtta+elm@posti.FMI.FI> (was hurtta+elm@ozone.FMI.FI)
 *****************************************************************************
 * Some code based on ../src/save_opts.c
 * That code was following copyright:
 *
 *  The Elm Mail System 
 *
 *			Copyright (c) 1988-1992 USENET Community Trust
 *			Copyright (c) 1986,1987 Dave Taylor
 *****************************************************************************/

#include "headers.h"
#include "rc_imp.h"
#include "save_opts.h"
#include "s_elmrc.h"

#include <errno.h> 
#ifndef ANSI_C
extern int errno;
#endif

DEBUG_VAR(Debug,__FILE__,"config");

int write_rc(targetfile,commentfile,global,actor,username)
     char *targetfile; 
     FILE * commentfile; 
     int global;
     char *actor;
     char *username;
{
    int close_comment_file = 0;
    char *tmp  = NULL;
    int res = 0;
    int errcode;

    int x;
    FILE *f;

    if (!commentfile) {
	commentfile = fopen(ELMRC_INFO,"r");
	if (!commentfile)
	    lib_error(CATGETS(elm_msg_cat, ElmrcSet, 
			      ElmrcSavingWithoutComments,
			      "Warning: saving without comments! Can't get to %s."),
		      ELMRC_INFO);
	else 
	    close_comment_file++;

    }


    tmp = elm_message(FRM("%s.N"),targetfile);
    
    errcode = can_open(tmp,"w");

    if (errcode) {
	lib_error(CATGETS(elm_msg_cat, ElmrcSet, ElmrcFileNotWriteable,
			  "File %s is not writeable: %s"),
		  tmp, error_description(errcode));
	
	res = 0;
	goto fail;
    }


    f = fopen(tmp,"w");
    if (!f) {
	int errcode = errno;
	lib_error(CATGETS(elm_msg_cat, ElmrcSet, ElmrcFileNotWriteable,
			  "File %s is not writeable: %s"),
		  tmp, error_description(errcode));
	
	res = 0;
	goto fail;
    }

    if (username && username[0])
	elm_fprintf(f, 
		    CATGETS(elm_msg_cat, ElmrcSet, ElmrcSavedAutoFor1,
			    "# Saved automatically by %s %s for %s\n#\n\n"),
		    actor, version_buff, username);
    else
	elm_fprintf(f, 
		    CATGETS(elm_msg_cat, ElmrcSet, ElmrcSavedAutoWrite1,
			    "# Saved automatically by %s %s\n#\n\n"), 
		    actor,version_buff);


    if (commentfile) {
	char line_buffer[SLEN];
	int x;
	int len;
	int local_value;
	int skip = 1;
	
	while (0  < (len = 
		     mail_gets(line_buffer, sizeof line_buffer, 
			       commentfile))) {
	    
	    int y = 0;

	    if (line_buffer[len-1] != '\n') {
		DPRINT(Debug,1,(&Debug, 
				"Too long line (read len=%d): %s\n",
				len,line_buffer));
		break;
	    }
	    line_buffer[--len] = '\0';
	    if (0 == len)
		continue;

	    if ('#' == line_buffer[0] || whitespace(line_buffer[0])) {
		
		if (strncmp(line_buffer, "#$HDR", 5) == 0) {
		    skip = 0;
		    continue;
		}
		
		if (skip)
		    continue;
		
		/* Copy initial comments */
		
		fprintf(f,"%s\n",line_buffer);
		continue;
	    }
	    skip = 1;


	    for (x = 0; x < NUMBER_OF_SAVEABLE_OPTIONS; x++) {
		y = strcmp(line_buffer, save_info[x].name);
		if (y <= 0)
		    break;
	    }
	    
	    if (x >= NUMBER_OF_SAVEABLE_OPTIONS || y != 0) {
		
		DPRINT(Debug,15,(&Debug,
				 "Skipping option %s ... \n",
				 line_buffer));
		
		continue;
	    }

	    if (global && 
		! (save_info[x].flags & FL_CHANGED) &&
		! (save_info[x].flags & FL_SYS)) {
		DPRINT(Debug,15,(&Debug,
				 "Skipping user option %s ... \n",
				 line_buffer));
		
		continue;
	    }
	    
	    if (!global &&
		(save_info[x].flags & FL_SYS)) {
		DPRINT(Debug,15,(&Debug,
				 "Skipping system option %s ... \n",
				 line_buffer));
		
		continue;
	    }
	    
	    fprintf(f,"\n");
	    
	    /* Copy comments */
	    while (0  < (len = 
			 mail_gets(line_buffer, sizeof line_buffer, 
				   commentfile))) {
		if ('#' != line_buffer[0])
		    break;
		fputs(line_buffer,f);
	    }
	    
	    if (global)
		local_value = save_info[x].flags & FL_CHANGED;
	    else
		local_value = save_info[x].flags & FL_LOCAL;
	    if (RCTYPE_magic != save_info[x].dt_type->magic)
		panic("RC PANIC",__FILE__,__LINE__,"write_rc",
		      "Bad config item type",0);

	    DPRINT(Debug,15,(&Debug,
			     "Writing option %s ... %s\n",
			     save_info[x].name,
			     local_value ? "(local value)" : ""));
	    
	    save_info[x].dt_type->print_value(f,
					      & save_info[x],
					      !local_value);
	    
	    
	    save_info[x].flags |= FL_SAVED;
	}
    }
    
    for (x = 0; x < NUMBER_OF_SAVEABLE_OPTIONS; x++) {
	int local_value;
	
	
	if (save_info[x].flags & FL_SAVED)
	    continue;
	
	if (global && 
	    ! (save_info[x].flags & FL_CHANGED) &&
	    ! (save_info[x].flags & FL_SYS)) {
	    DPRINT(Debug,15,(&Debug,
			     "Skipping user option %s ... \n",
			     save_info[x].name));
	    
	    continue;
	}
	
	if (!global &&
	    (save_info[x].flags & FL_SYS)) {
	    DPRINT(Debug,15,(&Debug,
			     "Skipping system option %s ... \n",
			     save_info[x].name));
	    
	    continue;
	}
	
	fprintf(f,"\n");
	
	if (global)
	    local_value = save_info[x].flags & FL_CHANGED;
	else
	    local_value = save_info[x].flags & FL_LOCAL;
	if (RCTYPE_magic != save_info[x].dt_type->magic)
	    panic("RC PANIC",__FILE__,__LINE__,"write_rc",
		  "Bad config item type",0);

	DPRINT(Debug,15,(&Debug,
			 "Writing option %s ... %s (no comment)\n",
			 save_info[x].name,
			 local_value ? "(local value)" : ""));
	
	
	save_info[x].dt_type->print_value(f,
					  & save_info[x],
					  !local_value);
    }
    
#ifdef USE_DLOPEN
    print_local_shared_options(f,global);
#endif
    
    if (EOF == fclose(f)) {
	int errcode = errno;
	lib_error(CATGETS(elm_msg_cat, ElmrcSet, ElmrcFileNotWriteable,
			  "File %s is not writeable: %s"),
		  tmp, error_description(errcode));
	
	res = 0;
	goto fail;
    }
    
    if (0 != rename(tmp,targetfile)) {
	int errcode = errno;
	lib_error(CATGETS(elm_msg_cat, ElmrcSet, ElmrcFileNotRenamed,
			  "Failed to rename temporary file to %s: %s"),
		  targetfile, error_description(errcode));
	
	res = 0;
	goto fail;
    }
        
    res = 1;

 fail:
    if (tmp)
	free(tmp);

    if (close_comment_file)
	fclose(commentfile);

    return res;
}


/*
 * Local Variables:
 *  mode:c
 *  c-basic-offset:4
 *  buffer-file-coding-system: iso-8859-1
 * End:
 */



syntax highlighted by Code2HTML, v. 0.9.1