/* 
	init.c
	15.3.99 tn
*/

#include "largefile.h"

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <string.h>
#include <strings.h>
#if defined(linux) || defined(__CYGWIN32__)
#include <getopt.h>
#endif
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include "xcdrdata.h"
#include "xcdroast.h"
#include "main.h"

extern setup_data_t setupdata;
extern current_set_t curset;
extern cd_info_t cdinfo;
extern track_info_t **trackinfo;
extern gint language;
extern track_read_set_t trackreadset;
extern GList *imagelist;
extern GList *writelist;
extern write_track_param_t writeparams;
extern gint wav_in;
extern GList *tocfiles;
extern gint debug;
extern gchar xcdroast_version_loaded[MAXLINE];
extern master_param_t masterparam;
extern gint oldfontcode;
extern gint ignorescanbus;
extern writer_driver_t **drv_options;
extern gint drvoptcount;
extern GtkWidget *toplevel;
extern gchar **charset_types;

gchar *system_platform;
gchar hostname[MAXLINE];
gchar username[MAXLINE];
gchar configdir[MAXLINE];
gchar sharedir[MAXLINE];
gchar rootconfig[MAXLINE];
gchar prefixdir[MAXLINE];
gint runningbash2;

/* give the setupdata-structure valid startvalues */

void init_setupdata() {
gchar tmp[MAXLINE];
gint fullaccess;

	setupdata.writer_devnr = -1;
	strcpy(setupdata.writer_vendor,"");
	strcpy(setupdata.writer_model,"");
	setupdata.writer_mode = -1;
	setupdata.writer_speed = 1;
	setupdata.writer_fifo = 4096;

	setupdata.readdev1_devnr = -1;
	strcpy(setupdata.readdev1_vendor,"");
	strcpy(setupdata.readdev1_model,"");
	setupdata.readdev2_devnr = -1;
	strcpy(setupdata.readdev2_vendor,"");
	strcpy(setupdata.readdev2_model,"");
	setupdata.audioread_interface = 0;
	setupdata.audioread_speed = 1;
	setupdata.audioread_overlap = 0;
	setupdata.audioread_sectorburst = 75;

	setupdata.image_dirs = NULL;
	
	setupdata.dsp_device = g_strdup("");
	setupdata.mix_device = g_strdup("");
	setupdata.notify_via = 1;
	setupdata.notify_at = 0;

	setupdata.cddb_host = g_strdup("freedb.freedb.org");
	setupdata.cddb_port = 888;

	g_snprintf(tmp,MAXLINE,"%s/%s", CONFIGDIR, LOGFILE);
	setupdata.logfile = g_strdup(tmp);
	setupdata.loglevel = 0;

	setupdata.language = -1;	

	setupdata.option_tooltips = 1;
	setupdata.option_autoraise = 0;
	setupdata.option_savepos = 0;
	setupdata.option_personimage = 0;
	setupdata.option_overwritewarn = 0;
	setupdata.option_autodelete = 0;
	setupdata.option_titleprogress = 0;
	setupdata.option_displaycdtext = 1;
	setupdata.option_selectionmode = 0;
	setupdata.def_write_mode = 0;

	setupdata.root_users_access = 0;
	setupdata.root_users_lists = NULL;
	setupdata.root_hosts_access = 0;
	setupdata.root_hosts_lists = NULL;

#if !(defined(__MACH__) && defined(__APPLE__)) 
	fullaccess = 0;
#else
	/* on osX no access-control, so allow all by default */
	fullaccess = 1;
#endif

        setupdata.root_option_change_writer = fullaccess;
        setupdata.root_option_change_writeparam = fullaccess;
        setupdata.root_option_change_reader = fullaccess;
        setupdata.root_option_change_readparam = fullaccess;
        setupdata.root_option_change_imagedirs = fullaccess;
        setupdata.root_option_change_logoptions = fullaccess;

}


/* init current-set-structure */

