/* 
	init.c
	15.3.99 tn
*/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include "largefile.h"

#if HAVE_LOCALE_H
#include <locale.h>
#else
# define setlocale(Category, Locale) 
#endif
#include "gettext.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

/*
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
*/

#if ENABLE_NLS
# define _(String) gettext (String)
# define N_(String) gettext_noop (String)
#else
# define _(String) (String)
# define N_(String) (String)
#endif

#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include "xcdrdata.h"
#include "xcdroast.h"
#include "main.h"



GList *imagelist;
GList *tocfiles;
track_read_set_t trackreadset;

extern setup_data_t setupdata;
extern writerreader_devices_t **writerreaderdevs;
extern current_set_t curset;
extern cd_info_t cdinfo;
extern track_info_t **trackinfo;
extern GList *writelist;
extern write_track_param_t writeparams;
extern gint wav_in;
extern gint debug;
extern gchar xcdroast_version_loaded[MAXLINE];
extern master_param_t masterparam;
extern gint oldfontcode;
extern gint no_versioncheck;
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 support_ontheflyaudio;
gint c_locale_is_utf8;
gchar *language = NULL;
GdkFont *fixedfont;

/* ProDVD key in global variable to let solaris-putenv access it */
gchar security_key[MAXLINE];

/* give the setupdata-structure valid startvalues */

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

	setupdata.writer_devnr = -1;
	setupdata.reader_devnr = -1;

	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;
	setupdata.cddb_proxy_host = g_strdup("");
	setupdata.cddb_proxy_port = 8080;
	setupdata.cddb_use_http = 0;
	setupdata.cddb_use_proxy = 0;

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

	setupdata.language = g_strdup("");	

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

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

	fullaccess = 1;

        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;

	setupdata.ProDVDkey = g_strdup("");	

	setupdata.mainwindow.x = -1;
	setupdata.mainwindow.y = -1;
	setupdata.mainwindow.width = -1;
	setupdata.mainwindow.height = -1;

	setupdata.burnwindow.x = -1;
	setupdata.burnwindow.y = -1;
	setupdata.burnwindow.width = -1;
	setupdata.burnwindow.height = -1;
}


/* init current-set-structure */

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

	curset.isProDVD = 0;
	curset.support_ontheflyaudio = 0;
	curset.writer_devnr = -1;
	curset.reader_devnr = -1;
	curset.image_index = -1;
	curset.proc_view = 2;
	curset.file_prefix = g_strdup("");
	curset.tocfile = g_strdup("");
	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.writeaudiomaster = 0;
	curset.writeforcespeed = 0;
	curset.writevarirec = 100; 	/* -1 or 0 belong to valid values */
	curset.writeignsize = 0;
	curset.writeimmed = 0;
	curset.blankmode = 1;
	curset.blank_force = 0;
	curset.blank_eject = 1;
	curset.noaudioverify = 0;
	curset.verifyfailabort = 0;
	curset.indexscan = 0;
	curset.sync_cdtext_artist = 0;
	curset.mstr_auto_calc = 1;
	curset.sudo_passwd = NULL;

	/* 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 */

static 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 */

static void init_trackreadset() {

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


/* init writeparams-structure */

static 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 */

static void init_masterparams() {
int i;

	masterparam.mstr_redir = NULL;
	masterparam.exclude_paths = NULL;
	masterparam.show_only_dirs = 1;
	masterparam.show_hidden_files = 0;
	masterparam.image_type = -1;
	for (i=0; i<22; 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.boot_load_size = -1;
	masterparam.boot_info_table = 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.outcharset = 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;
}


/* 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 */
#if 0
static gint suid_set(gchar *file) {
struct stat buf;

/* non-root-mode not required on MacOSX */
#if (defined(__MACH__) && defined(__APPLE__)) || (USE_NONROOTMODE == 0)
	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;
}
#endif

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

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

#if (defined(__MACH__) && defined(__APPLE__)) || (USE_NONROOTMODE == 0)
	return (gid_t) -1;
#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;
	}
	if (!isroot()) {
		g_warning("Installation problem? %s not found.\n", file); 
	}
	return (gid_t) -1;
}


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

