mc burn patch, version 0.2
- From: Bart Friederichs <bart friesoft nl>
- To: mc-devel gnome org, andy smile org ua
- Cc:
- Subject: mc burn patch, version 0.2
- Date: Thu, 11 Nov 2004 17:16:43 +0100
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]