void init_curset() {
gint cdrtypes[] = CDR_TYPES_MIN;
gint i;

	curset.isProDVD = 0;
	curset.writer_devnr = -1;
	curset.reader_devnr = -1;
	curset.writer_speed = -1;
	curset.audioread_speed = -1;
	curset.image_index = -1;
	curset.proc_view = 2;
	curset.file_prefix = g_strdup("");
	curset.tocfile = g_strdup("");
	curset.writemode = 0;
	curset.writesimul = 0;
	curset.writeeject = 1;
	curset.writepad = 1;
	curset.writeswap = 0;
	curset.nofixate = 0;
	curset.multisession = 0;
	curset.writecdtext = 0;
	curset.writeoverburn = 0;
	curset.writeburnfree = 1;
	curset.blankmode = 1;
	curset.blank_force = 0;
	curset.blank_eject = 1;
	curset.noaudioverify = 0;
	curset.verifyfailabort = 0;
	curset.indexscan = 1;
	curset.sync_cdtext_artist = 0;
	curset.mstr_auto_calc = 1;

	/* find out default value for cdrtype */
	curset.cdrtype = 0;
	i = 0;
	while (cdrtypes[i] != 0) {
		if (cdrtypes[i] < 0) {
			curset.cdrtype = abs(cdrtypes[i]);
		}
		i++;
	}	
}


/* init cdinfo and trackinfo-structure */

void init_cdinfo() {

	cdinfo.nr_tracks = 0;
	cdinfo.total_size = 0;
	strcpy(cdinfo.cddb_discid,"00000000");
	cdinfo.have_cdtext = 0;
	cdinfo.have_cdextra = 0;
	cdinfo.title = NULL;
	cdinfo.artist = NULL;
	cdinfo.cddb_dtitle = NULL;
	cdinfo.leadout = 0;	

	/* allocate tracks */
	trackinfo = g_new0(track_info_t *,MAXTRACKS);
}


/* init trackreadset-variable */

void init_trackreadset() {

	trackreadset.nrtracks = 0;
	trackreadset.tocfile = g_strdup("");
	trackreadset.cdtitle = g_strdup("");
	trackreadset.trackparams = NULL;
}


/* init writeparams-structure */

void init_writeparams() {

	writeparams.nrtracks = 0;
	writeparams.simulation = 0;
	writeparams.tracktype = NULL;
	writeparams.frames = NULL;
	writeparams.pct_so_far_arr = NULL;
	writeparams.pct_this_track_arr = NULL;
}


/* init master-parameters */

void init_masterparams() {
int i;

	masterparam.mstr_redir = NULL;
	masterparam.exclude_paths = NULL;
	masterparam.show_only_dirs = 1;
	masterparam.image_type = -1;
	for (i=0; i<16; i++) 
		masterparam.opt[i] = 0;	
	masterparam.bootable = 0;
	masterparam.boot_image = g_strdup("");
	masterparam.boot_catalog = g_strdup(DEF_BOOT_CATALOG);
	masterparam.boot_type = 0;
	masterparam.sparc_boot = g_strdup("");
	masterparam.volid = g_strdup("");
	masterparam.publisher = g_strdup("");
	masterparam.preparer = g_strdup("");
	masterparam.application = g_strdup("");
	masterparam.abstract = g_strdup("");
	masterparam.biblio = g_strdup("");
	masterparam.copyright = g_strdup("");
	masterparam.image_filename = g_strdup("");
	masterparam.old_session_size = 0;
	masterparam.session_size = 0;
	masterparam.charset = 0;
	masterparam.redirtype = 2;
	masterparam.lastredirpath = g_strdup("");
	masterparam.redirtype2 = 0;
	masterparam.lastredirpath2 = g_strdup("");
	masterparam.last_session_start = -1;
	masterparam.next_session_start = -1;
}

void init_drv_options() {

	drv_options=NULL;
	drvoptcount = 0;
}


/* make a stat on a file return 1 if it does exist, 0 if not */

