mc burn patch, version 0.2



A few years ago (2001) I wrote a patch to enable cd-writing in mc. I got an email from Andy Shevchenko, with some additions to it.. It now patches mc-4.6.1-pre1 and the saving of settings works.

Attached the patch for mcburn 0.2

Regards,
Bart
diff -rauN mc-4.6.1-pre1.orig/mc.spec mc-4.6.1-pre1-mcburn/mc.spec
--- mc-4.6.1-pre1.orig/mc.spec	2003-12-24 18:18:04.000000000 +0100
+++ mc-4.6.1-pre1-mcburn/mc.spec	1970-01-01 01:00:00.000000000 +0100
@@ -1,238 +0,0 @@
-# Conditional build (replace "#" with "%" to enable):
-#
-#define _with_ncurses		 1 # use ncurses
-#define _with_included_slang	 1 # use included S-Lang library
-#define _with_charset		 1 # enable code for charset conversion
-#define _with_samba		 1 # enable SMB/CIFS virtual file system
-#define _with_ext2undel		 1 # compile with ext2 undelete code
-#define _without_x		 1 # avoid dependency on X11 libraries
-
-# Note that this is NOT a relocatable package
-%define ver     4.6.1-pre1
-%define rpmver   4.6.1pre1
-%define  RELEASE 1
-%define  rel     %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE}
-
-Summary:   Midnight Commander visual shell
-Name:      mc
-Version:   %rpmver
-Release:   %rel
-Epoch:     1
-Copyright: GPL
-Group:     Applications/File
-Source0:   ftp://ftp.ibiblio.org/pub/Linux/utils/file/managers/mc/mc-%{ver}.tar.gz
-URL:       http://www.ibiblio.org/mc/
-BuildRoot: /var/tmp/mc-%{PACKAGE_VERSION}-root
-BuildRequires: glib-devel
-%{!?_with_included_slang:%{!?_with_ncurses:BuildRequires: slang-devel}}
-%{?_with_ncurses:BuildRequires: ncurses-devel}
-
-%description
-GNU Midnight Commander is a visual file manager.  It's a feature rich
-full-screen text mode application that allows you to copy, move and
-delete files and whole directory trees, search for files and run
-commands in the subshell.  Internal viewer and editor are included.
-Mouse is supported under X Window System and on Linux console.  VFS
-(Virtual Filesystem) allows you to view archives and files on remote
-servers.
-
-%prep
-%setup -q -n mc-%{ver}
-
-%build
-CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="-s" ./configure \
-	--prefix=%{_prefix} \
-	--mandir=%{_mandir} \
-%{?_with_ncurses: --with-screen=ncurses} \
-%{?_with_included_slang: --with-screen=mcslang} \
-%{?_with_charset: --enable-charset} \
-%{?_with_samba: --with-samba} \
-%{?_with_ext2undel: --with-ext2undel} \
-%{?_without_x: --without-x}
-
-make
-
-%install
-echo $RPM_BUILD_ROOT
-rm -rf $RPM_BUILD_ROOT
-make install DESTDIR=$RPM_BUILD_ROOT
-install -d $RPM_BUILD_ROOT/etc/profile.d
-cp -f $RPM_BUILD_ROOT%{_prefix}/share/mc/bin/mc.{csh,sh} \
-	$RPM_BUILD_ROOT/etc/profile.d
-
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%defattr(-, root, root)
-
-%doc FAQ COPYING NEWS README
-%{_prefix}/bin/mc
-%{_prefix}/bin/mcedit
-%{_prefix}/bin/mcview
-%{_prefix}/bin/mcmfmt
-%{_prefix}/lib/mc/cons.saver
-%{_mandir}/man1/*
-%{_mandir}/*/man1/*
-
-%config /etc/profile.d/*
-%{_prefix}/share/mc/cedit.menu
-%{_prefix}/share/mc/edit.indent.rc
-%{_prefix}/share/mc/edit.spell.rc
-%{_prefix}/share/mc/bin/*
-%{_prefix}/share/mc/extfs/*
-%{_prefix}/share/mc/mc.ext
-%{_prefix}/share/mc/mc.lib
-%{_prefix}/share/mc/mc.menu*
-%{?_with_charset:%config %{_prefix}/share/mc/mc.charsets}
-
-%{_prefix}/share/mc/mc.hint*
-%{_prefix}/share/mc/mc.hlp*
-%{_prefix}/share/mc/syntax/*
-%{_prefix}/share/locale/*/LC_MESSAGES/*
-
-%dir %{_prefix}/lib/mc
-%dir %{_prefix}/share/mc
-%dir %{_prefix}/share/mc/extfs
-%dir %{_prefix}/share/mc/syntax
-
-%changelog
-* Tue Sep 23 2003 Pavel Roskin <proski gnu org>
-- Remove term directory, it's obsolete and irrelevant on modern systems.
-- Include translated menu files.
-
-* Sun Feb 16 2003 Pavel Roskin <proski gnu org>
-- Remove obsolete dependency on /sbin/chkconfig.
-
-* Tue Dec 24 2002 Pavel Roskin <proski gnu org>
-- Work around bug in rpm 4.1 that expands defines in comments.
-- Handle --without-x.
-
-* Mon Nov 04 2002 Andrew V. Samoilov <sav bcs zp ua>
-- Handle --with ext2undel.
-
-* Fri Nov 01 2002 Pavel Roskin <proski gnu org>
-- Add wrappers to support setting last directory on exit.  Keep all
-  scripts in their original directory, just copy them.
-
-* Tue Oct 22 2002 Pavel Roskin <proski gnu org>
-- Don't use the included S-Lang, there is a workaround for Red Hat 8.0
-  S-Lang, and binary compatibility with Red Hat 7.x doesn't work anyway.
-
-* Tue Oct 08 2002 Pavel Roskin <proski gnu org>
-- Use the included S-Lang again, since we include a better version now.
-  This should avoid incompatibility with Red Hat 7.x.
-- Add _with_glib2 option.
-
-* Mon Oct 07 2002 Pavel Roskin <proski gnu org>
-- Remove installed mc.sh and mc.csh from %{_prefix}/share/mc/bin to
-  suppress a warning about installed but unpackaged files.
-
-* Mon Sep 30 2002 Andrew V. Samoilov <sav bcs zp ua>
-- Don't require slang-devel if _with_ncurses.
-- Handle --with samba.
-
-* Sun Sep 29 2002 Pavel Roskin <proski gnu org>
-- Use --with-screen instead of --with-ncurses and --with-included-slang.
-
-* Mon Sep 23 2002 Andrew V. Samoilov <sav bcs zp ua>
-- Restore %config for %{_prefix}/share/mc/mc.charsets.
-- Restore %{_prefix}/share/mc/edit.spell.rc.
-
-* Sat Sep 21 2002 Pavel Roskin <proski gnu org>
-- Use FHS-compliant paths.
-- Drop %config from files under /usr/share - users are not supposed to
-  edit them.  Local copies under ~/.mc should be used for that.
-
-* Wed Aug 21 2002 Pavel Roskin <proski gnu org>
-- Change description, update URLs, allow dash in the version.
-
-* Tue Aug 20 2002 Pavel Roskin <proski gnu org>
-- Support conditional builds.
-
-* Tue Aug 20 2002 Andrew V. Samoilov <sav bcs zp ua>
-- Add /usr/lib/mc/mc.charsets.
-- Add %{_mandir}/*/man1/*.
-
-* Fri Aug 16 2002 Pavel Roskin <proski gnu org>
-- Remove mc.global.
-
-* Mon Jan 21 2002 Pavel Roskin <proski gnu org>
-- Remove --with-gnome and --with-included-slang from configure options.
-- Add BuildPrereq.
-
-* Fri Aug 24 2001 Pavel Roskin <proski gnu org>
-- Remove gmc.  Reunite mc and mc-common.
-
-* Sun Aug 05 2001 Pavel Roskin <proski gnu org>
-- Set epoch.
-
-* Sun Jul 15 2001 Pavel Roskin <proski gnu org>
-- Remove /usr/lib/mc/layout.
-
-* Sat Jun 09 2001 Pavel Roskin <proski gnu org>
-- Use %{_prefix} and %{_mandir}. Specify --mandir to configure.
-
-* Fri May 25 2001 Pavel Roskin <proski gnu org>
-- Change groups. Don't include locale directories. More config files.
-
-* Sun May 20 2001 Pavel Roskin <proski gnu org>
-- Don't require stylesheets, since HTML files are now in the tarball.
-
-* Thu Apr 19 2001 Pavel Roskin <proski gnu org>
-- Remove package mcserv. Drop dependency on PAM.
-
-* Mon Feb 26 2001 Pavel Roskin <proski gnu org>
-- Remove mc-gnome.ext.
-
-* Thu Jan 11 2001 Pavel Roskin <proski gnu org>
-- Include mcview.
-
-* Mon Oct 23 2000 Pavel Roskin <proski gnu org>
-- Allow mcserv.8 to be gzipped.
-
-* Sat Sep 30 2000 Pavel Roskin <proski gnu org>
-- New package mc-common.
-- Use DESTDIR instead of misusing prefix.
-- Don't install old icons - they don't exist
-
-* Sat Sep 23 2000 Pavel Roskin <proski gnu org>
-- Include translations with mc, not gmc
-- chkconfig --del in %preun, not %postun
-- --without-debug not needed
-- /etc/X11/wmconfig not needed
-- /etc/pam.d/mcserv shouldn't be executable
-- New files in %{prefix}/lib/mc/ - translated hints, editor files
-
-* Thu Sep 09 1999 Elliot Lee <sopwith redhat com>
-- Include .idl files in the package.
-
-* Sat Sep 04 1999 Gregory McLean <gregm comstar net>
-- Added a build prereq so that rpms get built with documentation ;)
-
-* Mon Jul 12 1999 Kjartan Maraas  <kmaraas online no>
-- added help and locale files to %files
-
-* Tue Jun 22 1999 Vladimir Kondratiev <vkondra iil intel com>
-- added syntax files to %files
-
-* Wed May 26 1999 Cody Russell <bratsche dfw net>
-- chmod cons.saver at $RPM_BUILD_ROOT%{prefix}/lib rather than at
-  $RPM_BUILD_ROOT/usr/lib. We can now install to somewhere other than /usr.
-
-* Sun Apr 18 1999 Gregory McLean <gregm comstar net>
-- Updated the specfile, removed some kludges.
-
-* Thu Aug 20 1998 Michael Fulbright <msf redhat com>
-- rebuilt against gnome-libs 0.27 and gtk+-1.1
-
-* Thu Jul 09 1998 Michael Fulbright <msf redhat com>
-- made cons.saver not setuid
-
-* Sun Apr 19 1998 Marc Ewing <marc redhat com>
-- removed tkmc
-
-* Wed Apr 8 1998 Marc Ewing <marc redhat com>
-- add /usr/lib/mc/layout to gmc
-
diff -rauN mc-4.6.1-pre1.orig/src/Makefile.am mc-4.6.1-pre1-mcburn/src/Makefile.am
--- mc-4.6.1-pre1.orig/src/Makefile.am	2003-11-27 19:06:57.000000000 +0100
+++ mc-4.6.1-pre1-mcburn/src/Makefile.am	2004-11-11 16:08:00.000000000 +0100
@@ -52,6 +52,7 @@
 	glibcompat.c glibcompat.h global.h help.c help.h hotlist.c	\
 	hotlist.h info.c info.h key.c key.h keyxdef.c layout.c		\
 	layout.h learn.c learn.h listmode.c listmode.h main.c main.h	\
+	mcburn.h mcburn.c	\
 	menu.c menu.h mountlist.c mountlist.h mouse.c mouse.h myslang.h	\
 	option.c option.h panel.h panelize.c panelize.h poptalloca.h	\
 	popt.c poptconfig.c popt.h popthelp.c poptint.h poptparse.c	\
diff -rauN mc-4.6.1-pre1.orig/src/Makefile.in mc-4.6.1-pre1-mcburn/src/Makefile.in
--- mc-4.6.1-pre1.orig/src/Makefile.in	2003-12-24 18:15:11.000000000 +0100
+++ mc-4.6.1-pre1-mcburn/src/Makefile.in	2004-11-11 16:12:07.000000000 +0100
@@ -80,6 +80,7 @@
 	global.h help.c help.h hotlist.c hotlist.h info.c info.h key.c \
 	key.h keyxdef.c layout.c layout.h learn.c learn.h listmode.c \
 	listmode.h main.c main.h menu.c menu.h mountlist.c mountlist.h \
+	mcburn.h mcburn.c \
 	mouse.c mouse.h myslang.h option.c option.h panel.h panelize.c \
 	panelize.h poptalloca.h popt.c poptconfig.c popt.h popthelp.c \
 	poptint.h poptparse.c profile.c profile.h regex.c rxvt.c \
@@ -96,7 +97,7 @@
 	glibcompat.$(OBJEXT) help.$(OBJEXT) hotlist.$(OBJEXT) \
 	info.$(OBJEXT) key.$(OBJEXT) keyxdef.$(OBJEXT) \
 	layout.$(OBJEXT) learn.$(OBJEXT) listmode.$(OBJEXT) \
-	main.$(OBJEXT) menu.$(OBJEXT) mountlist.$(OBJEXT) \
+	main.$(OBJEXT) menu.$(OBJEXT) mountlist.$(OBJEXT) mcburn.$(OBJEXT) \
 	mouse.$(OBJEXT) option.$(OBJEXT) panelize.$(OBJEXT) \
 	popt.$(OBJEXT) poptconfig.$(OBJEXT) popthelp.$(OBJEXT) \
 	poptparse.$(OBJEXT) profile.$(OBJEXT) regex.$(OBJEXT) \
diff -rauN mc-4.6.1-pre1.orig/src/main.c mc-4.6.1-pre1-mcburn/src/main.c
--- mc-4.6.1-pre1.orig/src/main.c	2003-11-14 21:43:12.000000000 +0100
+++ mc-4.6.1-pre1-mcburn/src/main.c	2004-11-11 16:09:09.000000000 +0100
@@ -94,6 +94,8 @@
 
 #include "popt.h"
 
+#include "mcburn.h"             /* the CD recording extensions */
+
 /* When the modes are active, left_panel, right_panel and tree_panel */
 /* Point to a proper data structure.  You should check with the functions */
 /* get_current_type and get_other_type the types of the panels before using */