static 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 found */

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

	get_spawn_path(CDRECORD,tmp);
	check_executable(tmp,NULL,1);
	if (check_islink(tmp, link)) {
#if 0   
	/* (USE_NONROOTMODE == 1) */
		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);
#else
		dodebug(3, "%s is a link to %s\n", tmp, link); 
#endif
	}
	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);
	}
	dodebug(10, "Found version %s for %s\n", ver, CDRECORD); 

	get_spawn_path(MKISOFS,tmp);
	check_executable(tmp,NULL,1);
	if (check_islink(tmp, link)) {
#if 0 
		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);
#else
		dodebug(3, "%s is a link to %s\n", tmp, link); 
#endif
	}
	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);
	}
	dodebug(10, "Found version %s for %s\n", ver, MKISOFS); 

	get_spawn_path(READCD,tmp);
	check_executable(tmp,NULL,1);
	if (check_islink(tmp, link)) {
#if 0
		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);
#else
		dodebug(3, "%s is a link to %s\n", tmp, link); 
#endif
	}
	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);
	}
	dodebug(10, "Found version %s for %s\n", ver, READCD); 


	get_spawn_path(CDDA2WAV,tmp);
	check_executable(tmp,NULL,1);
	if (check_islink(tmp, link)) {
#if 0 
		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);
#else
		dodebug(3, "%s is a link to %s\n", tmp, link); 
#endif
	}
	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);
	}
	dodebug(10, "Found version %s for %s\n", ver, CDDA2WAV); 

	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 */

static 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;
}


/* 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 */

static 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 */
#if 0
static gint check_nonroot_mode_cdrtools(gchar *tmp) {
gid_t wrap_gid;
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;
}
#endif


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

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

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

#if 0
	/* 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;
	}
#endif
	/* check owner */
	if (wrap_uid != 0) {
		dodebug(3,"Note: %s is not owned by root\n", tmp);
		nofail = 0;
	}

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

#if 0 
	/* we dont care in new nonroot mode about the status of the cdrtools */

	/* 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;
	}

	/* check prodvd only when it is installed */
	get_spawn_path(CDRECORDPRODVD,tmp);
	if (is_file(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;
	}
#endif

	return nofail;
}


/* returns if we are running in nonrootmode */

gint query_nonrootmode() {
gint nonrootmode;

#if (defined(__MACH__) && defined(__APPLE__)) || (USE_NONROOTMODE == 0)
	dodebug(1,"-- X-CD-Roast compiled with disabled non-root-mode.\n");

#if !(defined(__MACH__) && defined(__APPLE__))
	if (!isroot()) {
		g_print("\nWARNING: Using X-CD-Roast as non-root and was compiled without non-root-support.\n");
	}
#endif
	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 */

static 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-w : Don't use cdrecord-ProDVD, even when it is available.\n");
#if (defined(__MACH__) && defined(__APPLE__)) 
	g_print("\t-a : Don't display the autodiskmount daemon handling at startup\n");
#else
	g_print("\t-a : Disable alternative device scans\n");
#endif
	g_print("\t-f \"<list of scsi-devices>\" : Instead of automatic scanning force\n\t     X-CD-Roast to use the given devices (semicolon seperated list).\n\t     You can set these also within the setup-menu.\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, gint *altdevscan) {
gchar tmp[MAXLINE];
gchar *mylocale;
gchar *p1;
gchar *alt_dev_string;
gint c, usercnf, stat;
gint isProDVD, ignoreProDVD;
	
	if (!language) 
		language = g_strdup("");
	debug = 0;
	oldfontcode = 0;
	*altdevscan = 1;
	no_versioncheck = 0;
	support_ontheflyaudio = 0;
	c_locale_is_utf8 = 0;
	ignoreProDVD = 0;
	alt_dev_string = NULL;
	strncpy(configdir, CONFIGDIR, MAXLINE);
	g_snprintf(rootconfig, MAXLINE, "%s/%s", SYSCONFDIR, ROOTCONFIG);
	writerreaderdevs = NULL;

#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:oanwf:")) != 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 'a':
		*altdevscan = 0;
		break;

	case 'o':
		oldfontcode = 1;
		break;

	case 'n':
		no_versioncheck = 1;
		break;

	case 'w':
		ignoreProDVD = 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));

	/* 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 = (gchar *) 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));

	/* gettext stuff */