gint stat_file(gchar *file) {
struct stat buf;
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar *p;

	/* strip first all after a space in filename (arguments) */
	strcpy(tmp,file);
	p = strtok(tmp," ");
	if (p != NULL) {
		strcpy(tmp2,p);
		strcpy(tmp,tmp2);
	}

	/* file does exist? */
	if (stat(tmp,&buf) == 0) {
		if (!(buf.st_mode & S_IEXEC)) {
			g_warning("%s not executable\n", file);
			gtk_exit(1);
		}
		return 1;
	} 
	return 0;
}


/* check if a given file got the suid-bit set */
/* return 0 if not set, 1 if set */

gint suid_set(gchar *file) {
struct stat buf;

/* non-root-mode not required on MacOSX */
#if (defined(__MACH__) && defined(__APPLE__)) 
	return 0;
#endif

	/* file does exist? */
	if (stat(file,&buf) == 0) {
		if (!(buf.st_mode & S_ISUID)) {
/*
			g_warning("Installation problem? No set-uid bit on %s\n", file);
			dodebug(1,"Warning: No set-uid bit on %s\n", file);
*/
			return 0;
		}
	}
	return 1;
}


/* check if a given file got the gid-bit set */
/* return the value gid_t */

gid_t sgid_set(gchar *file) {
struct stat buf;

#if (defined(__MACH__) && defined(__APPLE__)) 
	return (gid_t) 0;
#endif

	/* file does exist? */
	if (stat(file,&buf) == 0) {
/*
		if (!(buf.st_mode & S_ISGID)) {
			g_warning("Installation problem? No set-gid bit on %s\n", file);
			dodebug(1,"Warning: No set-gid bit on %s\n", file);
		}
*/

		return buf.st_gid;
	}
	return (gid_t) 0;
}


/* stat a file and see if its a binary */

gint check_executable(gchar *file, gchar *altfile, gint share) {
gint second;

	second = 0;
	if (altfile != NULL) {
		second = stat_file(altfile);
	}

	if (stat_file(file) == 0 && !second) {
		if (altfile == NULL) 
			g_warning("No %s installed\n", file);
		else
			g_warning("No %s or %s installed\n", file, altfile);
			
		if (share) 
			g_warning("(Invalid lib-directory? Check -l option)\n");
		gtk_exit(1);
	}

	return 0;
}

/* check if needed binaries are installed */
/* return if proDVD version */