@@ -873,6 +875,7 @@
     {' ', N_("&Compare directories  C-x d"), 'C', compare_dirs_cmd},
     {' ', N_("e&Xternal panelize    C-x !"), 'X', external_panelize},
     {' ', N_("show directory s&Izes"), 'I', dirsizes_cmd},
+    {' ', N_("B&urn this dir to CD"), 'u', do_burn},
     {' ', "", ' ', 0},
     {' ', N_("command &History"), 'H', history_cmd},
     {' ', N_("di&Rectory hotlist    C-\\"), 'R', quick_chdir_cmd},
@@ -903,6 +906,7 @@
 /* Must keep in sync with the constants in menu_cmd */
 static menu_entry OptMenu[] = {
     {' ', N_("&Configuration..."), 'C', configure_box},
+    {' ', N_("CD B&urning config..."), 'u', burn_config},
     {' ', N_("&Layout..."), 'L', layout_cmd},
     {' ', N_("c&Onfirmation..."), 'O', confirm_box},
     {' ', N_("&Display bits..."), 'D', display_bits_box},
diff -rauN mc-4.6.1-pre1.orig/src/mcburn.c mc-4.6.1-pre1-mcburn/src/mcburn.c
--- mc-4.6.1-pre1.orig/src/mcburn.c	1970-01-01 01:00:00.000000000 +0100
+++ mc-4.6.1-pre1-mcburn/src/mcburn.c	2004-11-11 16:09:18.000000000 +0100
@@ -0,0 +1,716 @@
+// mcburn.c
+// Function definitions for cdrecord support in Midnight Commander
+// Copyright 2001 Bart Friederichs
+
+/* 
+ * TODO for future versions
+ * - Beautify the burn dialog so that it looks like all dialogs in mc.
+ * - Build in multi-burner/cdrom support
+ * - Check for enough drive space for image in $HOME_DIR
+ */
+
+// inclusions copy-paste from main.c
+#include "layout.h"
+#include <config.h>
+#include <string.h>
+#include <stdio.h>
+/* Needed for the extern declarations of integer parameters */
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
+#   include <unistd.h>
+#endif
+#include "global.h"
+#include "tty.h"
+#include "win.h"
+#include "color.h"
+#include "widget.h"
+#include "setup.h"		/* For save_setup() */
+#include "dialog.h"		/* For do_refresh() */
+#include "main.h"
+#include "profile.h"		/* For sync_profiles */
+
+#include "dir.h"
+#include "panel.h"		/* Needed for the externs */
+#include "file.h"
+#include "layout.h"		/* For nice_rotating_dash */
+#include "option.h"
+// end of copy-paste
+
+#include "mcburn.h"
+#include "wtools.h"
+#include "execute.h"
+
+
+#define TOGGLE_VARIABLE 0
+#define INPUT_VARIABLE 1
+
+/* Burner options box coords */
+#define BX	4
+#define BY	2
+
+/* Filesystem option box coords */
+#define FY	2
+
+/* widget types */
+#define CHECKBOX	1
+#define INPUT		2
+
+/* option category */
+#define BURNER		1
+#define FS			2
+
+static const char* configfile = "/.mc/mcburn.conf";             /* watch it! $HOME_DIR will be prepended to this path */
+
+// global settings
+int interimage = 1;
+int dummyrun = 0;
+int joliet = 1;
+int rockridge = 1;
+int multi = 1;
+int speed = 2;
+int scsi_bus = -1, scsi_id = -1, scsi_lun = -1;
+char *cdwriter = NULL;
+
+static int burner_option_width = 0, fs_option_width = 0;
+static int FX = 0;
+static char *burn_options_title, *burner_title, *fs_title;
+static Dlg_head *burn_conf_dlg;
+static Dlg_head *burn_dlg;
+static char *burndir;
+static char *cdrecord_path;
+static char *mkisofs_path;
+static int burner_options, fs_options;			/* amount of burner and fs options */
+
+/* one struct with all burner settings */
+static struct {
+	char *text;
+	int *variable;
+	int type;				/* CHECKBOX, INPUT */
+	int category;			/* BURNER, FS */
+	WCheck *w_check;
+	WInput *w_input;
+	char *tk;
+	char *description;
+	
+	/* only applicable for the input widget; shoot me for the overhead */
+	int i_length;
+} options[] = {
+    {N_("make &Intermediate image"),  &interimage, CHECKBOX, BURNER, NULL, NULL, "interimage", "Make intermediate image", 0 },
+    {N_("&Dummy run"), &dummyrun, CHECKBOX, BURNER, NULL, NULL, "dummyrun", "Turn the laser off", 0 },
+    {N_("&Multisession CD"), &multi, CHECKBOX, BURNER, NULL, NULL, "multi", "Create a multi-session CD", 0 },	
+	{N_("Speed"), &speed, INPUT, BURNER, NULL, NULL, "speed", "Speed", 3 },
+	{N_("&Joliet extensions"), &joliet, CHECKBOX, FS, NULL, NULL, "joliet", "Use Joliet extensions", 0},
+    {N_("&RockRidge extensions"), &rockridge, CHECKBOX, FS, NULL, NULL, "rockridge", "Use RockRidge extensions", 0},
+	{0,0,0,0}
+};
+
+/* return a string that is a concatenation of s1 and s2 */
+char *concatstrings(const char *s1, const char *s2) {
+	char *temp = NULL;
+	int length = 0;
+	
+	length = strlen(s1) + strlen(s2) + 1;
+	temp = malloc(length*sizeof(char));
+	
+	strcpy(temp, s1);
+	strcat(temp, s2);
+	
+	return(temp);	
+}
+
+/* check for program and return a pointer to a string containing the full path */
+char *check_for(char *program) {
+	char *command;
+	FILE *output;
+
+	char buffer[1024];
+	char *fullpath;
+
+	command = malloc( (strlen(program) + 11) * sizeof(char));
+	strcpy(command, "which ");
+	strcat(command, program);
+	strcat(command, " 2>&1");
+
+	if (!(output = popen(command, "r")) )
+	{
+			message (0, "Error ", "An error occurred checking for program (popen failed)");
+			return NULL;
+	}
+
+	while (!feof(output))
+			fgets(buffer, 1024, output);
+
+	/* remove newline from buffer */
+	buffer[strlen(buffer)-1] = '\0';
+
+	/* not starting with '/' means it is not found */
+	if (buffer[0] != '/')
+		return NULL;
+
+	fullpath = malloc( (strlen(buffer)+1)	* sizeof(char) );
+	strncpy(fullpath, buffer, strlen(buffer)+1);
+
+  pclose(output);
+	return fullpath;
+}
+
+/* this lets the user choose a dir and burn that dir, with the
+   current options */
+void do_burn ()
+{
+		char buffer[1024];
+
+		// make sure cdrecord and mkisofs is available, and get their full path
+		if (!(mkisofs_path = check_for("mkisofs")))
+		{
+     		message (0, " Error ", "Couldn't find mkisofs");
+				return;
+		}
+
+		if (!(cdrecord_path = check_for("cdrecord")))
+		{
+				message (0, " Error ", "Couldn't find cdrecord");
+				return;
+		}
+
+		if (!strcmp(current_panel->dir.list[current_panel->selected].fname, ".."))
+		{
+			message(0, " Error ", "You can't burn the parent-directory");
+			return;
+		}
+
+    burndir = concat_dir_and_file(current_panel->cwd, current_panel->dir.list[current_panel->selected].fname);
+
+    if (!S_ISDIR(current_panel->dir.list[current_panel->selected].st.st_mode))
+    {
+			message(0, " Error ", "You can't burn a single file to CD");
+			return;
+    }
+    else
+    {
+			if (!scan_for_recorder(cdrecord_path)) {
+				sprintf(buffer, "No CD-Writer found");
+				message(0, " Error ", buffer);
+				return;
+			} 
+
+			init_burn();					/* initialize the burn dialog */
+			run_dlg(burn_dlg);				/* run the dialog */
+			destroy_dlg(burn_dlg);			/* and throw it away after usage */
+			
+			if (burn_dlg->ret_value == B_ENTER) {
+				/* here, the actual burning takes place 
+				 * construct a (series of) command(s) to execute 
+				 */
+				
+				sprintf(buffer, "echo \"Burning %s to CD ...\"", burndir);
+				shell_execute(buffer,EXECUTE_INTERNAL);
+				
+				/** continue here
+				 ** 1. make a mkisofs command
+				 ** 2. make a cdrecord command
+				 ** 3. pipe them if necessary (!interimage)
+				 ** 4. run consecutively if necessary (interimage)
+				 ** NOTE: dummyrun is NOT before writing, its just a dummy run (nice for testing purposes)
+				 **/
+				
+				/* STEP 1: create an image if the user wants to. Put the image in $HOMEDIR
+				 * it's the user's responsibility to make sure the is enough room (TODO 3)
+				 * this is where the fs-options come in, using -r for RockRidge and -J for Joliet extensions
+				 */
+				if (interimage) {
+					sprintf(buffer, "echo \"Building image...\"");
+					shell_execute(buffer, EXECUTE_INTERNAL);
+					strcpy(buffer, mkisofs_path);
+					if (rockridge) strcat(buffer, " -r");
+					if (joliet) strcat(buffer, " -J");
+					strcat(buffer, " -o ");
+					strcat(buffer, home_dir);
+					strcat(buffer, "/mcburn.iso ");
+					strcat(buffer, burndir);
+					shell_execute(buffer, EXECUTE_INTERNAL);
+				}
+				
+				/* STEP 2: create a cdrecord command, this is where speed, dummy, multi and the scsi_* vars come in
+				 * also, check for an image or pipe it right into cdrecord
+				 *
+				 * STEP 2b: cdrecord without a pipe (assume the $HOME/mcburn.iso exists (TODO 4))
+				 */
+				if (interimage) {
+					sprintf(buffer, "echo \"Burning CD...\"");
+					shell_execute(buffer, EXECUTE_INTERNAL);
+					strcpy (buffer, cdrecord_path);
+					if (dummyrun) strcat(buffer, " -dummy");
+					if (multi) strcat(buffer, " -multi");
+					sprintf(buffer, "%s -v speed=%d", buffer, speed);
+					sprintf(buffer, "%s dev=%d,%d,%d", buffer, scsi_bus, scsi_id, scsi_lun);
+					sprintf(buffer, "%s -data %s/mcburn.iso", buffer, home_dir);
+					
+				} else {		/* no image present, pipe mkisofs into cdrecord */
+					/* first get the size of the image to build */
+					FILE *pipe;
+					int imagesize;
+					strcpy(buffer, "mkisofs -R -q -print-size private_collection/  2>&1 | sed -e \"s/.* = //\""); 
+					pipe = popen(buffer, "r");
+					fgets(buffer, 1024, pipe);
+					imagesize = atoi(buffer);
+					pclose(pipe);
+					
+					sprintf(buffer, "[ \"0%d\" -ne 0 ] && %s %s %s %s | %s %s %s speed=%d dev=%d,%d,%d -data -", 
+						imagesize, mkisofs_path, rockridge?" -r":"", joliet?" -J":"", burndir, cdrecord_path, dummyrun?" -dummy":"", multi?" -multi":"", 
+						speed, scsi_bus, scsi_id, scsi_lun);
+				}
+				
+				/* execute the burn command */
+				shell_execute(buffer, EXECUTE_INTERNAL);
+				
+			}
+	}
+}
+
+/* scan for CD recorder 
+   This functions executes 'cdrecord -scanbus' and checks the output for 'CD-ROM'. It gets the first occurrence.
+   In the future, it should give all available CD-ROMs so that the user can choose from them
+   Also, the bus, id and lun received from the line can be wrong.
+
+   return 1 if a recorder is found, 0 otherwise
+*/
+int scan_for_recorder (char *cdrecord_command)
+{
+	char *command;
+	char buffer[1024];
+	FILE *output;
+
+	command = calloc( (strlen(cdrecord_command)+15), sizeof(char) );
+	strncpy(command, cdrecord_command, strlen(cdrecord_command));
+	strcat(command, " -scanbus 2>&1");
+
+	if (!(output = popen(command, "r")) )
+	{
+			message (0, "Error ", "An error occurred scanning for writers (popen failed)");
+			return 0;
+	}
+
+	while (!feof(output)) {
+			int i = -1;
+
+			fgets(buffer, 1024, output);
+
+			/* remove newline from buffer */
+			buffer[strlen(buffer)-1] = '\0';
+
+			for (i=0; i < strlen(buffer); i++)
+				if (buffer[i] == '\'') break;
+
+			/* parse all lines from 'cdrecord -scanbus'
+         and select the first CD-ROM */
+      	if (buffer[0] == '\t' && strstr(buffer, "CD-ROM")) {
+				/* this is a scsi cdrom player in this line */
+				scsi_bus = buffer[1] - 48;
+				scsi_id = buffer[3] - 48;
+				scsi_lun = buffer[5] - 48;
+
+				/* free the memory first, before allocating new */
+				if (cdwriter) free(cdwriter);
+				cdwriter = calloc(26, sizeof(char));
+				strncpy(cdwriter, &buffer[i+1], 8);
+				strcat(cdwriter, " ");
+				strncat(cdwriter, &buffer[i+12], 16);
+
+				break;										/* remove this to select _last_ occurence, i should make a menu where the user can choose */
+		}
+	}
+
+	free(command);
+	pclose(output);
+	
+	/* if the scsi_* vars are still -1, no recorder was found */
+	if (scsi_lun == -1) return 0;
+	else return 1;
+}
+
+/* the burn dialog box message handler 
+ * the burn dialog could use some better layout
+ */
+static cb_ret_t burn_callback (struct Dlg_head *h, dlg_msg_t Msg, int parm)
+{
+	int i, line=4;
+	char buffer[1025];
+	
+    switch (Msg) {
+    case DLG_DRAW:
+#ifndef HAVE_X
+			attrset (COLOR_NORMAL);
+			dlg_erase (h);
+			draw_box (h, 0, 0, h->lines, h->cols);
+
+			dlg_move (h, 1, 1);
+			addstr(_("directory:"));
+	
+			attrset (COLOR_YELLOW);
+			dlg_move (h, 1, 11);
+			addstr(burndir);
+			attrset (COLOR_NORMAL);
+			
+			dlg_move (h, 3, 1);
+			addstr(_("settings:"));
+
+			// run through all options
+			for (i = 0; options[i].tk; i++)
+			{
+				switch (options[i].type) {
+					case CHECKBOX:
+						if (*options[i].variable == 1)
+						{
+							dlg_move(h, line, 1);
+							addstr(_("- "));
+							dlg_move(h, line++, 4);
+							addstr(options[i].description);
+						}
+						break;
+					case INPUT:
+						dlg_move(h, line, 1);
+						addstr(options[i].description);
+						dlg_move(h, line++, strlen(options[i].description) + 2);
+						sprintf(buffer, "%d", *options[i].variable);
+						addstr(buffer);
+						break;
+					default:
+						break;
+				}
+			}
+			
+#endif
+			break;
+
+    case DLG_END:
+			break;
+    default:
+			break;
+    }
+
+    return 0;
+}
+
+/* this initializes the burn dialog box
+   there will be no way back after OK'ing this one */
+void init_burn ()
+{
+	int i;
+
+	int dialog_height = 0, dialog_width = 27;
+
+    /* button titles */
+    char* burn_button = _("&Burn");
+    char* cancel_button = _("&Cancel");
+
+	/* we need the height and width of the dialog
+		 that depends on the settings */
+	for (i = 0; options[i].tk; i++)
+		switch (options[i].type) {
+			case CHECKBOX:
+    			if (*options[i].variable == 1) dialog_height++;			/* just print the setting when it is checked */
+				break;
+			case INPUT:
+				dialog_height++;										/* these are always printed */
+				break;
+			default:
+				break;
+		}
+
+	dialog_height += 7;
+		
+	if (strlen(burndir) + 12 > 27) dialog_width = strlen(burndir) + 12;
+
+    burn_dlg = create_dlg(0,0,dialog_height,dialog_width, dialog_colors, burn_callback,
+			"CD Burn", _("Burn directory to CD"),
+			DLG_CENTER);
+
+    /* add the Burn and Cancel buttons */
+    add_widget (burn_dlg, button_new(dialog_height-2,1,B_ENTER, DEFPUSH_BUTTON,
+		    burn_button, 0));
+
+    add_widget (burn_dlg, button_new(dialog_height-2,12,B_CANCEL, NORMAL_BUTTON,
+		    cancel_button, 0));
+
+}
+
+/****************************************************************************************************************************************************
+  
+															  MC-Burn options functions
+
+****************************************************************************************************************************************************/
+
+/* this shows the burn options dialog */
+void burn_config ()
+{
+    int result, i;
+
+    init_burn_config();
+
+    run_dlg(burn_conf_dlg);
+
+    /* they pushed the OK or Save button, set the variables right */
+    result = burn_conf_dlg->ret_value;
+	
+	if (result == B_ENTER || result == B_EXIT) 
+		for (i = 0; options[i].tk; i++)
+			switch (options[i].type) {
+				case CHECKBOX:
+	    			if (options[i].w_check->state & C_CHANGE) 
+		    			*options[i].variable = !(*options[i].variable);
+					break;
+				case INPUT:
+					*options[i].variable = atoi(options[i].w_input->buffer);
+					break;
+			}
+
+	/* If they pressed the save button, save the values to ~/.mc/mcburn.conf */
+    if (result == B_EXIT){
+		save_mcburn_settings();
+    }
+
+    destroy_dlg(burn_conf_dlg);
+}
+
+/* the options dialog box message handler */
+static cb_ret_t burn_options_callback (struct Dlg_head *h, dlg_msg_t Msg, int parm)
+{
+    switch (Msg) {
+    case DLG_DRAW:
+#ifndef HAVE_X
+		attrset (COLOR_NORMAL);
+		dlg_erase (h);
+
+		/* all around the dialog box box */
+		draw_box (h, 1, 2, h->lines - 2, h->cols - 4);
+
+		/* option boxes */
+		draw_box (h, BY, BX, burner_options + 2, burner_option_width);
+		draw_box (h, FY, FX, fs_options + 2, fs_option_width);
+
+		/* titles */
+		dlg_move (h, 1, (h->cols - strlen(burn_options_title))/2);
+		addstr (burn_options_title);
+		dlg_move (h, BY, BX+2);
+		addstr (burner_title);
+		dlg_move (h, FY, FX+2);
+		addstr (fs_title);
+
+#endif
+		break;
+
+    case DLG_END:
+//	r_but = Id;
+		break;
+    default:
+		break;
+    }
+    return 0;
+}
+
+
+
+/* this initializes the burn options dialog box */
+void init_burn_config ()
+{
+    int i = 0;
+    static int dialog_height = 0, dialog_width = 0;
+    static int b1, b2, b3;
+	
+    /* button title */
+    char* ok_button = _("&Ok");
+    char* cancel_button = _("&Cancel");
+    char* save_button = _("&Save");
+	register int l1;
+
+	burner_options = 0;
+	fs_options = 0;	
+	
+	/* count the amount of burner and fs options */
+	for (i=0; options[i].tk; i++) 
+		switch (options[i].category) {
+			case BURNER: 
+				burner_options++;
+				break;
+			case FS:
+				fs_options++;
+				break;
+		}
+	
+	/* similar code is in options.c */
+	burn_options_title = _(" CD-Burn options ");
+	burner_title = _(" Burner options ");
+	fs_title = _(" Filesystem options ");
+
+	/* get the widths for the burner options and the fs options */
+	burner_option_width = strlen(burner_title) + 1;
+	fs_option_width = strlen(fs_title) + 1;
+	for (i = 0; options[i].tk; i++)
+	{
+		/* make sure the whole inputfield width is accounted for */
+		if (options[i].type == INPUT) l1 = options[i].i_length;
+		else l1 = 0;
+		
+		/* calculate longest width of text */
+		if (options[i].category == BURNER) {
+			options[i].text = _(options[i].text);
+			l1 += strlen(options[i].text) + 7;
+			if (l1 > burner_option_width)
+				burner_option_width = l1;
+		}
+		
+		if (options[i].category == FS) {
+			options[i].text = _(options[i].text);
+			l1 += strlen(options[i].text) + 7;
+			if (l1 > fs_option_width)
+				fs_option_width = l1;
+		}
+			
+	}
+	
+	l1 = 11 + strlen (ok_button)
+	 	+ strlen (save_button)
+		+ strlen (cancel_button);
+
+	i = (burner_option_width + fs_option_width - l1) / 4;
+	b1 = 5 + i;
+	b2 = b1 + strlen(ok_button) + i + 6;
+	b3 = b2 + strlen(save_button) + i + 4;
+
+    dialog_width = burner_option_width + fs_option_width + 7;
+    FX = FY + burner_option_width + 2;
+
+    /* figure out the height for the burn options dialog */
+    if (burner_options > fs_options)
+		dialog_height = burner_options + 7;
+    else
+		dialog_height = fs_options + 7;
+
+    burn_conf_dlg = create_dlg(0,0,dialog_height,dialog_width, dialog_colors, burn_options_callback,
+			"CD Burn options", _("Burner options"), DLG_CENTER);
+
+    /* add the OK, Cancel and Save buttons */
+    add_widget (burn_conf_dlg, button_new(dialog_height-3,b1,B_ENTER, DEFPUSH_BUTTON,
+		    ok_button, 0));
+
+    add_widget (burn_conf_dlg, button_new(dialog_height-3,b2,B_EXIT, NORMAL_BUTTON,
+		    save_button, 0));
+
+    add_widget (burn_conf_dlg, button_new(dialog_height-3,b3,B_CANCEL, NORMAL_BUTTON,
+		    cancel_button, 0));
+
+
+    /* add the burner options */
+	for (i = 0; options[i].tk; i++) {
+		int x = 0, y = 0;
+		char *defvalue;
+		
+		/* first find out where the widget should go (burner option or fs option) */
+		switch (options[i].category) {
+			case BURNER:
+				x = BX + 1;
+				y = BY + 1 + i;
+				break;
+			case FS:
+				x = FX + 1;
+				y = FY - burner_options + 1 + i;
+				break;
+			default:
+				break;
+		}
+
+		/* then create a new widget, depending on the type 
+		 * afterwards, add it to the dialog box 				*/
+		switch (options[i].type) {
+			case CHECKBOX:
+				options[i].w_check = check_new(y, x, *options[i].variable, options[i].text);					/* here, the values are taken from the variables and put in the checkboxes */
+				add_widget(burn_conf_dlg, options[i].w_check);
+				break;
+			case INPUT:
+				defvalue = malloc((options[i].i_length + 1) * sizeof(char));	
+				snprintf(defvalue, options[i].i_length, "%d", *options[i].variable);
+			
+				add_widget(burn_conf_dlg, label_new(y, x, options[i].text));							/* a label */				
+				options[i].w_input = input_new(y, x + strlen(options[i].text) + 1, 0, options[i].i_length, defvalue, options[i].tk);	/* and the input widget behind it */
+				add_widget(burn_conf_dlg, options[i].w_input);
+				break;
+			default:
+				break;
+		}
+	}
+
+}
+
+/****************************************************************************************************************************************************
+  
+															  MC-Burn configfile functions
+
+****************************************************************************************************************************************************/
+
+/* this loads the settings from ~/.mc/mcburn.conf */
+void load_mcburn_settings ()
+{
+	FILE *mcburn_settings_file;
+	char *filename;
+	int i, setting;
+	char buff[128];
+
+	filename = malloc(strlen(home_dir)+strlen(configfile)+1);
+	strcpy (filename, home_dir);
+	strcat (filename, configfile);
+
+	printf("Loading CD Burn extension settings...");
+
+	if ((mcburn_settings_file = fopen(filename, "r")) == NULL)
+	{
+		printf("failed\n");
+	}
+	else
+	{
+		while (!feof(mcburn_settings_file))
+		{
+			fscanf(mcburn_settings_file, "%s %d", buff, &setting);
+
+			for (i = 0; options[i].tk; i++)
+			{
+			 	if (!strcmp(options[i].tk, buff))
+				{
+					*options[i].variable = setting;
+				}
+			}
+		}
+		fclose(mcburn_settings_file);
+		printf("done\n");
+	}
+}
+
+/* this saves the settings to ~/.mc/mcburn.conf */
+void save_mcburn_settings ()
+{
+	FILE *mcburn_settings_file;
+	int i;
+	char *filename;
+
+	filename = malloc(strlen(home_dir)+strlen(configfile)+1);
+	strcpy (filename, home_dir);
+	strcat (filename, configfile);
+
+	if ((mcburn_settings_file = fopen(filename, "w")) == NULL)
+	{
+		message(0, " Save failed ", filename);
+	}
+	else
+	{
+		/* first, print a message not to tamper with the file */
+		fprintf(mcburn_settings_file, "# This file is generated by MC-Burn. DO NOT EDIT!\n");
+		for (i = 0; options[i].tk; i++)
+		{
+		 	fprintf(mcburn_settings_file, "%s %d\n", options[i].tk,	*options[i].variable);
+		}
+		fclose(mcburn_settings_file);
+	}
+}
+
diff -rauN mc-4.6.1-pre1.orig/src/mcburn.h mc-4.6.1-pre1-mcburn/src/mcburn.h
--- mc-4.6.1-pre1.orig/src/mcburn.h	1970-01-01 01:00:00.000000000 +0100
+++ mc-4.6.1-pre1-mcburn/src/mcburn.h	2004-11-11 16:09:09.000000000 +0100
@@ -0,0 +1,19 @@
+// mcburn.h
+// Header file for cdrecord support in Midnight Commander
+// Copyright 2001 Bart Friederichs
+
+// Changed for CVS
+
+#ifndef __MCBURN_H
+#define __MCBURN_H
+
+void do_burn ();
+void burn_config ();
+void init_burn_config ();						/* initialize burner config dialog */
+void init_burn ();									/* initialize burner dialog */
+void load_mcburn_settings ();
+void save_mcburn_settings ();
+int scan_for_recorder(char *);
+char *concatstrings(const char *, const char *);	/* returns a string that is the concatenation of s1 and s2 */
+
+#endif
diff -rauN mc-4.6.1-pre1.orig/src/setup.c mc-4.6.1-pre1-mcburn/src/setup.c
--- mc-4.6.1-pre1.orig/src/setup.c	2003-11-08 00:50:19.000000000 +0100
+++ mc-4.6.1-pre1-mcburn/src/setup.c	2004-11-11 16:09:18.000000000 +0100
@@ -57,6 +57,7 @@
 #   include "../edit/edit.h"
 #endif
 
+#include "mcburn.h"
 
 extern char *find_ignore_dirs;
 
@@ -354,6 +355,8 @@
     		 get_codepage_id( display_codepage ), profile_name );
 #endif /* HAVE_CHARSET */
 
+    save_mcburn_settings();
+
     g_free (profile);
     saving_setup = 0;
 }
@@ -557,6 +560,8 @@
 
     init_translation_table( source_codepage, display_codepage );
 #endif /* HAVE_CHARSET */
+
+    load_mcburn_settings();
 }
 
 #if defined(USE_VFS) && defined (USE_NETCODE)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]