#ifdef HAVE_SETLOCALE
	mylocale = setlocale (LC_ALL, "");
	if (mylocale) {
		dodebug(1, "my locale: %s\n", mylocale);
		if (strstr(mylocale, "UTF-8")) {
			c_locale_is_utf8 = 1;
		}
	}
	setlocale (LC_NUMERIC, "C");
#endif

	/* load fixed font */
	fixedfont = get_some_font(FIXEDFONT);

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

	/* check if the systemconfig-directory exists */
	if (!is_directory(SYSCONFDIR)) {
		g_warning("The configured system-config-directory \"%s\"\n\twas not found. Aborting..\n", SYSCONFDIR);
		gtk_exit(1);
	}

	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(_("Warning:"), _("Access denied!\nYou have no permission to start X-CD-Roast on that host.\nAsk the superuser to add you to the allow-list."), 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(_("Warning:"), _("No root configuration file found or not readable!\nThe superuser must start and configure X-CD-Roast\nfirst, before other users can use it."), T_OK);
			gtk_exit(1);
		}
	}

#if !(defined(__MACH__) && defined(__APPLE__)) && (USE_NONROOTMODE == 1)
	/* 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(_("Warning:"), _("No privileges to start X-CD-Roast.\n\nYou have to login as the root user the first time and\nstart X-CD-Roast to enable its Non-Root-Mode, which\nwill allow that any user can start it."), T_OK);
		gtk_exit(1);
	}
#endif 

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

	if (isProDVD) {
		if (ignoreProDVD) {
			isProDVD = 0;
			dodebug(1,"-> cdrecord.ProDVD detected but disabled\n");
		} else {	
			dodebug(1,"-> cdrecord.ProDVD detected\n");
		}
	} else {
		dodebug(1,"-> cdrecord.ProDVD not detected\n");
	}
	if (support_ontheflyaudio == 1) {
		dodebug(1, "   Enabled support for on-the-fly audio\n");

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

	/* any options given with -f? */
	parse_alt_devs(alt_dev_string);

#if 0
	/* device scanning moved into main.c */	
	toplevel = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_widget_realize(toplevel);
	create_device_scanning(altdevscan, 0, 1, NULL);
	gtk_widget_destroy(toplevel);