gint check_binaries(gint noversioncheck) {
gchar tmp[MAXLINE];
gchar ver[MAXLINE];
gint stat;
gint isProDVD;
	
	check_executable(UNAME,UNAME2,0);
	check_executable(DF,DF2,0);

	get_spawn_path(CDRECORD,tmp);
	check_executable(tmp,NULL,1);
	if (check_islink(tmp)) {
		g_warning("%s is a link. Please note\n\tthat the non-root-mode may fail. Use a copy of that file instead.\n", tmp);
	}
	stat = check_version_cdrecord(CDRECORD_VERSION,ver, &isProDVD);
	if (stat == 1 && !noversioncheck) {
		g_warning("Invalid cdrecord version %s found.\n\tExpecting at least version %s\n\tStart xcdroast with the -n option to override (not recommended!)", ver, CDRECORD_VERSION);	
		gtk_exit(1);
	}
	if (stat == 2) {
		g_warning("Failed to access cdrecord. Please check the permissions and ownership of %s\n", tmp);
		gtk_exit(1);
	}

	get_spawn_path(MKISOFS,tmp);
	check_executable(tmp,NULL,1);
	if (check_islink(tmp)) {
		g_warning("%s is a link. Please note\n\tthat the non-root-mode may fail. Use a copy of that file instead.\n", tmp);
	}
	stat = check_version_mkisofs(MKISOFS_VERSION,ver);
	if (stat == 1 && !noversioncheck) {
		g_warning("Invalid mkisofs version %s found.\n\tExpecting at least version %s\n\tStart xcdroast with the -n option to override (not recommended!)", ver, MKISOFS_VERSION);	
		gtk_exit(1);
	}
	if (stat == 2) {
		g_warning("Failed to access mkisofs. Please check the permissions and ownership of %s\n", tmp);
		gtk_exit(1);
	}

	get_spawn_path(READCD,tmp);
	check_executable(tmp,NULL,1);
	if (check_islink(tmp)) {
		g_warning("%s is a link. Please note\n\tthat the non-root-mode may fail. Use a copy of that file instead.\n", tmp);
	}
	stat = check_version_readcd(READCD_VERSION,ver);
	if (stat == 1 && !noversioncheck) {
		g_warning("Invalid readcd version %s found.\n\tExpecting at least version %s\n\tStart xcdroast with the -n option to override (not recommended!)", ver, READCD_VERSION);	
		gtk_exit(1);
	}
	if (stat == 2) {
		g_warning("Failed to access readcd. Please check the permissions and ownership of %s\n", tmp);
		gtk_exit(1);
	}


	get_spawn_path(CDDA2WAV,tmp);
	check_executable(tmp,NULL,1);
	if (check_islink(tmp)) {
		g_warning("%s is a link. Please note\n\tthat the non-root-mode may fail. Use a copy of that file instead.\n", tmp);
	}
	stat = check_version_cdda2wav(CDDA2WAV_VERSION,ver);
	if (stat == 1 && !noversioncheck) {
		g_warning("Invalid cdda2wav version %s found.\n\tExpecting at least version %s\n\tStart xcdroast with the -n option to override (not recommended!)", ver, CDDA2WAV_VERSION);	
		gtk_exit(1);
	}
	if (stat == 2) {
		g_warning("Failed to access cdda2wav. Please check the permissions and ownership of %s\n", tmp);
		gtk_exit(1);
	}

	g_snprintf(tmp,MAXLINE,"%s/%s", sharedir, WAVPLAY);
	check_executable(tmp,NULL,1);
	g_snprintf(tmp,MAXLINE,"%s/%s", sharedir, RMTOOL);
	check_executable(tmp,NULL,1);
	g_snprintf(tmp,MAXLINE,"%s/%s", sharedir, VRFYTOOL);
	check_executable(tmp,NULL,1);
	g_snprintf(tmp,MAXLINE,"%s/%s", sharedir, CDDBTOOL);
	check_executable(tmp,NULL,1);

	return isProDVD;
}


/* check the wrapper binary */
/* return 1 when user got no permission */
/* return 2 if rootconfig not readable */

gint check_wrapper_binary() {
gchar tmp[MAXLINE];
gint stat;

	g_snprintf(tmp,MAXLINE,"%s/%s", sharedir, WRAPPER);
	check_executable(tmp,NULL,1);

	/* security check. If this fails then the wrapper is wrong */
	stat = check_version_wrapper(tmp);
	if (stat == 1) {
		fprintf(stderr, "Aborting...\n");
		gtk_exit(1);
	}
	if (stat == 2) {
		/* this user is not allowed to start the wrapper */
		return 1;
	}
	if (stat == 3) {
		/* no rootconfig readable */
		return 2;
	}

	return 0;
}


#if 0
/* a graphically root-warning */

void check_root() {

	if (!isroot()) {
		/* we need a toplevel for the show_dialog function */
		toplevel = gtk_window_new(GTK_WINDOW_TOPLEVEL);
		gtk_widget_realize(toplevel);
	
		show_dialog(ICO_WARN, text(413), T_OK, NULL, NULL, 0);
		gtk_exit(1);
	}
}
#endif

/* check if we have at least 800x600 virtual screen size */
/* for bigfonts we need 1024x768 */

gint check_screensize(gint bigfonts) {
gint xsize, ysize;

	xsize = gdk_screen_width();
	ysize = gdk_screen_height();

	if (bigfonts == 0) {
		if (xsize < 800 || ysize < 600) 
			return 1;
	} else {
		if (xsize < 1024 || ysize < 768) 
			return 1;
	}
	return 0;
}


/* do check if the current user and host is allowed to start xcdroast */
/* return 1 if so, 0 if denied */

gint checkuserhost(gchar *username,gchar *hostname) {
gint userok, hostok;
gint match;
GList *loop;

	match = 0;
	/* user first */
	if (setupdata.root_users_access == 0) {
		userok = 1;
	} else 
	if (setupdata.root_users_access == 1) {
		userok = 0;
	} else {
		loop = g_list_first(setupdata.root_users_lists);
		while (loop) {
			if (strcmp(username,(gchar *)loop->data) == 0) {
				/* found our login on the list */
				match = 1;
			}		
			loop = loop->next;
		}
		if ((setupdata.root_users_access == 2 && match) ||
		    (setupdata.root_users_access == 3 && !match)) {
			userok = 1;
		} else  {
			userok = 0;
		}
	}	

	match = 0;
	/* now check host */
	if (setupdata.root_hosts_access == 0) {
		hostok = 1;
	} else 
	if (setupdata.root_hosts_access == 1) {
		hostok = 0;
	} else {
		loop = g_list_first(setupdata.root_hosts_lists);
		while (loop) {
			if (strcmp(hostname,(gchar *)loop->data) == 0) {
				/* found our login on the list */
				match = 1;
			}		
			loop = loop->next;
		}
		if ((setupdata.root_hosts_access == 2 && match) ||
		    (setupdata.root_hosts_access == 3 && !match)) {
			hostok = 1;
		} else  {
			hostok = 0;
		}
	}

	/* only when both the host and the user are allowed, allow access */
	if (userok && hostok) {
		return 1;
	} else {
		return 0;
	}
}


/* returns if a cdrtools-executable got right permissions */

gint check_nonroot_mode_cdrtools(gchar *tmp) {
gid_t wrap_gid;
gchar tmp2[MAXLINE];
gint nofail;
	
	nofail = 1;
	wrap_gid = sgid_set(tmp);
	if (!match_group_name(wrap_gid,NONROOTMODEGROUP)) {

		return_group_name(wrap_gid, tmp2);
		dodebug(3,"Note: %s got wrong group (%s)\n", tmp, tmp2);
		nofail = 0;
	}
	if (suid_set(tmp) == 0) {
		dodebug(3,"Note: %s no suid-bit set.\n", tmp);
		nofail = 0;
	}

	return nofail;
}


/* return 0 if nonrootmode is not possible, 1 if possible (activated) */

gint check_if_nonrootmode() {
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
struct stat buf;
gid_t wrap_gid;
gint nofail;

	nofail = 1;
	
	/* first check if the wrapper got the correct permissions */
	g_snprintf(tmp,MAXLINE,"%s/%s", sharedir, WRAPPER);
	wrap_gid = sgid_set(tmp);

	/* check group */
	if (!match_group_name(wrap_gid,NONROOTMODEGROUP)) {

		return_group_name(wrap_gid, tmp2);
		dodebug(3,"Note: %s got wrong group (%s)\n", tmp, tmp2);
		nofail = 0;
	}

	/* check file mode of wrapper */
	if (stat(tmp,&buf) == 0) {
		if (buf.st_mode != 0102755) {
			dodebug(3,"Note: %s wrong modes set (0%o)\n", tmp, buf.st_mode);
			nofail = 0;
		}
	}

	/* wrapper seems to be ok */
	/* check if the cdrtools got the right permissions */

	get_spawn_path(CDRECORD,tmp);
	if (check_nonroot_mode_cdrtools(tmp) == 0) {
		nofail = 0;
	}

	get_spawn_path(MKISOFS,tmp);
	if (check_nonroot_mode_cdrtools(tmp) == 0) {
		nofail = 0;
	}

	get_spawn_path(READCD,tmp);
	if (check_nonroot_mode_cdrtools(tmp) == 0) {
		nofail = 0;
	}

	get_spawn_path(CDDA2WAV,tmp);
	if (check_nonroot_mode_cdrtools(tmp) == 0) {
		nofail = 0;
	}

	return nofail;
}


/* returns if we are running in nonrootmode */