#endif

	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();
	imagelist = (GList *) NULL;
	writelist = (GList *) NULL;
	tocfiles = (GList *) NULL;
	strcpy(xcdroast_version_loaded, "");

	curset.isProDVD = isProDVD;
	curset.support_ontheflyaudio = support_ontheflyaudio;

	/* 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);

	/* load write options if available */
	g_snprintf(tmp,MAXLINE,"%s/%s", configdir, WRITEOPTFILE);
	load_writeoptions_file(tmp);

	/* 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__)) && (USE_NONROOTMODE == 1)
	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(_("Warning:"), _("No root configuration file found or not readable!\nThe superuser must start and configure X-CD-Roast\nfirst, before other users can use it."), 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 (strcmp(setupdata.language, "") != 0) {
		g_free(language);
	        language = g_strdup(setupdata.language);
#ifdef HAVE_SETLOCALE
		setlocale (LC_ALL, language);
		setlocale (LC_NUMERIC, "C");
		dodebug(3, "Setting language to %s\n", language);
#endif
       	}

	/* 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, _("The root configuration file is not owned by root!\nAborting..."), 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(_("Warning:"), _("Access denied!\nYou have no permission to start X-CD-Roast on that host.\nAsk the superuser to add you to the allow-list."), T_OK);
			gtk_exit(1);
		}
	}

#endif

	/* tmp dir writeable? */
	if (is_dir_writeable(TMP_XCDR_DIR) == 1) {
		toplevel = gtk_window_new(GTK_WINDOW_TOPLEVEL);
		gtk_widget_realize(toplevel);
		g_snprintf(tmp,MAXLINE,_("The temporary directory \"%s\" is not writeable.\nAborting..."), TMP_XCDR_DIR);
		show_dialog(ICO_WARN, tmp, T_OK, NULL, NULL, 0);
		gtk_exit(1);
	} else {
		/* writeable - but how many space free? */
		if (get_free_space(TMP_XCDR_DIR, NULL) == 0) {
			toplevel = gtk_window_new(GTK_WINDOW_TOPLEVEL);
			gtk_widget_realize(toplevel);
			g_snprintf(tmp,MAXLINE,_("No free space in the temporary directory \"%s\".\nAborting..."), TMP_XCDR_DIR);
			show_dialog(ICO_WARN, tmp, T_OK, NULL, NULL, 0);
			gtk_exit(1);
		}
	}

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

#if (defined(__MACH__) && defined(__APPLE__)) || (USE_NONROOTMODE == 0)
	/* load user config on osX always */
	usercnf = load_setup_config(tmp,0);

#if !(defined(__MACH__) && defined(__APPLE__)) && (USE_NONROOTMODE == 0) 
	/* no config yet? */
	if (usercnf == 1) {
		/* if nonrootmode was disabled warn user */
		toplevel = gtk_window_new(GTK_WINDOW_TOPLEVEL);
		gtk_widget_realize(toplevel);
		if (isroot()) {
			show_fancy_dialog(_("Warning:"), _("This copy of X-CD-Roast has been compiled without\nnon-root-support. If you want to use X-CD-Roast without entering\nthe root-password, you have to install a fully enabled version.\n\nVisit http://www.xcdroast.org for more information."), T_OK);
		} else {
			show_fancy_dialog(_("Warning:"), _("This copy of X-CD-Roast has been compiled without\nnon-root-support. Therefore you will not be able to use it as\nnon-root user unless you have take special precautions. It is\nrecommended that you install a fully enabled version.\n\nVisit http://www.xcdroast.org for more information."), T_OK);
		}
		gtk_widget_destroy(toplevel);
	}
#endif
#else 
	if (!isroot()) {
		/* load only when not root */
		usercnf = load_setup_config(tmp,0);
	} else {
		usercnf = 0;
	}
#endif

	if (curset.isProDVD == 1) {
		/* set key if we got one from the config-file */
		if (strcmp(setupdata.ProDVDkey,"")) {

#if defined(HAVE_SETENV) && HAVE_SETENV == 1
			setenv("CDR_SECURITY", setupdata.ProDVDkey, 1);
#else 
			g_snprintf(security_key,MAXLINE,"CDR_SECURITY=%s", 
				setupdata.ProDVDkey);
			putenv(security_key);
#endif
		}
	}

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

		/* set language to the one in user-config */
        	if (strcmp(setupdata.language, "") != 0) {
			g_free(language);
	        	language = g_strdup(setupdata.language);

#ifdef HAVE_SETLOCALE
			setlocale (LC_ALL, language);
			setlocale (LC_NUMERIC, "C");
			dodebug(3, "Setting language to %s\n", language);
#endif
       		}
		return 0;
	} else {
		/* load failed */
		strcpy(xcdroast_version_loaded,"");
		return 1;
	}
}