gint query_nonrootmode() {
gint nonrootmode;

#if (defined(__MACH__) && defined(__APPLE__))
	return -1;
#endif

	dodebug(3, "Checking X-CD-Roast non-root-mode configuration\n");
	nonrootmode = check_if_nonrootmode();
	if (nonrootmode) {
		dodebug(1,"--> X-CD-Roast configured correctly for non-root-mode.\n");
	} else {
		dodebug(1,"--> X-CD-Roast not configured for non-root-mode.\n");
	}

	return nonrootmode;
}


/* print usage-info */

void usage(gchar *cmd) {

	g_print("Usage: %s [options]  (Version: %s)\n", cmd, XCDROAST_VERSION);
	g_print("Options:\n");
	g_print("\t-d <debug level>\n");
	g_print("\t-c <config directory>  (currently: %s)\n", configdir);
	g_print("\t-l <lib directory>     (currently: %s)\n", sharedir);
/*	g_print("\t-r <root config-file>  (currently: %s)\n", rootconfig); */
	g_print("\t-o : Disable multibyte font support\n");
	g_print("\t-n : Disable cdrtools version check (use at own risk)\n");
	g_print("\t-i : Ignore SCSI-scan (allows you to start xcdroast without\n\t     any scsi-support)\n");
	g_print("\t-f \"<list of scsi-devices>\" : Won't scan for devices, but force\n\t     X-CD-Roast to use the given ones (semicolon seperated list).\n\t     Most useful on AIX or OpenBSD systems where scanning fails.\n");
	
	g_print("Some GTK-Options:\n");
	g_print("\t--display <remote host>\n");
	g_print("\t--sync\n");
#if (defined(__MACH__) && defined(__APPLE__)) 
	g_print("\t--no-xshm (Always set on MacOSX)\n");
#else
	g_print("\t--no-xshm\n");
#endif
}


/* Misc-init-stuff. stuff done once at program-startup */
/* return 0 if config file ok loaded, 1 on failure */

gint init(gint argc, gchar *argv[], gint *nonrootmode) { 
gchar tmp[MAXLINE];
gchar *p1;
gchar *alt_dev_string;
gint c, usercnf, noversioncheck, stat;
gint isProDVD;
gchar *keyenv;
	
	language = -1;
	debug = 0;
	oldfontcode = 0;
	ignorescanbus = 0;
	noversioncheck = 0;
	alt_dev_string = NULL;
	strncpy(configdir, CONFIGDIR, MAXLINE);
	strncpy(rootconfig, ROOTCONFIG, MAXLINE);

#ifdef PRE_LIBDIR 
	/* use prefix as sharedir as it came from the makefile-option */
	strncpy(sharedir, PRE_LIBDIR, MAXLINE);
#else
	/* otherwise install our default prefix */
	strncpy(sharedir, LIBDIR, MAXLINE);
#endif

#ifdef CDRTOOLS_PREFIX
        /* use prefix as it came from the makefile-option */
        strncpy(prefixdir, CDRTOOLS_PREFIX, MAXLINE);
#else
# ifdef PREFIX
	/* use prefix as it came from the makefile-option */
	strncpy(prefixdir, PRE_PREFIX, MAXLINE);
# else
	/* otherwise install our default prefix */
	strncpy(prefixdir, PREFIX, MAXLINE);
# endif	
#endif	
	/* parse command-line */
	while ((c = getopt(argc,argv,"d:c:l:r:oinf:")) != EOF)
	switch ((gchar)c) {
	
	case 'd':
		debug = atoi(optarg);
		break;

	case 'c':
		strncpy(configdir, optarg, MAXLINE);
		break;

/*
	case 'r':
		strncpy(rootconfig, optarg, MAXLINE);
		break;
*/
	case 'l':
		strncpy(sharedir, optarg, MAXLINE);
		break;

	case 'o':
		oldfontcode = 1;
		break;

	case 'i':
		ignorescanbus = 1;
		break;

	case 'n':
		noversioncheck = 1;
		break;

	case 'f':
		alt_dev_string = g_strdup(optarg);
#if (defined(__MACH__) && defined(__APPLE__)) 
		g_warning("-f option not supported on MacOSX\n");
		g_free(alt_dev_string);
		alt_dev_string = NULL;
#endif
		break;

	default:
		usage(argv[0]);
		gtk_exit(1);
	}
	
	/* init random generator */
	srand(time(NULL));

	/* --- all the following commands were needed for pre alpha9
	   non root code --- */
	/* something needed for debian ?????*/
	/* setregid(getegid(),getegid()); */

	/* check which kind of shell runs us */
	/*
	runningbash2 = check_version_shell();
	dodebug(3, "/bin/sh is bash2? = %d\n", runningbash2);
	*/

	/* this call does swap the egid with the gid - needed for
 	   the nonroot mode */
	/*	fix_guid(); */

	/* get some system-info */
	system_platform = g_strdup(strip_string(get_uname_info(tmp)));
	if (gethostname(hostname,MAXLINE) != 0) {
		strncpy(hostname,"not_available",MAXLINE);
	}

	p1 = g_get_user_name();
	if (p1 != NULL) {
		strncpy(username,p1, MAXLINE);
	} else {
		strncpy(username,"not_available",MAXLINE);
	}

	/* subst ~/ by $HOME */
	check_tilde(configdir);

	dodebug(1, "Starting X-CD-Roast %s by %s@%s on %s\n", 
		XCDROAST_VERSION,  username, hostname, system_platform);
	dodebug(1, "debug level: %d\n", debug);
	dodebug(1, "configdir: %s\n", configdir);
	dodebug(1, "rootconfig: %s\n", rootconfig);
	dodebug(1, "libdir: %s\n",sharedir);
	dodebug(1, "checking large file support: sizeof(off_t) = %d\n", sizeof(off_t));

	/* load language files */
	g_snprintf(tmp,MAXLINE,"%s/lang/language.def", sharedir);
	load_langfile(tmp);
	g_snprintf(tmp,MAXLINE,"%s/lang/langhelp.def", sharedir);
	load_helpfile(tmp);

	/* look for enviroment-variable $LANG - if not found set language
	   to english */
	scan_lang();

	/* get current status of nonroot mode */
	*nonrootmode = query_nonrootmode();

	dodebug(3, "Checking X-CD-Roast wrapper installation\n");
	stat = check_wrapper_binary();
	if (stat == 1) {
		/* we need a toplevel for the show_dialog function */
		toplevel = gtk_window_new(GTK_WINDOW_TOPLEVEL);
		gtk_widget_realize(toplevel);
		show_fancy_dialog(text(534), text(437), T_OK);
		gtk_exit(1);
	}
	/* no root config file yet */
	if (stat == 2) {
		if (!isroot()) {
			/* we need a toplevel for the show_dialog function */
			toplevel = gtk_window_new(GTK_WINDOW_TOPLEVEL);
			gtk_widget_realize(toplevel);
			show_fancy_dialog(text(534), text(435), T_OK);
			gtk_exit(1);
		} 
	}

#if !(defined(__MACH__) && defined(__APPLE__)) 
	/* check if we are a normal user and non-root-mode is off */
	if (*nonrootmode == 0 && !isroot()) {
		/* not allow start in this case */
		toplevel = gtk_window_new(GTK_WINDOW_TOPLEVEL);
		gtk_widget_realize(toplevel);
		show_fancy_dialog(text(534), text(468), T_OK);
		gtk_exit(1);
	}
#endif 

	dodebug(3, "Checking for helper binaries (noversioncheck = %d)\n", noversioncheck);
	isProDVD = check_binaries(noversioncheck);


	/* config-directory available? */
	if (!is_directory(configdir)) {
		/* try to create directory */
		mkdir(configdir, 0700);
		dodebug(2, "trying to mkdir %s\n", configdir);
	}


	/* check for permissions */
#if !defined(__CYGWIN32__)
	/* check_root(); */
#endif

	parse_alt_devs(alt_dev_string);
	scanbus();
	scandrivers();
	scanblankmodes();
	scancharsets();

	dodebug(3, "Initializing global data structures\n");
	wav_in = -1;
	init_setupdata();
	init_curset();
	init_cdinfo();
	init_trackreadset();
	init_writeparams();
	init_masterparams();
	init_drv_options();
	imagelist = (GList *) NULL;
	writelist = (GList *) NULL;
	tocfiles = (GList *) NULL;
	strcpy(xcdroast_version_loaded, "");

	curset.isProDVD = isProDVD;

	dolog(1, "Starting X-CD-Roast %s by %s@%s on %s\n", 
		XCDROAST_VERSION,  username, hostname, system_platform);

	/* load iso-options if available */
	g_snprintf(tmp,MAXLINE,"%s/%s", configdir, ISOOPTFILE);
	load_isooptions_file(tmp);

	/* load iso-headers if available */
	g_snprintf(tmp,MAXLINE,"%s/%s", configdir, ISOHEADERFILE);
	load_isoheaders_file(tmp);

	/* get the language from locale - can be overriden later */
	/* scan_lang(); */

	/* first load config-file from root */
	/* fix here guid, so that we are allowed to read the config */
	/* fix_guid(); */

	/* on osX no root config is required */
#if !(defined(__MACH__) && defined(__APPLE__)) 
	if (load_setup_config(rootconfig,1) != 0) {
		/* failed */
		if (!isroot()) {
			/* we need a toplevel for the show_dialog function */
			toplevel = gtk_window_new(GTK_WINDOW_TOPLEVEL);
			gtk_widget_realize(toplevel);
			show_fancy_dialog(text(534), text(435), T_OK);
			gtk_exit(1);
		} else {
			/* first start for root - let him create config */
			/* restore guid again */
			/* fix_guid(); */
			return 1;
		}
	}

	/* restore guid again */
	/* fix_guid(); */

	/* set the language to the one defined in the root config */
        if (setupdata.language >= 0) {
	        language = setupdata.language;
       	}

	/* now check if the loaded root-config was really from root */
	if (get_file_owner(rootconfig) != 0) {
		/* we need a toplevel for the show_dialog function */
		toplevel = gtk_window_new(GTK_WINDOW_TOPLEVEL);
		gtk_widget_realize(toplevel);
		show_dialog(ICO_WARN, text(436), T_OK, NULL, NULL, 0);
		gtk_exit(1);
	}

	/* here check if the current user is allowed to run xcdroast */
	if (!isroot()) {
		if (!checkuserhost(username,hostname)) {
			/* we need a toplevel for the show_dialog function */
			toplevel = gtk_window_new(GTK_WINDOW_TOPLEVEL);
			gtk_widget_realize(toplevel);
			show_fancy_dialog(text(534), text(437), T_OK);
			gtk_exit(1);
		}
	}

#endif

	/* load user config file - if possible */
	g_snprintf(tmp,MAXLINE,"%s/%s", configdir, CONFFILE);

#if (defined(__MACH__) && defined(__APPLE__)) 
	/* load user config on osX always */
	usercnf = load_setup_config(tmp,0);
#else 
	if (!isroot()) {
		/* load only when not root */
		usercnf = load_setup_config(tmp,0);
	} else {
		usercnf = 0;
	}
#endif

	/* if we are in DVD mode, check if the security-key is set */
	if (curset.isProDVD == 1) {
		keyenv = getenv("CDR_SECURITY");
		if (keyenv == NULL) {
			g_warning("The CDR_SECURITY environment varible is not set.\n\tYou might run into problems using cdrecord-ProDVD.\n");
		}		
	}

	if (usercnf == 0) {
		/* load ok */

		/* set language to the one in user-config */
	        if (setupdata.language >= 0) {
       		        language = setupdata.language;
        	}

		return 0;
	} else {
		/* load failed */
		strcpy(xcdroast_version_loaded,"");
		return 1;
	}
}

