summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2009-01-14 22:13:47 +0100
committerChristophe Grenier <grenier@cgsecurity.org>2009-01-14 22:13:47 +0100
commit1650fe5b8b6cea638c280df13605aea816718a00 (patch)
treefed11bd9361236aba47157d859607c109db05814 /src
parent56e1c29b2c0614b0b3230946d72e1eaf37618bcc (diff)
Split ncurses text interface from functions
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am32
-rw-r--r--src/addpart.c78
-rw-r--r--src/addpart.h23
-rw-r--r--src/adv.c19
-rw-r--r--src/analyse.c101
-rw-r--r--src/analyse.h1
-rw-r--r--src/askloc.c471
-rw-r--r--src/askloc.h30
-rw-r--r--src/bfs.c1
-rw-r--r--src/bsd.c1
-rw-r--r--src/chgtype.c385
-rw-r--r--src/chgtype.h5
-rw-r--r--src/chgtypen.c439
-rw-r--r--src/chgtypen.h31
-rw-r--r--src/common.h1
-rw-r--r--src/cramfs.c1
-rw-r--r--src/dimage.c5
-rw-r--r--src/dir.c428
-rw-r--r--src/dir.h8
-rw-r--r--src/dirn.c463
-rw-r--r--src/dirn.h33
-rw-r--r--src/dirpart.c15
-rw-r--r--src/ext2.c1
-rw-r--r--src/ext2_sbn.c135
-rw-r--r--src/ext2_sbn.h30
-rw-r--r--src/ext2grp.c5
-rw-r--r--src/ext2p.c25
-rw-r--r--src/fat.c155
-rw-r--r--src/fat.h4
-rw-r--r--src/fat1x.c2
-rw-r--r--src/fat32.c6
-rw-r--r--src/fat_adv.c70
-rw-r--r--src/fatn.c133
-rw-r--r--src/fatn.h36
-rw-r--r--src/file_jpg.h6
-rw-r--r--src/file_list.c345
-rw-r--r--src/filegen.c115
-rw-r--r--src/fnctdsk.c1
-rw-r--r--src/geometry.c2
-rw-r--r--src/geometry.h30
-rw-r--r--src/godmode.c30
-rw-r--r--src/hdcache.c1
-rw-r--r--src/hdwin32.c1
-rw-r--r--src/hfsp.c1
-rw-r--r--src/hidden.c79
-rw-r--r--src/hidden.h9
-rw-r--r--src/hiddenn.c87
-rw-r--r--src/hiddenn.h30
-rw-r--r--src/intrf.c1783
-rw-r--r--src/intrf.h12
-rw-r--r--src/intrface.c15
-rw-r--r--src/intrface.h7
-rw-r--r--src/intrfn.c1313
-rw-r--r--src/intrfn.h13
-rw-r--r--src/io_redir.c1
-rw-r--r--src/log.c105
-rw-r--r--src/log.h16
-rw-r--r--src/log_part.c43
-rw-r--r--src/log_part.h33
-rw-r--r--src/msdos.c1
-rw-r--r--src/nodisk.c87
-rw-r--r--src/nodisk.h29
-rw-r--r--src/ntfs_adv.c22
-rw-r--r--src/ntfs_udl.c3
-rw-r--r--src/ntfs_utl.c1
-rw-r--r--src/ntfsp.c23
-rw-r--r--src/partauto.c1
-rw-r--r--src/partgpt.c114
-rw-r--r--src/partgpt.h7
-rw-r--r--src/partgptn.c160
-rw-r--r--src/partgptn.h30
-rw-r--r--src/parti386.c159
-rw-r--r--src/parti386.h31
-rw-r--r--src/parti386n.c168
-rw-r--r--src/parti386n.h30
-rw-r--r--src/partmac.c147
-rw-r--r--src/partmac.h9
-rw-r--r--src/partmacn.c153
-rw-r--r--src/partmacn.h32
-rw-r--r--src/partnone.c2
-rw-r--r--src/partsun.c110
-rw-r--r--src/partsun.h30
-rw-r--r--src/partsunn.c121
-rw-r--r--src/partsunn.h30
-rw-r--r--src/partxbox.c117
-rw-r--r--src/partxbox.h9
-rw-r--r--src/partxboxn.c128
-rw-r--r--src/partxboxn.h30
-rw-r--r--src/pbanner.c44
-rw-r--r--src/pdisksel.c21
-rw-r--r--src/pfree_whole.h8
-rw-r--r--src/phmain.c363
-rw-r--r--src/photorec.c745
-rw-r--r--src/photorec.h9
-rw-r--r--src/phrecn.c83
-rw-r--r--src/phrecn.h10
-rw-r--r--src/ppartsel.c20
-rw-r--r--src/ppartsel.h8
-rw-r--r--src/rfs.c1
-rw-r--r--src/sun.c2
-rw-r--r--src/sysv.c1
-rw-r--r--src/tanalyse.c11
-rw-r--r--src/tbanner.c44
-rw-r--r--src/tdiskop.c2
-rw-r--r--src/tdisksel.c11
-rw-r--r--src/testdisk.c55
-rw-r--r--src/thfs.c8
-rw-r--r--src/tload.c1
-rw-r--r--src/tntfs.c6
-rw-r--r--src/ufs.c1
-rw-r--r--src/xfs.c1
111 files changed, 6022 insertions, 4468 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 747d45a..fab582c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,21 +6,39 @@ ICON_TESTDISK=icon_tst.rc ../ico/testdisk.ico
ICON_PHOTOREC=icon_ph.rc ../ico/photorec.ico
endif
+if USEQT
+ QPHOTOREC=qphotorec
+endif
-sbin_PROGRAMS = testdisk photorec
-#diskcp
+sbin_PROGRAMS = testdisk photorec $(QPHOTOREC)
-base_C = common.c crc.c ewf.c fnctdsk.c hdaccess.c hdcache.c hdwin32.c hidden.c hpa_dco.c intrf.c log.c misc.c msdos.c parti386.c partgpt.c partmac.c partsun.c partnone.c partxbox.c chgtype.c io_redir.c ntfs_io.c ntfs_utl.c partauto.c sudo.c unicode.c win32.c
-base_H = alignio.h common.h crc.h ewf.h fnctdsk.h hdaccess.h hdwin32.h hidden.h guid_cmp.h guid_cpy.h hdcache.h hpa_dco.h intrf.h intrfn.h lang.h log.h misc.h types.h chgtype.h io_redir.h msdos.h ntfs_utl.h partgpt.h partmac.h partnone.h partxbox.h partauto.h sudo.h unicode.h win32.h
+base_C = common.c crc.c ewf.c fnctdsk.c hdaccess.c hdcache.c hdwin32.c hidden.c hpa_dco.c intrf.c log.c log_part.c misc.c msdos.c parti386.c partgpt.c partmac.c partsun.c partnone.c partxbox.c io_redir.c ntfs_io.c ntfs_utl.c partauto.c sudo.c unicode.c win32.c
+base_H = alignio.h common.h crc.h ewf.h fnctdsk.h hdaccess.h hdwin32.h hidden.h guid_cmp.h guid_cpy.h hdcache.h hpa_dco.h intrf.h lang.h log.h log_part.h misc.h types.h io_redir.h msdos.h ntfs_utl.h parti386.h partgpt.h partmac.h partnone.h partsun.h partxbox.h partauto.h sudo.h unicode.h win32.h
fs_C = analyse.c bfs.c bsd.c cramfs.c fat.c fatx.c ext2.c jfs.c hfs.c hfsp.c luks.c lvm.c md.c netware.c ntfs.c rfs.c savehdr.c sun.c swap.c sysv.c ufs.c xfs.c
fs_H = analyse.h bfs.h bsd.h cramfs.h fat.h fatx.h ext2.h jfs_superblock.h jfs.h hfs.h hfsp.h luks.h lvm.h md.h netware.h ntfs.h rfs.h savehdr.h sun.h swap.h sysv.h ufs.h xfs.h
-testdisk_SOURCES = testdisk.c $(base_C) $(base_H) $(fs_C) $(fs_H) testdisk.h adv.c adv.h dir.c dir.h dirpart.c dirpart.h diskacc.c diskacc.h edit.c edit.h ext2_dir.c ext2_dir.h ext2_inc.h ext2_sb.c ext2_sb.h fat1x.c fat1x.h fat32.c fat32.h fat_adv.c fat_adv.h fat_dir.c fat_dir.h geometry.c godmode.c godmode.h intrface.c diskcapa.c diskcapa.h intrface.h ntfs_adv.c ntfs_dir.c ntfs_dir.h ntfs_fix.c ntfs_inc.h rfs_dir.c rfs_dir.h $(ICON_TESTDISK) next.c next.h dimage.c dimage.h ntfs_udl.c ntfs_udl.h tanalyse.c tanalyse.h tdelete.c tdelete.h tdisksel.c tdisksel.h tdiskop.c tdiskop.h thfs.c thfs.h tload.c tload.h tlog.c tlog.h tmbrcode.c tmbrcode.h tntfs.c tntfs.h toptions.c toptions.h tpartwr.c tpartwr.h
+testdisk_ncurses_C = addpart.c adv.c askloc.c chgtype.c chgtypen.c dimage.c dirn.c dirpart.c diskacc.c diskcapa.c edit.c ext2_sb.c ext2_sbn.c fat1x.c fat32.c fat_adv.c fatn.c geometry.c godmode.c hiddenn.c intrface.c intrfn.c nodisk.c ntfs_adv.c ntfs_fix.c ntfs_udl.c parti386n.c partgptn.c partmacn.c partsunn.c partxboxn.c tanalyse.c tbanner.c tdelete.c tdiskop.c tdisksel.c testdisk.c thfs.c tload.c tlog.c tmbrcode.c tntfs.c toptions.c tpartwr.c
+testdisk_ncurses_H = addpart.h adv.h askloc.h chgtype.h chgtypen.h dimage.h dirn.h dirpart.h diskacc.h diskcapa.h edit.h ext2_sb.h ext2_sbn.h fat1x.h fat32.h fat_adv.h fatn.h geometry.h godmode.h hiddenn.h intrface.h intrfn.h nodisk.h ntfs_udl.h partgptn.h parti386n.h partmacn.h partsunn.h partxboxn.h tanalyse.h tdelete.h tdiskop.h tdisksel.h testdisk.h thfs.h tload.h tlog.h tmbrcode.h tntfs.h toptions.h tpartwr.h
+
+testdisk_SOURCES = $(base_C) $(base_H) $(fs_C) $(fs_H) $(testdisk_ncurses_C) $(testdisk_ncurses_H) dir.c dir.h ext2_dir.c ext2_dir.h ext2_inc.h fat_dir.c fat_dir.h ntfs_dir.c ntfs_dir.h ntfs_inc.h rfs_dir.c rfs_dir.h $(ICON_TESTDISK) next.c next.h
+
+file_C = filegen.c file_list.c file_7z.c file_a.c file_ab.c file_abcdp.c file_ace.c file_ahn.c file_aif.c file_all.c file_als.c file_amd.c file_amr.c file_ape.c file_arj.c file_asf.c file_asm.c file_atd.c file_au.c file_bkf.c file_bld.c file_bmp.c file_bz2.c file_cab.c file_cam.c file_chm.c file_cm.c file_compress.c file_crw.c file_ctg.c file_cwk.c file_dat.c file_dbf.c file_dim.c file_dir.c file_djv.c file_doc.c file_dpx.c file_drw.c file_ds2.c file_dsc.c file_dss.c file_dta.c file_dump.c file_dv.c file_dwg.c file_elf.c file_emf.c file_evt.c file_exe.c file_ext.c file_fcp.c file_fcs.c file_fbk.c file_fdb.c file_fh10.c file_fh5.c file_fits.c file_flac.c file_flv.c file_fob.c file_frm.c file_fs.c file_gho.c file_gif.c file_gpg.c file_gz.c file_ifo.c file_imb.c file_indd.c file_iso.c file_itu.c file_jpg.c file_kdb.c file_lnk.c file_logic.c file_m2ts.c file_max.c file_mb.c file_mcd.c file_mdb.c file_mdf.c file_mfa.c file_mfg.c file_mid.c file_mkv.c file_mov.c file_mp3.c file_mpg.c file_mrw.c file_mus.c file_mysql.c file_njx.c file_ogg.c file_one.c file_orf.c file_paf.c file_pap.c file_pcap.c file_pct.c file_pcx.c file_pdf.c file_pfx.c file_png.c file_prc.c file_prt.c file_ps.c file_psd.c file_psp.c file_pst.c file_ptb.c file_qbb.c file_qdf.c file_qxd.c file_ra.c file_raf.c file_rar.c file_raw.c file_rdc.c file_reg.c file_res.c file_riff.c file_rm.c file_rns.c file_rpm.c file_sib.c file_sit.c file_skp.c file_sp3.c file_spe.c file_spf.c file_spss.c file_sql.c file_sqm.c file_stl.c file_stu.c file_swf.c file_tar.c file_tax.c file_tib.c file_tiff.c file_tph.c file_txt.c file_veg.c file_vmdk.c file_wks.c file_wmf.c file_wnk.c file_wpd.c file_wv.c file_x3f.c file_xcf.c file_xm.c file_xsv.c file_zip.c
+
+file_H = list.h file_jpg.h file_tar.h file_sp3.h file_tiff.h filegen.h pe.h ole.h
+
+photorec_C = photorec.c phcfg.c ext2grp.c ext2_dir.c fat_dir.c fatp.c list.c ntfs_dir.c ntfsp.c sessionp.c
+
+photorec_H = photorec.h phcfg.h dir.c dir.h ext2grp.h ext2p.c ext2p.h ext2_dir.h ext2_inc.h fat_dir.h fatp.h memmem.h ntfs_dir.h ntfsp.h ntfs_inc.h sessionp.h
+
+photorec_ncurses_C = addpart.c askloc.c chgtype.c chgtypen.c geometry.c hiddenn.c intrfn.c nodisk.c parti386n.c partgptn.c partmacn.c partsunn.c partxboxn.c pbanner.c pblocksize.c pdisksel.c pfree_whole.c phrecn.c ppartsel.c
+photorec_ncurses_H = addpart.h askloc.h chgtype.h chgtypen.h geometry.h hiddenn.h intrfn.h nodisk.h parti386n.h partgptn.h partmacn.h partsunn.h partxboxn.h pblocksize.h pdisksel.h pfree_whole.h phrecn.h ppartsel.h
+
+photorec_SOURCES = phmain.c $(photorec_C) $(photorec_H) $(photorec_ncurses_C) $(photorec_ncurses_H) $(file_C) $(file_H) $(base_C) $(base_H) $(fs_C) $(fs_H) $(ICON_PHOTOREC)
-photorec_SOURCES = photorec.c photorec.h phcfg.c phcfg.h phrecn.c phrecn.h dir.c dir.h ext2grp.c ext2grp.h ext2p.c ext2p.h ext2_dir.c ext2_dir.h ext2_inc.h fat_dir.c fat_dir.h fatp.c fatp.h filegen.c filegen.h file_7z.c file_a.c file_ab.c file_abcdp.c file_ace.c file_ahn.c file_aif.c file_all.c file_als.c file_amd.c file_amr.c file_ape.c file_arj.c file_asf.c file_asm.c file_atd.c file_au.c file_bkf.c file_bld.c file_bmp.c file_bz2.c file_cab.c file_cam.c file_chm.c file_cm.c file_compress.c file_crw.c file_ctg.c file_cwk.c file_dat.c file_dbf.c file_dim.c file_dir.c file_djv.c file_doc.c file_dpx.c file_drw.c file_ds2.c file_dsc.c file_dss.c file_dta.c file_dump.c file_dv.c file_dwg.c file_elf.c file_emf.c file_evt.c file_exe.c pe.h file_ext.c file_fcp.c file_fcs.c file_fbk.c file_fdb.c file_fh10.c file_fh5.c file_fits.c file_flac.c file_flv.c file_fob.c file_frm.c file_fs.c file_gho.c file_gif.c file_gpg.c file_gz.c file_ifo.c file_imb.c file_indd.c file_iso.c file_itu.c file_jpg.c file_jpg.h file_kdb.c file_lnk.c file_logic.c file_m2ts.c file_max.c file_mb.c file_mcd.c file_mdb.c file_mdf.c file_mfa.c file_mfg.c file_mid.c file_mkv.c file_mov.c file_mp3.c file_mpg.c file_mrw.c file_mus.c file_mysql.c file_njx.c file_ogg.c file_one.c file_orf.c file_paf.c file_pap.c file_pcap.c file_pct.c file_pcx.c file_pdf.c file_pfx.c file_png.c file_prc.c file_prt.c file_ps.c file_psd.c file_psp.c file_pst.c file_ptb.c file_qbb.c file_qdf.c file_qxd.c file_ra.c file_raf.c file_rar.c file_raw.c file_rdc.c file_reg.c file_res.c file_riff.c file_rm.c file_rns.c file_rpm.c file_sib.c file_sit.c file_skp.c file_sp3.c file_sp3.h file_spe.c file_spf.c file_spss.c file_sql.c file_sqm.c file_stl.c file_stu.c file_swf.c file_tar.c file_tar.h file_tax.c file_tib.c file_tiff.c file_tiff.h file_tph.c file_txt.c file_veg.c file_vmdk.c file_wks.c file_wmf.c file_wnk.c file_wpd.c file_wv.c file_x3f.c file_xcf.c file_xm.c file_xsv.c file_zip.c memmem.h geometry.c list.c list.h ole.h ntfs_dir.c ntfs_dir.h ntfsp.c ntfsp.h ntfs_inc.h pblocksize.c pblocksize.h pdisksel.c pdisksel.h pfree_whole.c pfree_whole.h ppartsel.c ppartsel.h sessionp.c sessionp.h $(base_C) $(base_H) $(fs_C) $(fs_H) $(ICON_PHOTOREC)
+qphotorec_SOURCES = qmainrec.cpp qphotorec.cpp qphotorec.h chgtype.c chgtype.h $(photorec_C) $(photorec_H) $(file_C) $(file_H) $(base_C) $(base_H) $(fs_C) $(fs_H) $(ICON_PHOTOREC)
-#diskcp_SOURCES = diskcp.c types.h
+#file_SOURCES = file.c $(file_C) $(file_H) log.c log.h crc.c crc.h
DISTCLEANFILES = *~ core
diff --git a/src/addpart.c b/src/addpart.c
new file mode 100644
index 0000000..4b5adb2
--- /dev/null
+++ b/src/addpart.c
@@ -0,0 +1,78 @@
+/*
+
+ File: addpart.c
+
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include "types.h"
+#include "common.h"
+#include "parti386.h"
+#include "partgpt.h"
+#include "partmac.h"
+#include "partsun.h"
+#include "partxbox.h"
+#ifdef HAVE_NCURSES
+#include "parti386n.h"
+#include "partgptn.h"
+#include "partmacn.h"
+#include "partsunn.h"
+#include "partxboxn.h"
+#endif
+#include "addpart.h"
+
+extern const arch_fnct_t arch_gpt;
+extern const arch_fnct_t arch_i386;
+extern const arch_fnct_t arch_mac;
+extern const arch_fnct_t arch_sun;
+extern const arch_fnct_t arch_xbox;
+
+list_part_t *add_partition(disk_t *disk_car, list_part_t *list_part, const int verbose, char **current_cmd)
+{
+ if(*current_cmd!=NULL)
+ {
+ if(disk_car->arch==&arch_gpt)
+ return add_partition_gpt_cli(disk_car, list_part, verbose, current_cmd);
+ else if(disk_car->arch==&arch_i386)
+ return add_partition_i386_cli(disk_car, list_part, verbose, current_cmd);
+ else if(disk_car->arch==&arch_mac)
+ return add_partition_mac_cli(disk_car, list_part, verbose, current_cmd);
+ else if(disk_car->arch==&arch_sun)
+ return add_partition_sun_cli(disk_car, list_part, verbose, current_cmd);
+ else if(disk_car->arch==&arch_xbox)
+ return add_partition_xbox_cli(disk_car, list_part, verbose, current_cmd);
+ }
+#ifdef HAVE_NCURSES
+ if(disk_car->arch==&arch_gpt)
+ return add_partition_gpt_ncurses(disk_car, list_part, verbose, current_cmd);
+ else if(disk_car->arch==&arch_i386)
+ return add_partition_i386_ncurses(disk_car, list_part, verbose, current_cmd);
+ else if(disk_car->arch==&arch_mac)
+ return add_partition_mac_ncurses(disk_car, list_part, verbose, current_cmd);
+ else if(disk_car->arch==&arch_sun)
+ return add_partition_sun_ncurses(disk_car, list_part, verbose, current_cmd);
+ else if(disk_car->arch==&arch_xbox)
+ return add_partition_xbox_ncurses(disk_car, list_part, verbose, current_cmd);
+#endif
+ return list_part;
+}
diff --git a/src/addpart.h b/src/addpart.h
new file mode 100644
index 0000000..ee1ccb4
--- /dev/null
+++ b/src/addpart.h
@@ -0,0 +1,23 @@
+/*
+
+ File: addpart.h
+
+ Copyright (C) 2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+list_part_t *add_partition(disk_t *disk_car, list_part_t *list_part, const int verbose, char **current_cmd);
diff --git a/src/adv.c b/src/adv.c
index e887410..de237c0 100644
--- a/src/adv.c
+++ b/src/adv.c
@@ -2,7 +2,7 @@
File: adv.c
- Copyright (C) 1998-2008 Christophe GRENIER <grenier@cgsecurity.org>
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
This software is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,7 +22,8 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-
+
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -35,21 +36,25 @@
#include "intrf.h"
#include "intrfn.h"
#include "fnctdsk.h"
-#include "chgtype.h"
+#include "chgtypen.h"
#include "dirpart.h"
#include "fat.h"
#include "ntfs.h"
#include "adv.h"
#include "analyse.h"
#include "log.h"
+#include "log_part.h"
#include "guid_cmp.h"
#include "dimage.h"
#include "ntfs_udl.h"
#include "ext2_sb.h"
+#include "ext2_sbn.h"
#include "fat1x.h"
#include "fat32.h"
#include "tntfs.h"
#include "thfs.h"
+#include "askloc.h"
+#include "addpart.h"
extern const arch_fnct_t arch_gpt;
extern const arch_fnct_t arch_i386;
@@ -378,9 +383,9 @@ void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const
break;
case 'a':
case 'A':
- if(disk_car->arch->add_partition!=NULL)
+ if(disk_car->arch!=&arch_none)
{
- list_part=disk_car->arch->add_partition(disk_car,list_part, verbose, current_cmd);
+ list_part=add_partition(disk_car, list_part, verbose, current_cmd);
current_element=list_part;
rewrite=1;
}
@@ -463,10 +468,14 @@ void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const
case 'C':
{
char *image_dd;
+#ifdef HAVE_NCURSES
if(*current_cmd!=NULL)
image_dd=get_default_location();
else
image_dd=ask_location("Do you want to save partition file image.dd in %s%s ? [Y/N]","");
+#else
+ image_dd=get_default_location();
+#endif
if(image_dd!=NULL)
{
char *new_recup_dir=(char *)MALLOC(strlen(image_dd)+1+strlen(DEFAULT_IMAGE_NAME)+1);
diff --git a/src/analyse.c b/src/analyse.c
index 2bf21da..3ffee03 100644
--- a/src/analyse.c
+++ b/src/analyse.c
@@ -22,19 +22,19 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
-//#include <assert.h>
#include "types.h"
#include "common.h"
#include "fnctdsk.h"
#include "analyse.h"
#include "intrf.h"
-#include "intrfn.h"
#include "savehdr.h"
#include "lang.h"
#include "bfs.h"
@@ -262,100 +262,3 @@ int search_type_128(unsigned char *buffer, disk_t *disk_car,partition_t *partiti
#endif
return 0;
}
-
-list_part_t *search_superblock(disk_t *disk_car, const partition_t *partition, const int verbose, const int dump_ind, const int interface)
-{
- unsigned char *buffer=(unsigned char *)MALLOC(2*0x200);
- uint64_t hd_offset;
- int nbr_sb=0;
- list_part_t *list_part=NULL;
- int ind_stop=0;
-#ifdef HAVE_NCURSES
- unsigned long int old_percent=0;
-#endif
- struct ext2_super_block *sb=(struct ext2_super_block *)buffer;
- partition_t *new_partition=partition_new(disk_car->arch);
- log_trace("search_superblock\n");
-#ifdef HAVE_NCURSES
- if(interface>0)
- {
- aff_copy(stdscr);
- wmove(stdscr,4,0);
- wprintw(stdscr,"%s",disk_car->description(disk_car));
- mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
- wmove(stdscr,6,0);
- aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
- wmove(stdscr,22,0);
- wattrset(stdscr, A_REVERSE);
- waddstr(stdscr," Stop ");
- wattroff(stdscr, A_REVERSE);
- }
-#endif
- for(hd_offset=0;hd_offset<partition->part_size && nbr_sb<10 && ind_stop==0;hd_offset+=DEFAULT_SECTOR_SIZE)
- {
-#ifdef HAVE_NCURSES
- unsigned long int percent;
- percent=hd_offset*100/partition->part_size;
- if(interface>0 && percent!=old_percent)
- {
- wmove(stdscr,9,0);
- wclrtoeol(stdscr);
- wprintw(stdscr,"Search ext2/ext3/ext4 superblock %10lu/%lu %lu%%", (long unsigned)(hd_offset/disk_car->sector_size),
- (long unsigned)(partition->part_size/disk_car->sector_size),percent);
- wrefresh(stdscr);
- ind_stop|=check_enter_key_or_s(stdscr);
- old_percent=percent;
- }
-#endif
- /* ext2/ext3/ext4 */
- if( hd_offset==(EXT2_MIN_BLOCK_SIZE<<0) ||
- hd_offset==(EXT2_MIN_BLOCK_SIZE<<1) ||
- hd_offset==(EXT2_MIN_BLOCK_SIZE<<2) ||
- hd_offset==(1*(EXT2_MIN_BLOCK_SIZE<<0)*8*(EXT2_MIN_BLOCK_SIZE<<0)+2*512) ||
- hd_offset==(1*(EXT2_MIN_BLOCK_SIZE<<1)*8*(EXT2_MIN_BLOCK_SIZE<<1)) ||
- hd_offset==(1*(EXT2_MIN_BLOCK_SIZE<<2)*8*(EXT2_MIN_BLOCK_SIZE<<2)) ||
- hd_offset%(3*(EXT2_MIN_BLOCK_SIZE<<0)*8*(EXT2_MIN_BLOCK_SIZE<<0)+2*512)==0 ||
- hd_offset%(5*(EXT2_MIN_BLOCK_SIZE<<0)*8*(EXT2_MIN_BLOCK_SIZE<<0)+2*512)==0 ||
- hd_offset%(7*(EXT2_MIN_BLOCK_SIZE<<0)*8*(EXT2_MIN_BLOCK_SIZE<<0)+2*512)==0 ||
- hd_offset%(3*(EXT2_MIN_BLOCK_SIZE<<1)*8*(EXT2_MIN_BLOCK_SIZE<<1))==0 ||
- hd_offset%(5*(EXT2_MIN_BLOCK_SIZE<<1)*8*(EXT2_MIN_BLOCK_SIZE<<1))==0 ||
- hd_offset%(7*(EXT2_MIN_BLOCK_SIZE<<1)*8*(EXT2_MIN_BLOCK_SIZE<<1))==0 ||
- hd_offset%(3*(EXT2_MIN_BLOCK_SIZE<<2)*8*(EXT2_MIN_BLOCK_SIZE<<2))==0 ||
- hd_offset%(5*(EXT2_MIN_BLOCK_SIZE<<2)*8*(EXT2_MIN_BLOCK_SIZE<<2))==0 ||
- hd_offset%(7*(EXT2_MIN_BLOCK_SIZE<<2)*8*(EXT2_MIN_BLOCK_SIZE<<2))==0)
- {
- if(disk_car->read(disk_car,1024, buffer, partition->part_offset+hd_offset)==0)
- {
- if(le16(sb->s_magic)==EXT2_SUPER_MAGIC)
- {
- dup_partition_t(new_partition,partition);
- new_partition->part_offset+=hd_offset;
- if(recover_EXT2(disk_car,sb,new_partition,verbose,dump_ind)==0)
- {
- int insert_error=0;
- if(hd_offset<=(EXT2_MIN_BLOCK_SIZE<<2))
- new_partition->part_offset-=hd_offset;
- log_info("Ext2 superblock found at sector %llu (block=%llu, blocksize=%u)\n",
- (long long unsigned) hd_offset/DEFAULT_SECTOR_SIZE,
- (long long unsigned) hd_offset>>(EXT2_MIN_BLOCK_LOG_SIZE+le32(sb->s_log_block_size)),
- EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size));
-#ifdef HAVE_NCURSES
- wmove(stdscr,10+nbr_sb,0);
- wprintw(stdscr,"Ext2 superblock found at sector %llu (block=%llu, blocksize=%u) \n",
- (long long unsigned) hd_offset/DEFAULT_SECTOR_SIZE,
- (long long unsigned) hd_offset>>(EXT2_MIN_BLOCK_LOG_SIZE+le32(sb->s_log_block_size)),
- EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size));
-#endif
- list_part=insert_new_partition(list_part, new_partition, 1, &insert_error);
- new_partition=partition_new(disk_car->arch);
- nbr_sb++;
- }
- }
- }
- }
- }
- free(new_partition);
- free(buffer);
- return list_part;
-}
-
diff --git a/src/analyse.h b/src/analyse.h
index 94f553a..84a47df 100644
--- a/src/analyse.h
+++ b/src/analyse.h
@@ -33,7 +33,6 @@ int search_type_128(unsigned char *buffer, disk_t *disk_car,partition_t *partiti
int search_FAT_backup(unsigned char *buffer, disk_t *disk_car,partition_t *partition, const int verbose, const int dump_ind);
int search_HFS_backup(unsigned char *buffer, disk_t *disk_car,partition_t *partition, const int verbose, const int dump_ind);
int search_NTFS_backup(unsigned char *buffer, disk_t *disk_car,partition_t *partition, const int verbose, const int dump_ind);
-list_part_t *search_superblock(disk_t *disk_car, const partition_t *partition, const int verbose, const int dump_ind, const int interface);
#ifdef __cplusplus
} /* closing brace for extern "C" */
diff --git a/src/askloc.c b/src/askloc.c
new file mode 100644
index 0000000..e6f584b
--- /dev/null
+++ b/src/askloc.c
@@ -0,0 +1,471 @@
+/*
+
+ File: askloc.c
+
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_NCURSES
+#include <stdarg.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <ctype.h>
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_CYGWIN_H
+#include <sys/cygwin.h>
+#endif
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#include "types.h"
+#include "common.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "list.h"
+#include "dir.h"
+#include "log.h"
+#include "askloc.h"
+
+extern const char *monstr[];
+
+#define INTER_DIR (LINES-25+16)
+
+#define SPATH_SEP "/"
+#define PATH_SEP '/'
+#if defined(__CYGWIN__)
+/* /cygdrive/c/ => */
+#define PATH_DRIVE_LENGTH 9
+#endif
+
+#define ASK_LOCATION_WAITKEY 0
+#define ASK_LOCATION_UPDATE 1
+#define ASK_LOCATION_NEWDIR 2
+#define ASK_LOCATION_QUIT 3
+
+static void set_parent_directory(char *dst_directory);
+static void dir_aff_entry(WINDOW *window, file_info_t *file_info);
+static int aff_txt(int line, WINDOW *window, const char *_format, ...) __attribute__ ((format (printf, 3, 4)));
+
+#if defined(DJGPP) || defined(__OS2__)
+void get_dos_drive_list(struct td_list_head *list);
+
+void get_dos_drive_list(struct td_list_head *list)
+{
+ int i;
+ for(i='a';i<='z';i++)
+ {
+ file_info_t *new_drive;
+ new_drive=(file_info_t*)MALLOC(sizeof(*new_drive));
+ new_drive->name[0]=i;
+ new_drive->name[1]=':';
+ new_drive->name[2]=PATH_SEP;
+ new_drive->name[3]='\0';
+ new_drive->stat.st_mode=LINUX_S_IFDIR|LINUX_S_IRWXUGO;
+ td_list_add_tail(&new_drive->list, list);
+ }
+}
+#endif
+static void set_parent_directory(char *dst_directory)
+{
+ int i;
+ int last_sep=-1;
+ for(i=0;dst_directory[i]!='\0';i++)
+ if(dst_directory[i]==PATH_SEP)
+ last_sep=i;
+#ifdef __CYGWIN__
+ /* /cygdrive */
+ if(last_sep>PATH_DRIVE_LENGTH)
+ dst_directory[last_sep]='\0';
+ else
+ dst_directory[PATH_DRIVE_LENGTH]='\0';
+#elif defined(DJGPP) || defined(__OS2__)
+ if(last_sep > 2 )
+ dst_directory[last_sep]='\0'; /* subdirectory */
+ else if(last_sep == 2 && dst_directory[3]!='\0')
+ dst_directory[3]='\0'; /* root directory */
+ else
+ dst_directory[0]='\0'; /* drive list */
+#else
+ if(last_sep>1)
+ dst_directory[last_sep]='\0';
+ else
+ dst_directory[1]='\0';
+#endif
+}
+
+char *ask_location(const char*msg, const char *src_dir)
+{
+ char dst_directory[4096];
+ char *res=NULL;
+ int quit;
+ WINDOW *window=newwin(0,0,0,0); /* full screen */
+ aff_copy(window);
+ td_getcwd(dst_directory, sizeof(dst_directory));
+ do
+ {
+ DIR* dir;
+ static file_info_t dir_list = {
+ .list = TD_LIST_HEAD_INIT(dir_list.list),
+ .name = {0}
+ };
+ wmove(window,7,0);
+ wclrtoeol(window); /* before addstr for BSD compatibility */
+ if(has_colors())
+ wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
+ waddstr(window,"Directory listing in progress...");
+ if(has_colors())
+ wbkgdset(window,' ' | COLOR_PAIR(0));
+ wrefresh(window);
+#if defined(DJGPP) || defined(__OS2__)
+ if(dst_directory[0]=='\0')
+ {
+ get_dos_drive_list(&dir_list.list);
+ dir=NULL;
+ }
+ else
+ dir=opendir(dst_directory);
+#else
+ dir=opendir(dst_directory);
+#endif
+ if(dir!=NULL)
+ {
+ struct dirent *dir_entrie;
+ file_info_t *file_info;
+ file_info=(file_info_t*)MALLOC(sizeof(*file_info));
+ do
+ {
+ char current_file[4096];
+ dir_entrie=readdir(dir);
+ /* if dir_entrie exists
+ * there is enough room to store the filename
+ * dir_entrie->d_name is ".", ".." or something that doesn't begin by a "."
+ * */
+ if(dir_entrie!=NULL
+ && strlen(dst_directory)+1+strlen(file_info->name)+1<=sizeof(current_file) &&
+ (dir_entrie->d_name[0]!='.' ||
+ dir_entrie->d_name[1]=='\0' ||
+ (dir_entrie->d_name[1]=='.' && dir_entrie->d_name[2]=='\0'))
+#ifdef __CYGWIN__
+ && (strlen(dst_directory)>PATH_DRIVE_LENGTH || dir_entrie->d_name[0]!='.')
+#endif
+ )
+ {
+ strcpy(current_file,dst_directory);
+#if defined(DJGPP) || defined(__OS2__)
+ if(current_file[0]!='\0'&&current_file[1]!='\0'&&current_file[2]!='\0'&&current_file[3]!='\0')
+#else
+ if(current_file[1]!='\0')
+#endif
+ strcat(current_file,SPATH_SEP);
+ strcat(current_file,dir_entrie->d_name);
+#ifdef HAVE_LSTAT
+ if(lstat(current_file,&file_info->stat)==0)
+#else
+ if(stat(current_file,&file_info->stat)==0)
+#endif
+ {
+#if defined(DJGPP) || defined(__OS2__)
+ /* If the C library doesn't use posix definition, st_mode need to be fixed */
+ if(S_ISDIR(file_info->stat.st_mode))
+ file_info->stat.st_mode=LINUX_S_IFDIR|LINUX_S_IRWXUGO;
+ else
+ file_info->stat.st_mode=LINUX_S_IFREG|LINUX_S_IRWXUGO;
+#endif
+#ifdef __CYGWIN__
+ /* Fix Drive list */
+ if(strlen(dst_directory)<=PATH_DRIVE_LENGTH)
+ {
+ file_info->stat.st_mode=LINUX_S_IFDIR|LINUX_S_IRWXUGO;
+ file_info->stat.st_mtime=0;
+ file_info->stat.st_uid=0;
+ file_info->stat.st_gid=0;
+ }
+#endif
+ strncpy(file_info->name,dir_entrie->d_name,sizeof(file_info->name));
+ td_list_add_sorted(&file_info->list, &dir_list.list, filesort);
+ file_info=(file_info_t*)MALLOC(sizeof(*file_info));
+ }
+ }
+ } while(dir_entrie!=NULL);
+ free(file_info);
+ closedir(dir);
+ }
+ if(dir_list.list.next!=&dir_list.list)
+ {
+ struct td_list_head *current_file=dir_list.list.next;
+ int offset=0;
+ int pos_num=0;
+ int old_LINES=LINES;
+ do
+ {
+ int dst_directory_ok=0;
+ if(old_LINES!=LINES)
+ { /* Screen size has changed, reset to initial values */
+ current_file=dir_list.list.next;
+ offset=0;
+ pos_num=0;
+ old_LINES=LINES;
+ }
+ aff_copy(window);
+ wmove(window,7,0);
+#ifdef __CYGWIN__
+ if(strlen(dst_directory)<=PATH_DRIVE_LENGTH)
+ wprintw(window,"To select a drive, use the arrow keys.");
+ else
+ wprintw(window,"To select another directory, use the arrow keys.");
+#elif defined(DJGPP) || defined(__OS2__)
+ if(dst_directory[0]=='\0')
+ wprintw(window,"To select a drive, use the arrow keys.");
+ else
+ wprintw(window,"To select another directory, use the arrow keys.");
+#else
+ wprintw(window,"To select another directory, use the arrow keys.");
+#endif
+ {
+ struct td_list_head *file_walker = NULL;
+ int i=0;
+ td_list_for_each(file_walker,&dir_list.list)
+ {
+ if(i++<offset)
+ continue;
+ {
+ file_info_t *file_info;
+ file_info=td_list_entry(file_walker, file_info_t, list);
+ wmove(window,8-1+i-offset,0);
+ wclrtoeol(window); /* before addstr for BSD compatibility */
+ if(file_walker==current_file)
+ wattrset(window, A_REVERSE);
+ dir_aff_entry(window,file_info);
+ if(file_walker==current_file)
+ wattroff(window, A_REVERSE);
+ }
+ if(offset+INTER_DIR<=i)
+ break;
+ }
+ wmove(window, 8+INTER_DIR, 4);
+ wclrtoeol(window);
+ if(file_walker!=&dir_list.list && file_walker->next!=&dir_list.list)
+ wprintw(window, "Next");
+ }
+ if(strcmp(dst_directory,".")==0)
+ {
+ aff_txt(4, window, msg, src_dir, "the program is running from");
+ dst_directory_ok=1;
+ }
+ else
+ {
+#ifdef __CYGWIN__
+ if(strlen(dst_directory)>PATH_DRIVE_LENGTH)
+ {
+ char beautifull_dst_directory[4096];
+ cygwin_conv_to_win32_path(dst_directory, beautifull_dst_directory);
+ aff_txt(4, window, msg, src_dir, beautifull_dst_directory);
+ dst_directory_ok=1;
+ }
+#elif defined(DJGPP) || defined(__OS2__)
+ if(strlen(dst_directory)>0)
+ {
+ aff_txt(4, window, msg, src_dir, dst_directory);
+ dst_directory_ok=1;
+ }
+#else
+ aff_txt(4, window, msg, src_dir, dst_directory);
+ dst_directory_ok=1;
+#endif
+ }
+ wclrtoeol(window); /* before addstr for BSD compatibility */
+ wrefresh(window);
+ do
+ {
+ quit=ASK_LOCATION_WAITKEY;
+ switch(wgetch(window))
+ {
+ case 'y':
+ case 'Y':
+ if(dst_directory_ok>0)
+ {
+ res=strdup(dst_directory);
+ quit=ASK_LOCATION_QUIT;
+ }
+ break;
+ case 'n':
+ case 'N':
+ res=NULL;
+ quit=ASK_LOCATION_QUIT;
+ break;
+ case KEY_UP:
+ case '8':
+ if(current_file->prev!=&dir_list.list)
+ {
+ current_file=current_file->prev;
+ pos_num--;
+ quit=ASK_LOCATION_UPDATE;
+ }
+ break;
+ case KEY_DOWN:
+ case '2':
+ if(current_file->next!=&dir_list.list)
+ {
+ current_file=current_file->next;
+ pos_num++;
+ quit=ASK_LOCATION_UPDATE;
+ }
+ break;
+ case KEY_PPAGE:
+ {
+ int i;
+ for(i=0; i<INTER_DIR-1 && current_file->prev!=&dir_list.list; i++)
+ {
+ current_file=current_file->prev;
+ pos_num--;
+ quit=ASK_LOCATION_UPDATE;
+ }
+ }
+ break;
+ case KEY_NPAGE:
+ {
+ int i;
+ for(i=0; i<INTER_DIR-1 && current_file->next!=&dir_list.list; i++)
+ {
+ current_file=current_file->next;
+ pos_num++;
+ quit=ASK_LOCATION_UPDATE;
+ }
+ }
+ break;
+ case KEY_LEFT:
+ case '4':
+ set_parent_directory(dst_directory);
+ quit=ASK_LOCATION_NEWDIR;
+ break;
+ case KEY_RIGHT:
+ case '\r':
+ case '\n':
+ case '6':
+ case KEY_ENTER:
+#ifdef PADENTER
+ case PADENTER:
+#endif
+ {
+ file_info_t *file_info;
+ file_info=td_list_entry(current_file, file_info_t, list);
+ if(current_file!=&dir_list.list &&
+ (LINUX_S_ISDIR(file_info->stat.st_mode) || LINUX_S_ISLNK(file_info->stat.st_mode)))
+ if(current_file!=&dir_list.list)
+ {
+ if(strcmp(file_info->name,".")==0)
+ {
+ }
+ else if(strcmp(file_info->name,"..")==0)
+ {
+ set_parent_directory(dst_directory);
+ quit=ASK_LOCATION_NEWDIR;
+ }
+ else if(strlen(dst_directory)+1+strlen(file_info->name)+1<=sizeof(dst_directory))
+ {
+#if defined(DJGPP) || defined(__OS2__)
+ if(dst_directory[0]!='\0'&&dst_directory[1]!='\0'&&dst_directory[2]!='\0'&&dst_directory[3]!='\0')
+#else
+ if(dst_directory[1]!='\0')
+#endif
+ strcat(dst_directory,SPATH_SEP);
+ strcat(dst_directory,file_info->name);
+ quit=ASK_LOCATION_NEWDIR;
+ }
+ }
+ }
+ break;
+
+ }
+ if(pos_num<offset)
+ offset=pos_num;
+ if(pos_num>=offset+INTER_DIR)
+ offset=pos_num-INTER_DIR+1;
+ } while(quit==ASK_LOCATION_WAITKEY && old_LINES==LINES);
+ } while(quit==ASK_LOCATION_UPDATE || old_LINES!=LINES);
+ delete_list_file_info(&dir_list.list);
+ }
+ else
+ {
+ set_parent_directory(dst_directory);
+ quit=ASK_LOCATION_NEWDIR;
+ }
+ } while(quit==ASK_LOCATION_NEWDIR);
+ delwin(window);
+ (void) clearok(stdscr, TRUE);
+#ifdef HAVE_TOUCHWIN
+ touchwin(stdscr);
+#endif
+ return res;
+}
+
+static void dir_aff_entry(WINDOW *window, file_info_t *file_info)
+{
+ struct tm *tm_p;
+ char str[11];
+ char datestr[80];
+ if(file_info->stat.st_mtime!=0)
+ {
+ tm_p = localtime(&file_info->stat.st_mtime);
+ snprintf(datestr, sizeof(datestr),"%2d-%s-%4d %02d:%02d",
+ tm_p->tm_mday, monstr[tm_p->tm_mon],
+ 1900 + tm_p->tm_year, tm_p->tm_hour,
+ tm_p->tm_min);
+ /* May have to use %d instead of %e */
+ } else {
+ strncpy(datestr, " ",sizeof(datestr));
+ }
+ mode_string(file_info->stat.st_mode,str);
+ wprintw(window, "%s %5u %5u ",
+ str, (unsigned int)file_info->stat.st_uid, (unsigned int)file_info->stat.st_gid);
+ wprintw(window, "%7llu", (long long unsigned int)file_info->stat.st_size);
+ /* screen may overlap due to long filename */
+ wprintw(window, " %s %s", datestr, file_info->name);
+}
+
+static int aff_txt(int line, WINDOW *window, const char *_format, ...)
+{
+ va_list ap;
+ va_start(ap,_format);
+ line=vaff_txt(line, window, _format, ap);
+ va_end(ap);
+ return line;
+}
+
+#endif
diff --git a/src/askloc.h b/src/askloc.h
new file mode 100644
index 0000000..6032227
--- /dev/null
+++ b/src/askloc.h
@@ -0,0 +1,30 @@
+/*
+
+ File: askloc.h
+
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char *ask_location(const char*msg, const char *src_dir);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/bfs.c b/src/bfs.c
index 4a5de95..d1ffa34 100644
--- a/src/bfs.c
+++ b/src/bfs.c
@@ -23,6 +23,7 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
diff --git a/src/bsd.c b/src/bsd.c
index 9c01386..9bab4b3 100644
--- a/src/bsd.c
+++ b/src/bsd.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
#endif
+#include <stdio.h>
#include "types.h"
#include "common.h"
#include "bsd.h"
diff --git a/src/chgtype.c b/src/chgtype.c
index 4e6346e..1097234 100644
--- a/src/chgtype.c
+++ b/src/chgtype.c
@@ -2,7 +2,7 @@
File: chgtype.c
- Copyright (C) 1998-2008 Christophe GRENIER <grenier@cgsecurity.org>
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
This software is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,7 +22,8 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-
+
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -33,394 +34,50 @@
#include "common.h"
#include "lang.h"
#include "intrf.h"
-#include "intrfn.h"
#include "fnctdsk.h"
#include "chgtype.h"
#include "log.h"
-#include "guid_cmp.h"
-#include "guid_cpy.h"
+#include "log_part.h"
#include "partgpt.h"
extern const arch_fnct_t arch_gpt;
extern const arch_fnct_t arch_none;
extern const arch_fnct_t arch_i386;
extern const arch_fnct_t arch_sun;
-extern const struct systypes_gtp gpt_sys_types[];
-
-struct part_name_struct
-{
- unsigned int index;
- const char *name;
-};
-
-static void change_part_type_cli(const disk_t *disk_car,partition_t *partition, char **current_cmd)
-{
- if(partition->arch->set_part_type==NULL)
- return ;
- while(*current_cmd[0]==',')
- (*current_cmd)++;
- {
- int tmp_val= strtol(*current_cmd, NULL, 16);
- while(*current_cmd[0]!=',' && *current_cmd[0]!='\0')
- (*current_cmd)++;
- partition->arch->set_part_type(partition,tmp_val);
- }
-}
-#ifdef HAVE_NCURSES
-static void change_part_type_ncurses(const disk_t *disk_car,partition_t *partition)
+void change_part_type_cli(const disk_t *disk_car,partition_t *partition, char **current_cmd)
{
- partition_t *new_partition;
- char response[100];
- int size=0;
- int i;
- unsigned int last[3], done = 0, next = 0;
- struct part_name_struct part_name[0x100];
- struct MenuItem menuType[]=
- {
- { 'P', "Previous",""},
- { 'N', "Next","" },
- { 'Q', "Proceed","Go set the partition type"},
- { 0, NULL, NULL }
- };
- if(partition->arch->set_part_type==NULL)
+ if(*current_cmd==NULL || partition->arch==NULL)
return ;
- /* Create an index of all partition type except Intel extended */
- new_partition=partition_new(NULL);
- dup_partition_t(new_partition,partition);
- for(i=0;i<=0xFF;i++)
- {
- if(partition->arch->set_part_type(new_partition,i)==0)
- {
- part_name[size].name=new_partition->arch->get_partition_typename(new_partition);
- if(part_name[size].name!=NULL)
- part_name[size++].index=i;
- }
- }
- free(new_partition);
-
- /* Display the list of partition type in 3 columns */
- screen_buffer_reset();
- screen_buffer_add("List of partition type\n");
- for (i = 2; i >= 0; i--)
- last[2 - i] = done += (size + i - done) / (i + 1);
- i = done = 0;
- while (done < last[0])
- {
- screen_buffer_add( "%02x %-20s%c", part_name[next].index, part_name[next].name,(i==2 ? '\n' : ' '));
- next = last[i++] + done;
- if (i > 2 || next >= last[i]) {
- i = 0;
- next = ++done;
- }
- }
-
- /* Ask for the new partition type*/
- aff_copy(stdscr);
- wmove(stdscr,4,0);
- aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
- screen_buffer_display(stdscr,"",menuType);
- wmove(stdscr,LINES-2,0);
- wprintw(stdscr,"New partition type [current %02x] ? ",partition->arch->get_part_type(partition));
- if (get_string(response, sizeof(response), NULL) > 0) {
- int tmp_val = strtol(response, NULL, 16);
- partition->arch->set_part_type(partition,tmp_val);
- }
-}
-#define INTER_CHGTYPE 15
-#define INTER_CHGTYPE_X 0
-#define INTER_CHGTYPE_Y 23
-
-static void change_part_type_ncurses2(const disk_t *disk_car, partition_t *partition)
-{
- partition_t *new_partition;
- unsigned int intr_nbr_line=0;
- unsigned int offset=0;
- unsigned int i;
- unsigned int current_element_num=0;
- struct part_name_struct part_name[0x100];
- if(partition->arch->set_part_type==NULL)
- return ;
- aff_copy(stdscr);
- wmove(stdscr,4,0);
- aff_part(stdscr, AFF_PART_ORDER|AFF_PART_STATUS, disk_car, partition);
- wmove(stdscr,INTER_CHGTYPE_Y, INTER_CHGTYPE_X);
- wattrset(stdscr, A_REVERSE);
- wprintw(stdscr, "[ Proceed ]");
- wattroff(stdscr, A_REVERSE);
- /* Create an index of all partition type except Intel extended */
- new_partition=partition_new(NULL);
- dup_partition_t(new_partition,partition);
- for(i=0;i<=0xFF;i++)
- {
- if(partition->arch->set_part_type(new_partition,i)==0)
- {
- part_name[intr_nbr_line].name=new_partition->arch->get_partition_typename(new_partition);
- if(part_name[intr_nbr_line].name!=NULL)
- {
- if(partition->arch->get_part_type(partition)==i)
- current_element_num=intr_nbr_line;
- part_name[intr_nbr_line++].index=i;
- }
- }
- }
- free(new_partition);
- while(1)
- {
- wmove(stdscr,5,0);
- wprintw(stdscr, "Please choose the partition type, press Enter when done.");
- wmove(stdscr,5+1,1);
- wclrtoeol(stdscr);
- if(offset>0)
- wprintw(stdscr, "Previous");
- for(i=offset;i<intr_nbr_line && (i-offset)<3*INTER_CHGTYPE;i++)
- {
- if(i-offset<INTER_CHGTYPE)
- wmove(stdscr,5+2+i-offset,0);
- else if(i-offset<2*INTER_CHGTYPE)
- wmove(stdscr,5+2+i-offset-INTER_CHGTYPE,26);
- else
- wmove(stdscr,5+2+i-offset-2*INTER_CHGTYPE,52);
- wclrtoeol(stdscr); /* before addstr for BSD compatibility */
- if(i==current_element_num)
- {
- wattrset(stdscr, A_REVERSE);
- wprintw(stdscr,"%s", part_name[i].name);
- wattroff(stdscr, A_REVERSE);
- } else
- {
- wprintw(stdscr,"%s", part_name[i].name);
- }
- }
- if(i-offset<INTER_CHGTYPE)
- wmove(stdscr,5+2+i-offset,1);
- else if(i-offset<2*INTER_CHGTYPE)
- wmove(stdscr,5+2+i-offset-INTER_CHGTYPE,27);
- else
- wmove(stdscr,5+2+i-offset-2*INTER_CHGTYPE,53);
- wclrtoeol(stdscr);
- if(i<intr_nbr_line)
- wprintw(stdscr, "Next");
- switch(wgetch(stdscr))
- {
- case 'p':
- case 'P':
- case KEY_UP:
- if(current_element_num>0)
- current_element_num--;
- break;
- case 'n':
- case 'N':
- case KEY_DOWN:
- if(current_element_num < intr_nbr_line-1)
- current_element_num++;
- break;
- case KEY_LEFT:
- if(current_element_num > INTER_CHGTYPE)
- current_element_num-=INTER_CHGTYPE;
- else
- current_element_num=0;
- break;
- case KEY_PPAGE:
- if(current_element_num > 3*INTER_CHGTYPE-1)
- current_element_num-=3*INTER_CHGTYPE-1;
- else
- current_element_num=0;
- break;
- case KEY_RIGHT:
- if(current_element_num+INTER_CHGTYPE < intr_nbr_line-1)
- current_element_num+=INTER_CHGTYPE;
- else
- current_element_num=intr_nbr_line-1;
- break;
- case KEY_NPAGE:
- if(current_element_num+3*INTER_CHGTYPE-1 < intr_nbr_line-1)
- current_element_num+=3*INTER_CHGTYPE-1;
- else
- current_element_num=intr_nbr_line-1;
- break;
- case 'Q':
- case 'q':
- case key_CR:
-#ifdef PADENTER
- case PADENTER:
-#endif
- partition->arch->set_part_type(partition, part_name[current_element_num].index);
- return;
- }
- if(current_element_num < offset)
- offset=current_element_num;
- if(current_element_num >= offset+3*INTER_CHGTYPE)
- offset=current_element_num-3*INTER_CHGTYPE+1;
- }
-}
-
-static void gpt_change_part_type(const disk_t *disk_car, partition_t *partition)
-{
- unsigned int offset=0;
- unsigned int i,j;
- unsigned int current_element_num=0;
- log_info("gpt_change_part_type\n");
- aff_copy(stdscr);
- wmove(stdscr,4,0);
- aff_part(stdscr, AFF_PART_ORDER|AFF_PART_STATUS, disk_car, partition);
- wmove(stdscr,INTER_CHGTYPE_Y, INTER_CHGTYPE_X);
- wattrset(stdscr, A_REVERSE);
- wprintw(stdscr, "[ Proceed ]");
- wattroff(stdscr, A_REVERSE);
- /* By default, select the current type */
- for(i=0;gpt_sys_types[i].name!=NULL;i++)
- {
- if(guid_cmp(partition->part_type_gpt, gpt_sys_types[i].part_type)==0)
- {
- current_element_num=i;
- while(current_element_num >= offset+3*INTER_CHGTYPE)
- offset++;
- }
- }
- while(1)
- {
- wmove(stdscr,5,0);
- wprintw(stdscr, "Please choose the partition type, press Enter when done.");
- wmove(stdscr,5+1,1);
- wclrtoeol(stdscr);
- if(offset>0)
- wprintw(stdscr, "Previous");
- for(i=offset;gpt_sys_types[i].name!=NULL && (i-offset)<3*INTER_CHGTYPE;i++)
- {
- if(i-offset<INTER_CHGTYPE)
- wmove(stdscr,5+2+i-offset,0);
- else if(i-offset<2*INTER_CHGTYPE)
- wmove(stdscr,5+2+i-offset-INTER_CHGTYPE,26);
- else
- wmove(stdscr,5+2+i-offset-2*INTER_CHGTYPE,52);
- wclrtoeol(stdscr); /* before addstr for BSD compatibility */
- if(i==current_element_num)
- {
- wattrset(stdscr, A_REVERSE);
- wprintw(stdscr,"%s", gpt_sys_types[i].name);
- wattroff(stdscr, A_REVERSE);
- } else
- {
- wprintw(stdscr,"%s", gpt_sys_types[i].name);
- }
- }
- if(i-offset<INTER_CHGTYPE)
- wmove(stdscr,5+2+i-offset,1);
- else if(i-offset<2*INTER_CHGTYPE)
- wmove(stdscr,5+2+i-offset-INTER_CHGTYPE,27);
- else
- wmove(stdscr,5+2+i-offset-2*INTER_CHGTYPE,53);
- wclrtoeol(stdscr);
- if(gpt_sys_types[i].name!=NULL)
- wprintw(stdscr, "Next");
- switch(wgetch(stdscr))
- {
- case 'p':
- case 'P':
- case KEY_UP:
- if(current_element_num>0)
- current_element_num--;
- break;
- case 'n':
- case 'N':
- case KEY_DOWN:
- if(gpt_sys_types[current_element_num].name!=NULL && gpt_sys_types[current_element_num+1].name!=NULL)
- current_element_num++;
- break;
- case KEY_LEFT:
- if(current_element_num > INTER_CHGTYPE)
- current_element_num-=INTER_CHGTYPE;
- else
- current_element_num=0;
- break;
- case KEY_PPAGE:
- if(current_element_num > 3*INTER_CHGTYPE-1)
- current_element_num-=3*INTER_CHGTYPE-1;
- else
- current_element_num=0;
- break;
- case KEY_RIGHT:
- for(j=0;j<INTER_CHGTYPE;j++)
- {
- if(gpt_sys_types[current_element_num].name!=NULL && gpt_sys_types[current_element_num+1].name!=NULL)
- current_element_num++;
- }
- break;
- case KEY_NPAGE:
- for(j=0;j<3*INTER_CHGTYPE;j++)
- {
- if(gpt_sys_types[current_element_num].name!=NULL && gpt_sys_types[current_element_num+1].name!=NULL)
- current_element_num++;
- }
- break;
- case 'Q':
- case 'q':
- case key_CR:
-#ifdef PADENTER
- case PADENTER:
-#endif
- guid_cpy(&partition->part_type_gpt, &gpt_sys_types[current_element_num].part_type);
- return;
- }
- if(current_element_num<offset)
- offset=current_element_num;
- if(current_element_num >= offset+3*INTER_CHGTYPE)
- offset=current_element_num-3*INTER_CHGTYPE+1;
- }
-}
-#endif
-
-void change_part_type(const disk_t *disk_car,partition_t *partition, char **current_cmd)
-{
if(partition->arch==NULL)
- {
- log_error("change_part_type arch==NULL\n");
return;
- }
if(partition->arch==&arch_gpt)
{
- if(*current_cmd!=NULL)
- { /* TODO: implement it */
- }
- else
- {
-#ifdef HAVE_NCURSES
- gpt_change_part_type(disk_car, partition);
-#endif
- }
- log_info("Change partition type:\n");
- log_partition(disk_car,partition);
partition->arch=&arch_none;
- if(*current_cmd!=NULL)
- change_part_type_cli(disk_car, partition, current_cmd);
- else
+ while(*current_cmd[0]==',')
+ (*current_cmd)++;
{
-#ifdef HAVE_NCURSES
- change_part_type_ncurses2(disk_car, partition);
-#endif
+ int tmp_val= strtol(*current_cmd, NULL, 16);
+ while(*current_cmd[0]!=',' && *current_cmd[0]!='\0')
+ (*current_cmd)++;
+ partition->arch->set_part_type(partition,tmp_val);
}
log_info("Change partition type:\n");
log_partition(disk_car,partition);
partition->arch=&arch_gpt;
- return ;
- }
- if(partition->arch->set_part_type==NULL)
- {
- log_error("change_part_type set_part_type==NULL\n");
return;
}
- if(*current_cmd!=NULL)
- change_part_type_cli(disk_car, partition, current_cmd);
- else
+ if(partition->arch->set_part_type==NULL)
+ return ;
+ while(*current_cmd[0]==',')
+ (*current_cmd)++;
{
-#ifdef HAVE_NCURSES
- if(partition->arch==&arch_i386 || partition->arch==&arch_sun)
- change_part_type_ncurses(disk_car, partition);
- else
- change_part_type_ncurses2(disk_car, partition);
-#endif
+ int tmp_val= strtol(*current_cmd, NULL, 16);
+ while(*current_cmd[0]!=',' && *current_cmd[0]!='\0')
+ (*current_cmd)++;
+ partition->arch->set_part_type(partition,tmp_val);
}
log_info("Change partition type:\n");
log_partition(disk_car,partition);
+ return ;
}
diff --git a/src/chgtype.h b/src/chgtype.h
index 20f138f..7904397 100644
--- a/src/chgtype.h
+++ b/src/chgtype.h
@@ -2,7 +2,7 @@
File: chgtype.h
- Copyright (C) 1998-2007 Christophe GRENIER <grenier@cgsecurity.org>
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
This software is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,8 +23,7 @@
extern "C" {
#endif
-void change_geometry(disk_t *disk_car, char **current_cmd);
-void change_part_type(const disk_t *disk_car,partition_t *partition, char **current_cmd);
+void change_part_type_cli(const disk_t *disk_car,partition_t *partition, char **current_cmd);
#ifdef __cplusplus
} /* closing brace for extern "C" */
diff --git a/src/chgtypen.c b/src/chgtypen.c
new file mode 100644
index 0000000..c5b7e1d
--- /dev/null
+++ b/src/chgtypen.c
@@ -0,0 +1,439 @@
+/*
+
+ File: chgtypen.c
+
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include "types.h"
+#include "common.h"
+#include "lang.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "fnctdsk.h"
+#include "chgtype.h"
+#include "chgtypen.h"
+#include "log.h"
+#include "log_part.h"
+#include "guid_cmp.h"
+#include "guid_cpy.h"
+#include "partgpt.h"
+#include "hdaccess.h"
+
+extern const arch_fnct_t arch_gpt;
+extern const arch_fnct_t arch_i386;
+extern const arch_fnct_t arch_mac;
+extern const arch_fnct_t arch_none;
+extern const arch_fnct_t arch_sun;
+extern const struct systypes_gtp gpt_sys_types[];
+
+#ifdef HAVE_NCURSES
+struct part_name_struct
+{
+ unsigned int index;
+ const char *name;
+};
+
+static void change_part_type_ncurses(const disk_t *disk_car,partition_t *partition)
+{
+ partition_t *new_partition;
+ char response[100];
+ int size=0;
+ int i;
+ unsigned int last[3], done = 0, next = 0;
+ struct part_name_struct part_name[0x100];
+ struct MenuItem menuType[]=
+ {
+ { 'P', "Previous",""},
+ { 'N', "Next","" },
+ { 'Q', "Proceed","Go set the partition type"},
+ { 0, NULL, NULL }
+ };
+ if(partition->arch->set_part_type==NULL)
+ return ;
+ /* Create an index of all partition type except Intel extended */
+ new_partition=partition_new(NULL);
+ dup_partition_t(new_partition,partition);
+ for(i=0;i<=0xFF;i++)
+ {
+ if(partition->arch->set_part_type(new_partition,i)==0)
+ {
+ part_name[size].name=new_partition->arch->get_partition_typename(new_partition);
+ if(part_name[size].name!=NULL)
+ part_name[size++].index=i;
+ }
+ }
+ free(new_partition);
+
+ /* Display the list of partition type in 3 columns */
+ screen_buffer_reset();
+ screen_buffer_add("List of partition type\n");
+ for (i = 2; i >= 0; i--)
+ last[2 - i] = done += (size + i - done) / (i + 1);
+ i = done = 0;
+ while (done < last[0])
+ {
+ screen_buffer_add( "%02x %-20s%c", part_name[next].index, part_name[next].name,(i==2 ? '\n' : ' '));
+ next = last[i++] + done;
+ if (i > 2 || next >= last[i]) {
+ i = 0;
+ next = ++done;
+ }
+ }
+
+ /* Ask for the new partition type*/
+ aff_copy(stdscr);
+ wmove(stdscr,4,0);
+ aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
+ screen_buffer_display(stdscr,"",menuType);
+ wmove(stdscr,LINES-2,0);
+ wprintw(stdscr,"New partition type [current %02x] ? ",partition->arch->get_part_type(partition));
+ if (get_string(response, sizeof(response), NULL) > 0) {
+ int tmp_val = strtol(response, NULL, 16);
+ partition->arch->set_part_type(partition,tmp_val);
+ }
+}
+#define INTER_CHGTYPE 15
+#define INTER_CHGTYPE_X 0
+#define INTER_CHGTYPE_Y 23
+
+static void change_part_type_ncurses2(const disk_t *disk_car, partition_t *partition)
+{
+ partition_t *new_partition;
+ unsigned int intr_nbr_line=0;
+ unsigned int offset=0;
+ unsigned int i;
+ unsigned int current_element_num=0;
+ struct part_name_struct part_name[0x100];
+ if(partition->arch->set_part_type==NULL)
+ return ;
+ aff_copy(stdscr);
+ wmove(stdscr,4,0);
+ aff_part(stdscr, AFF_PART_ORDER|AFF_PART_STATUS, disk_car, partition);
+ wmove(stdscr,INTER_CHGTYPE_Y, INTER_CHGTYPE_X);
+ wattrset(stdscr, A_REVERSE);
+ wprintw(stdscr, "[ Proceed ]");
+ wattroff(stdscr, A_REVERSE);
+ /* Create an index of all partition type except Intel extended */
+ new_partition=partition_new(NULL);
+ dup_partition_t(new_partition,partition);
+ for(i=0;i<=0xFF;i++)
+ {
+ if(partition->arch->set_part_type(new_partition,i)==0)
+ {
+ part_name[intr_nbr_line].name=new_partition->arch->get_partition_typename(new_partition);
+ if(part_name[intr_nbr_line].name!=NULL)
+ {
+ if(partition->arch->get_part_type(partition)==i)
+ current_element_num=intr_nbr_line;
+ part_name[intr_nbr_line++].index=i;
+ }
+ }
+ }
+ free(new_partition);
+ while(1)
+ {
+ wmove(stdscr,5,0);
+ wprintw(stdscr, "Please choose the partition type, press Enter when done.");
+ wmove(stdscr,5+1,1);
+ wclrtoeol(stdscr);
+ if(offset>0)
+ wprintw(stdscr, "Previous");
+ for(i=offset;i<intr_nbr_line && (i-offset)<3*INTER_CHGTYPE;i++)
+ {
+ if(i-offset<INTER_CHGTYPE)
+ wmove(stdscr,5+2+i-offset,0);
+ else if(i-offset<2*INTER_CHGTYPE)
+ wmove(stdscr,5+2+i-offset-INTER_CHGTYPE,26);
+ else
+ wmove(stdscr,5+2+i-offset-2*INTER_CHGTYPE,52);
+ wclrtoeol(stdscr); /* before addstr for BSD compatibility */
+ if(i==current_element_num)
+ {
+ wattrset(stdscr, A_REVERSE);
+ wprintw(stdscr,"%s", part_name[i].name);
+ wattroff(stdscr, A_REVERSE);
+ } else
+ {
+ wprintw(stdscr,"%s", part_name[i].name);
+ }
+ }
+ if(i-offset<INTER_CHGTYPE)
+ wmove(stdscr,5+2+i-offset,1);
+ else if(i-offset<2*INTER_CHGTYPE)
+ wmove(stdscr,5+2+i-offset-INTER_CHGTYPE,27);
+ else
+ wmove(stdscr,5+2+i-offset-2*INTER_CHGTYPE,53);
+ wclrtoeol(stdscr);
+ if(i<intr_nbr_line)
+ wprintw(stdscr, "Next");
+ switch(wgetch(stdscr))
+ {
+ case 'p':
+ case 'P':
+ case KEY_UP:
+ if(current_element_num>0)
+ current_element_num--;
+ break;
+ case 'n':
+ case 'N':
+ case KEY_DOWN:
+ if(current_element_num < intr_nbr_line-1)
+ current_element_num++;
+ break;
+ case KEY_LEFT:
+ if(current_element_num > INTER_CHGTYPE)
+ current_element_num-=INTER_CHGTYPE;
+ else
+ current_element_num=0;
+ break;
+ case KEY_PPAGE:
+ if(current_element_num > 3*INTER_CHGTYPE-1)
+ current_element_num-=3*INTER_CHGTYPE-1;
+ else
+ current_element_num=0;
+ break;
+ case KEY_RIGHT:
+ if(current_element_num+INTER_CHGTYPE < intr_nbr_line-1)
+ current_element_num+=INTER_CHGTYPE;
+ else
+ current_element_num=intr_nbr_line-1;
+ break;
+ case KEY_NPAGE:
+ if(current_element_num+3*INTER_CHGTYPE-1 < intr_nbr_line-1)
+ current_element_num+=3*INTER_CHGTYPE-1;
+ else
+ current_element_num=intr_nbr_line-1;
+ break;
+ case 'Q':
+ case 'q':
+ case key_CR:
+#ifdef PADENTER
+ case PADENTER:
+#endif
+ partition->arch->set_part_type(partition, part_name[current_element_num].index);
+ return;
+ }
+ if(current_element_num < offset)
+ offset=current_element_num;
+ if(current_element_num >= offset+3*INTER_CHGTYPE)
+ offset=current_element_num-3*INTER_CHGTYPE+1;
+ }
+}
+
+static void gpt_change_part_type(const disk_t *disk_car, partition_t *partition)
+{
+ unsigned int offset=0;
+ unsigned int i,j;
+ unsigned int current_element_num=0;
+ log_info("gpt_change_part_type\n");
+ aff_copy(stdscr);
+ wmove(stdscr,4,0);
+ aff_part(stdscr, AFF_PART_ORDER|AFF_PART_STATUS, disk_car, partition);
+ wmove(stdscr,INTER_CHGTYPE_Y, INTER_CHGTYPE_X);
+ wattrset(stdscr, A_REVERSE);
+ wprintw(stdscr, "[ Proceed ]");
+ wattroff(stdscr, A_REVERSE);
+ /* By default, select the current type */
+ for(i=0;gpt_sys_types[i].name!=NULL;i++)
+ {
+ if(guid_cmp(partition->part_type_gpt, gpt_sys_types[i].part_type)==0)
+ {
+ current_element_num=i;
+ while(current_element_num >= offset+3*INTER_CHGTYPE)
+ offset++;
+ }
+ }
+ while(1)
+ {
+ wmove(stdscr,5,0);
+ wprintw(stdscr, "Please choose the partition type, press Enter when done.");
+ wmove(stdscr,5+1,1);
+ wclrtoeol(stdscr);
+ if(offset>0)
+ wprintw(stdscr, "Previous");
+ for(i=offset;gpt_sys_types[i].name!=NULL && (i-offset)<3*INTER_CHGTYPE;i++)
+ {
+ if(i-offset<INTER_CHGTYPE)
+ wmove(stdscr,5+2+i-offset,0);
+ else if(i-offset<2*INTER_CHGTYPE)
+ wmove(stdscr,5+2+i-offset-INTER_CHGTYPE,26);
+ else
+ wmove(stdscr,5+2+i-offset-2*INTER_CHGTYPE,52);
+ wclrtoeol(stdscr); /* before addstr for BSD compatibility */
+ if(i==current_element_num)
+ {
+ wattrset(stdscr, A_REVERSE);
+ wprintw(stdscr,"%s", gpt_sys_types[i].name);
+ wattroff(stdscr, A_REVERSE);
+ } else
+ {
+ wprintw(stdscr,"%s", gpt_sys_types[i].name);
+ }
+ }
+ if(i-offset<INTER_CHGTYPE)
+ wmove(stdscr,5+2+i-offset,1);
+ else if(i-offset<2*INTER_CHGTYPE)
+ wmove(stdscr,5+2+i-offset-INTER_CHGTYPE,27);
+ else
+ wmove(stdscr,5+2+i-offset-2*INTER_CHGTYPE,53);
+ wclrtoeol(stdscr);
+ if(gpt_sys_types[i].name!=NULL)
+ wprintw(stdscr, "Next");
+ switch(wgetch(stdscr))
+ {
+ case 'p':
+ case 'P':
+ case KEY_UP:
+ if(current_element_num>0)
+ current_element_num--;
+ break;
+ case 'n':
+ case 'N':
+ case KEY_DOWN:
+ if(gpt_sys_types[current_element_num].name!=NULL && gpt_sys_types[current_element_num+1].name!=NULL)
+ current_element_num++;
+ break;
+ case KEY_LEFT:
+ if(current_element_num > INTER_CHGTYPE)
+ current_element_num-=INTER_CHGTYPE;
+ else
+ current_element_num=0;
+ break;
+ case KEY_PPAGE:
+ if(current_element_num > 3*INTER_CHGTYPE-1)
+ current_element_num-=3*INTER_CHGTYPE-1;
+ else
+ current_element_num=0;
+ break;
+ case KEY_RIGHT:
+ for(j=0;j<INTER_CHGTYPE;j++)
+ {
+ if(gpt_sys_types[current_element_num].name!=NULL && gpt_sys_types[current_element_num+1].name!=NULL)
+ current_element_num++;
+ }
+ break;
+ case KEY_NPAGE:
+ for(j=0;j<3*INTER_CHGTYPE;j++)
+ {
+ if(gpt_sys_types[current_element_num].name!=NULL && gpt_sys_types[current_element_num+1].name!=NULL)
+ current_element_num++;
+ }
+ break;
+ case 'Q':
+ case 'q':
+ case key_CR:
+#ifdef PADENTER
+ case PADENTER:
+#endif
+ guid_cpy(&partition->part_type_gpt, &gpt_sys_types[current_element_num].part_type);
+ return;
+ }
+ if(current_element_num<offset)
+ offset=current_element_num;
+ if(current_element_num >= offset+3*INTER_CHGTYPE)
+ offset=current_element_num-3*INTER_CHGTYPE+1;
+ }
+}
+
+void change_part_type(const disk_t *disk_car,partition_t *partition, char **current_cmd)
+{
+ if(*current_cmd!=NULL)
+ return change_part_type_cli(disk_car, partition, current_cmd);
+ if(partition->arch==NULL)
+ {
+ log_error("change_part_type arch==NULL\n");
+ return;
+ }
+ if(partition->arch==&arch_gpt)
+ {
+ gpt_change_part_type(disk_car, partition);
+ log_info("Change partition type:\n");
+ log_partition(disk_car,partition);
+ partition->arch=&arch_none;
+ change_part_type_ncurses2(disk_car, partition);
+ log_info("Change partition type:\n");
+ log_partition(disk_car,partition);
+ partition->arch=&arch_gpt;
+ return ;
+ }
+ if(partition->arch->set_part_type==NULL)
+ {
+ log_error("change_part_type set_part_type==NULL\n");
+ return;
+ }
+ if(partition->arch==&arch_i386 || partition->arch==&arch_sun)
+ change_part_type_ncurses(disk_car, partition);
+ else
+ change_part_type_ncurses2(disk_car, partition);
+ log_info("Change partition type:\n");
+ log_partition(disk_car,partition);
+}
+#endif
+
+int interface_partition_type(disk_t *disk_car, const int verbose, char**current_cmd)
+{
+ const arch_fnct_t *arch_list[]={&arch_i386, &arch_gpt, &arch_none, &arch_sun, &arch_mac, NULL};
+ int ask_user=1;
+ if(*current_cmd!=NULL)
+ {
+ int keep_asking;
+ do
+ {
+ int i;
+ ask_user=0;
+ keep_asking=0;
+ while(*current_cmd[0]==',')
+ (*current_cmd)++;
+ for(i=0;arch_list[i]!=NULL;i++)
+ if(strncmp(*current_cmd, arch_list[i]->part_name_option, strlen(arch_list[i]->part_name_option))==0)
+ {
+ (*current_cmd)+=strlen(arch_list[i]->part_name_option);
+ disk_car->arch=arch_list[i];
+ autoset_unit(disk_car);
+ keep_asking=1;
+ }
+ if(strncmp(*current_cmd, "ask_type", 8)==0)
+ {
+ (*current_cmd)+=8;
+ ask_user=1;
+ }
+ } while(keep_asking>0);
+ }
+ if(ask_user>0)
+ {
+#ifdef HAVE_NCURSES
+ if(interface_partition_type_ncurses(disk_car))
+ return 1;
+#endif
+ }
+ log_info("%s\n",disk_car->description_short(disk_car));
+ log_info("Partition table type: %s\n",disk_car->arch->part_name);
+ hd_update_geometry(disk_car, 0,verbose);
+ return 0;
+}
diff --git a/src/chgtypen.h b/src/chgtypen.h
new file mode 100644
index 0000000..4ad3d1e
--- /dev/null
+++ b/src/chgtypen.h
@@ -0,0 +1,31 @@
+/*
+
+ File: chgtype.h
+
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void change_part_type(const disk_t *disk_car,partition_t *partition, char **current_cmd);
+int interface_partition_type(disk_t *disk_car, const int verbose, char**current_cmd);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/common.h b/src/common.h
index 959f0b3..de33c0b 100644
--- a/src/common.h
+++ b/src/common.h
@@ -283,7 +283,6 @@ struct arch_fnct_struct
int (*get_geometry_from_mbr)(const unsigned char *buffer, const int verbose, CHSgeometry_t *geometry);
int (*check_part)(disk_t *disk_car,const int verbose,partition_t *partition, const int saveheader);
int (*write_MBR_code)(disk_t *disk_car);
- list_part_t *(*add_partition)(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd);
void (*set_prev_status)(const disk_t *disk_car, partition_t *partition);
void (*set_next_status)(const disk_t *disk_car, partition_t *partition);
int (*test_structure)(list_part_t *list_part);
diff --git a/src/cramfs.c b/src/cramfs.c
index fa49fae..dd61236 100644
--- a/src/cramfs.c
+++ b/src/cramfs.c
@@ -24,6 +24,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
diff --git a/src/dimage.c b/src/dimage.c
index d92dc37..7c1de82 100644
--- a/src/dimage.c
+++ b/src/dimage.c
@@ -20,6 +20,7 @@
*/
+#include <stdio.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -45,11 +46,7 @@
#include "common.h"
#include "testdisk.h"
#include "intrf.h"
-#ifdef HAVE_NCURSES
#include "intrfn.h"
-#else
-#include <stdio.h>
-#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
diff --git a/src/dir.c b/src/dir.c
index f821d0d..92d40ea 100644
--- a/src/dir.c
+++ b/src/dir.c
@@ -2,7 +2,7 @@
File: dir.c
- Copyright (C) 1998-2008 Christophe GRENIER <grenier@cgsecurity.org>
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
This software is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -46,27 +46,19 @@
#include "fnctdsk.h"
#include "testdisk.h"
#include "intrf.h"
-#ifdef HAVE_NCURSES
-#include "intrfn.h"
-#else
#include <stdio.h>
-#endif
#include "dir.h"
#include "ext2_dir.h"
#include "fat_dir.h"
#include "ntfs_dir.h"
#include "rfs_dir.h"
#include "log.h"
+#include "log_part.h"
const char *monstr[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
-static int dir_partition_aux(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const unsigned long int inode, const unsigned int depth, char **current_cmd);
-static int copy_dir(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_data_t *dir);
static char ftypelet (unsigned int bits);
-#ifdef HAVE_NCURSES
-static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_data_t*dir_list, const unsigned long int inode, const unsigned int depth);
-#endif
static char ftypelet (unsigned int bits)
{
@@ -265,291 +257,6 @@ int log_list_file(const disk_t *disk, const partition_t *partition, const dir_da
return test_date;
}
-#ifdef HAVE_NCURSES
-#define INTER_DIR (LINES-25+16)
-
-static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_data_t*dir_list, const unsigned long int inode, const unsigned int depth)
-{
- /* Return value
- * -1: quit
- * 1: back
- * other: new inode
- * */
- int quit=0;
- WINDOW *window=(WINDOW*)dir_data->display;
- do
- {
- int offset=0;
- int pos_num=0;
- const file_data_t *current_file;
- const file_data_t *pos=dir_list;
- int old_LINES=LINES;
- aff_copy(window);
- wmove(window,3,0);
- aff_part(window, AFF_PART_ORDER|AFF_PART_STATUS, disk, partition);
- wmove(window,4,0);
- wprintw(window,"Directory %s\n",dir_data->current_directory);
- do
- {
- int i;
- int car;
- for(i=0,current_file=dir_list;(current_file!=NULL) && (i<offset);current_file=current_file->next,i++);
- for(i=offset;(current_file!=NULL) &&((i-offset)<INTER_DIR);i++,current_file=current_file->next)
- {
- char str[11];
- char datestr[80];
- wmove(window, 6+i-offset, 0);
- wclrtoeol(window); /* before addstr for BSD compatibility */
- if(current_file==pos)
- wattrset(window, A_REVERSE);
- if((current_file->status&FILE_STATUS_DELETED)!=0 && has_colors())
- wbkgdset(window,' ' | COLOR_PAIR(1));
- if(current_file->stat.st_mtime!=0)
- {
- struct tm *tm_p;
- tm_p = localtime(&current_file->stat.st_mtime);
- snprintf(datestr, sizeof(datestr),"%2d-%s-%4d %02d:%02d",
- tm_p->tm_mday, monstr[tm_p->tm_mon],
- 1900 + tm_p->tm_year, tm_p->tm_hour,
- tm_p->tm_min);
- /* May have to use %d instead of %e */
- } else {
- strncpy(datestr, " ",sizeof(datestr));
- }
- mode_string(current_file->stat.st_mode,str);
- wprintw(window, "%s %5u %5u ",
- str, (unsigned int)current_file->stat.st_uid, (unsigned int)current_file->stat.st_gid);
- wprintw(window, "%7llu", (long long unsigned int)current_file->stat.st_size);
- /* screen may overlap due to long filename */
- wprintw(window, " %s %s", datestr, current_file->name);
- if((current_file->status&FILE_STATUS_DELETED)!=0 && has_colors())
- wbkgdset(window,' ' | COLOR_PAIR(0));
- if(current_file==pos)
- wattroff(window, A_REVERSE);
- }
- wmove(window, 6-1, 51);
- wclrtoeol(window);
- if(offset>0)
- wprintw(window, "Previous");
- /* Clear the last line, useful if overlapping */
- wmove(window,6+i-offset,0);
- wclrtoeol(window);
- wmove(window, 6+INTER_DIR, 51);
- wclrtoeol(window);
- if(current_file!=NULL)
- wprintw(window, "Next");
- if(dir_list==NULL)
- {
- wmove(window,6,0);
- wprintw(window,"No file found, filesystem seems damaged.");
- }
- /* Redraw the bottom of the screen everytime because very long filenames may have corrupt it*/
- mvwaddstr(window,LINES-2,0,"Use ");
- if(depth>0)
- {
- if(has_colors())
- wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
- waddstr(window, "Left");
- if(has_colors())
- wbkgdset(window,' ' | COLOR_PAIR(0));
- waddstr(window," arrow to go back, ");
- }
- if(has_colors())
- wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
- waddstr(window,"Right");
- if(has_colors())
- wbkgdset(window,' ' | COLOR_PAIR(0));
- waddstr(window," arrow to change directory, ");
- if(dir_data->copy_file!=NULL)
- {
- if(has_colors())
- wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
- waddstr(window,"c");
- if(has_colors())
- wbkgdset(window,' ' | COLOR_PAIR(0));
- waddstr(window," to copy, ");
- }
- wmove(window,LINES-1,4);
- if((dir_data->capabilities&CAPA_LIST_DELETED)!=0)
- {
- if(has_colors())
- wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
- waddstr(window,"h");
- if(has_colors())
- wbkgdset(window,' ' | COLOR_PAIR(0));
- if((dir_data->param&FLAG_LIST_DELETED)==0)
- waddstr(window," to unhide deleted files, ");
- else
- waddstr(window," to hide deleted files, ");
- }
- if(has_colors())
- wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
- waddstr(window,"q");
- if(has_colors())
- wbkgdset(window,' ' | COLOR_PAIR(0));
- waddstr(window," to quit");
- wrefresh(window);
- /* Using gnome terminal under FC3, TERM=xterm, the screen is not always correct */
- wredrawln(window,0,getmaxy(window)); /* redrawwin def is boggus in pdcur24 */
- car=wgetch(window);
- wmove(window,5,0);
- wclrtoeol(window);
- switch(car)
- {
- case key_ESC:
- case 'q':
- case 'M':
- quit=1;
- break;
- case '-':
- case KEY_LEFT:
- case '4':
- if(depth>0)
- return 1;
- break;
- case 'h':
- if((dir_data->capabilities&CAPA_LIST_DELETED)!=0)
- dir_data->param^=FLAG_LIST_DELETED;
- return inode;
- }
- if(dir_list!=NULL)
- {
- switch(car)
- {
- case KEY_UP:
- case '8':
- if(pos->prev!=NULL)
- {
- pos=pos->prev;
- pos_num--;
- }
- break;
- case KEY_DOWN:
- case '2':
- if(pos->next!=NULL)
- {
- pos=pos->next;
- pos_num++;
- }
- break;
- case 'p':
- case 'P':
- case '+':
- case ' ':
- case KEY_RIGHT:
- case '\r':
- case '\n':
- case '6':
- case KEY_ENTER:
-#ifdef PADENTER
- case PADENTER:
-#endif
- if((pos!=NULL) && (LINUX_S_ISDIR(pos->stat.st_mode)!=0))
- {
- unsigned long int new_inode=pos->stat.st_ino;
- if((new_inode!=inode) &&(strcmp(pos->name,".")!=0))
- {
- if(strcmp(pos->name,"..")==0)
- return 1;
- if(strlen(dir_data->current_directory)+1+strlen(pos->name)+1<=sizeof(dir_data->current_directory))
- {
- if(strcmp(dir_data->current_directory,"/"))
- strcat(dir_data->current_directory,"/");
- strcat(dir_data->current_directory,pos->name);
- return (long int)new_inode;
- }
- }
- }
- break;
- case KEY_PPAGE:
- for(i=0;(i<INTER_DIR-1)&&(pos->prev!=NULL);i++)
- {
- pos=pos->prev;
- pos_num--;
- }
- break;
- case KEY_NPAGE:
- for(i=0;(i<INTER_DIR-1)&&(pos->next!=NULL);i++)
- {
- pos=pos->next;
- pos_num++;
- }
- break;
- case 'c':
- if(dir_data->copy_file!=NULL)
- {
- const unsigned int current_directory_namelength=strlen(dir_data->current_directory);
- if(strcmp(pos->name,"..")!=0 &&
- current_directory_namelength+1+strlen(pos->name)<sizeof(dir_data->current_directory)-1)
- {
- if(strcmp(dir_data->current_directory,"/"))
- strcat(dir_data->current_directory,"/");
- if(strcmp(pos->name,".")!=0)
- strcat(dir_data->current_directory,pos->name);
- if(dir_data->local_dir==NULL)
- {
- if(LINUX_S_ISDIR(pos->stat.st_mode)!=0)
- dir_data->local_dir=ask_location("Are you sure you want to copy %s and any files below to the directory %s ? [Y/N]",
- dir_data->current_directory);
- else
- dir_data->local_dir=ask_location("Are you sure you want to copy %s to the directory %s ? [Y/N]",
- dir_data->current_directory);
- }
- if(dir_data->local_dir!=NULL)
- {
- int res=-1;
- wmove(window,5,0);
- wclrtoeol(window);
- if(has_colors())
- wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(1));
- wprintw(window,"Copying, please wait...");
- if(has_colors())
- wbkgdset(window,' ' | COLOR_PAIR(0));
- wrefresh(window);
- if(LINUX_S_ISDIR(pos->stat.st_mode)!=0)
- {
- res=copy_dir(disk, partition, dir_data, pos);
- }
- else if(LINUX_S_ISREG(pos->stat.st_mode)!=0)
- {
- res=dir_data->copy_file(disk, partition, dir_data, pos);
- }
- wmove(window,5,0);
- wclrtoeol(window);
- if(res < -1)
- {
- if(has_colors())
- wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(1));
- wprintw(window,"Copy failed!");
- }
- else
- {
- if(has_colors())
- wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(2));
- if(res < 0)
- wprintw(window,"Copy done! (Failed to copy some files)");
- else
- wprintw(window,"Copy done!");
- }
- if(has_colors())
- wbkgdset(window,' ' | COLOR_PAIR(0));
- }
- dir_data->current_directory[current_directory_namelength]='\0';
- }
- }
- break;
- }
- if(pos_num<offset)
- offset=pos_num;
- if(pos_num>=offset+INTER_DIR)
- offset=pos_num-INTER_DIR+1;
- }
- } while(quit==0 && old_LINES==LINES);
- } while(quit==0);
- return -1;
-}
-#endif
-
unsigned int delete_list_file(file_data_t *file_list)
{
int nbr=0;
@@ -577,65 +284,6 @@ void delete_list_file_info(struct td_list_head *list)
}
}
-int dir_partition_aff(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const unsigned long int inode, char **current_cmd)
-{
- if(dir_data==NULL)
- return -1;
- return dir_partition_aux(disk, partition, dir_data, inode, 0, current_cmd);
-}
-
-static int dir_partition_aux(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const unsigned long int inode, const unsigned int depth, char**current_cmd)
-{
-#define MAX_DIR_NBR 256
- static unsigned long int inode_known[MAX_DIR_NBR];
- if(depth==MAX_DIR_NBR)
- return 1; /* subdirectories depth is too high => Back */
- if(dir_data->verbose>0)
- {
- log_info("\ndir_partition inode=%lu\n",inode);
- log_partition(disk, partition);
- }
- while(1)
- {
- const unsigned int current_directory_namelength=strlen(dir_data->current_directory);
- long int new_inode=-1; /* Quit */
- file_data_t *dir_list;
- /* Not perfect for FAT32 root cluster */
- inode_known[depth]=inode;
- dir_list=dir_data->get_dir(disk, partition, dir_data, inode);
- dir_aff_log(disk, partition, dir_data, dir_list);
- if(*current_cmd!=NULL)
- {
- dir_data->current_directory[current_directory_namelength]='\0';
- delete_list_file(dir_list);
- return -1; /* Quit */
- }
-#ifdef HAVE_NCURSES
- new_inode=dir_aff_ncurses(disk, partition, dir_data,dir_list,inode,depth);
-#endif
- if(new_inode==-1 || new_inode==1) /* -1:Quit or 1:Back */
- {
- delete_list_file(dir_list);
- return new_inode;
- }
- if(new_inode>=2)
- {
- unsigned int new_inode_ok=1;
- unsigned int i;
- for(i=0;i<=depth && new_inode_ok!=0;i++)
- if(new_inode==inode_known[i]) /* Avoid loop */
- new_inode_ok=0;
- if(new_inode_ok>0)
- {
- dir_partition_aux(disk, partition, dir_data, (unsigned long int)new_inode, depth+1, current_cmd);
- }
- }
- /* restore current_directory name */
- dir_data->current_directory[current_directory_namelength]='\0';
- delete_list_file(dir_list);
- }
-}
-
static int dir_whole_partition_log_aux(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const unsigned long int inode)
{
file_data_t *dir_list;
@@ -689,62 +337,6 @@ int dir_whole_partition_log(disk_t *disk, const partition_t *partition, dir_data
return dir_whole_partition_log_aux(disk, partition, dir_data, inode);
}
-/*
-Returns
--2: no file copied
--1: failed to copy some files
-0: all files has been copied
-*/
-static int copy_dir(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_data_t *dir)
-{
- file_data_t *dir_list;
- const unsigned int current_directory_namelength=strlen(dir_data->current_directory);
- file_data_t *current_file;
- char *dir_name;
- int copy_bad=0;
- int copy_ok=0;
- if(dir_data->get_dir==NULL || dir_data->copy_file==NULL)
- return -2;
- dir_name=mkdir_local(dir_data->local_dir, dir_data->current_directory);
- dir_list=dir_data->get_dir(disk, partition, dir_data, (const unsigned long int)dir->stat.st_ino);
- for(current_file=dir_list;current_file!=NULL;current_file=current_file->next)
- {
- dir_data->current_directory[current_directory_namelength]='\0';
- if(current_directory_namelength+1+strlen(current_file->name)<sizeof(dir_data->current_directory)-1)
- {
- if(strcmp(dir_data->current_directory,"/"))
- strcat(dir_data->current_directory,"/");
- strcat(dir_data->current_directory,current_file->name);
- if(LINUX_S_ISDIR(current_file->stat.st_mode)!=0)
- {
- int tmp=0;
- if(current_file->stat.st_ino != dir->stat.st_ino &&
- strcmp(current_file->name,"..")!=0 && strcmp(current_file->name,".")!=0)
- tmp=copy_dir(disk, partition, dir_data, current_file);
- if(tmp>=-1)
- copy_ok=1;
- if(tmp<0)
- copy_bad=1;
- }
- else if(LINUX_S_ISREG(current_file->stat.st_mode)!=0)
- {
-// log_trace("copy_file %s\n",dir_data->current_directory);
- int tmp;
- tmp=dir_data->copy_file(disk, partition, dir_data, current_file);
- if(tmp==0)
- copy_ok=1;
- else
- copy_bad=1;
- }
- }
- }
- dir_data->current_directory[current_directory_namelength]='\0';
- delete_list_file(dir_list);
- set_date(dir_name, dir->stat.st_atime, dir->stat.st_mtime);
- free(dir_name);
- return (copy_bad>0?(copy_ok>0?-1:-2):0);
-}
-
/**
* set_date - Set the file's date and time
* @pathname: Path and name of the file to alter
@@ -1100,17 +692,13 @@ char *mkdir_local(const char *localroot, const char *pathname)
void mkdir_local_for_file(const char *filename)
{
- char *dir=strdup(filename);
- char *sep=NULL;
- char *oldsep;
- do
- {
- oldsep=sep;
- sep=strchr(dir,'/');
- } while(sep!=NULL);
- if(oldsep!=NULL)
+ char *dir;
+ char *sep;
+ dir=strdup(filename);
+ sep=strrchr(dir,'/');
+ if(sep!=NULL)
{
- *oldsep='\0';
+ *sep='\0';
free(mkdir_local(NULL, dir));
}
free(dir);
diff --git a/src/dir.h b/src/dir.h
index a21764b..8dcb716 100644
--- a/src/dir.h
+++ b/src/dir.h
@@ -21,6 +21,9 @@
*/
#ifndef _DIR_H
#define _DIR_H
+#ifdef __cplusplus
+extern "C" {
+#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
@@ -52,6 +55,7 @@ struct dir_data
};
#define FILE_STATUS_DELETED 1
+#define FILE_STATUS_MARKED 2
/* TODO: add status to file_info and migrate file_data to file_info */
struct file_data
@@ -75,7 +79,6 @@ int dir_aff_log(const disk_t *disk_car, const partition_t *partition, const dir_
int log_list_file(const disk_t *disk_car, const partition_t *partition, const dir_data_t *dir_data, const file_info_t*list);
unsigned int delete_list_file(file_data_t *file_list);
void delete_list_file_info(struct td_list_head *list);
-int dir_partition_aff(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int inode, char **current_cmd);
int dir_whole_partition_log(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int inode);
void mode_string (const unsigned int mode, char *str);
int set_date(const char *pathname, time_t actime, time_t modtime);
@@ -128,4 +131,7 @@ void mkdir_local_for_file(const char *filename);
#define LINUX_S_ISSOCK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFSOCK)
int filesort(const struct td_list_head *a, const struct td_list_head *b);
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
#endif
diff --git a/src/dirn.c b/src/dirn.c
new file mode 100644
index 0000000..da7e7df
--- /dev/null
+++ b/src/dirn.c
@@ -0,0 +1,463 @@
+/*
+
+ File: dirn.c
+
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_NCURSES
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#include "types.h"
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+#include <errno.h>
+#include "common.h"
+#include "fat.h"
+#include "lang.h"
+#include "fnctdsk.h"
+#include "testdisk.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "dir.h"
+#include "ext2_dir.h"
+#include "fat_dir.h"
+#include "ntfs_dir.h"
+#include "rfs_dir.h"
+#include "log.h"
+#include "log_part.h"
+#include "dirn.h"
+#include "askloc.h"
+
+extern const char *monstr[];
+
+static int dir_partition_aux(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const unsigned long int inode, const unsigned int depth, char **current_cmd);
+static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_data_t*dir_list, const unsigned long int inode, const unsigned int depth);
+static int copy_dir(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_data_t *dir);
+
+#define INTER_DIR (LINES-25+16)
+
+static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_data_t*dir_list, const unsigned long int inode, const unsigned int depth)
+{
+ /* Return value
+ * -1: quit
+ * 1: back
+ * other: new inode
+ * */
+ int quit=0;
+ WINDOW *window=(WINDOW*)dir_data->display;
+ do
+ {
+ int offset=0;
+ int pos_num=0;
+ const file_data_t *current_file;
+ const file_data_t *pos=dir_list;
+ int old_LINES=LINES;
+ aff_copy(window);
+ wmove(window,3,0);
+ aff_part(window, AFF_PART_ORDER|AFF_PART_STATUS, disk, partition);
+ wmove(window,4,0);
+ wprintw(window,"Directory %s\n",dir_data->current_directory);
+ do
+ {
+ int i;
+ int car;
+ for(i=0,current_file=dir_list;(current_file!=NULL) && (i<offset);current_file=current_file->next,i++);
+ for(i=offset;(current_file!=NULL) &&((i-offset)<INTER_DIR);i++,current_file=current_file->next)
+ {
+ char str[11];
+ char datestr[80];
+ wmove(window, 6+i-offset, 0);
+ wclrtoeol(window); /* before addstr for BSD compatibility */
+ if(current_file==pos)
+ wattrset(window, A_REVERSE);
+ if((current_file->status&FILE_STATUS_DELETED)!=0 && has_colors())
+ wbkgdset(window,' ' | COLOR_PAIR(1));
+ if(current_file->stat.st_mtime!=0)
+ {
+ struct tm *tm_p;
+ tm_p = localtime(&current_file->stat.st_mtime);
+ snprintf(datestr, sizeof(datestr),"%2d-%s-%4d %02d:%02d",
+ tm_p->tm_mday, monstr[tm_p->tm_mon],
+ 1900 + tm_p->tm_year, tm_p->tm_hour,
+ tm_p->tm_min);
+ /* May have to use %d instead of %e */
+ } else {
+ strncpy(datestr, " ",sizeof(datestr));
+ }
+ mode_string(current_file->stat.st_mode,str);
+ wprintw(window, "%s %5u %5u ",
+ str, (unsigned int)current_file->stat.st_uid, (unsigned int)current_file->stat.st_gid);
+ wprintw(window, "%7llu", (long long unsigned int)current_file->stat.st_size);
+ /* screen may overlap due to long filename */
+ wprintw(window, " %s %s", datestr, current_file->name);
+ if((current_file->status&FILE_STATUS_DELETED)!=0 && has_colors())
+ wbkgdset(window,' ' | COLOR_PAIR(0));
+ if(current_file==pos)
+ wattroff(window, A_REVERSE);
+ }
+ wmove(window, 6-1, 51);
+ wclrtoeol(window);
+ if(offset>0)
+ wprintw(window, "Previous");
+ /* Clear the last line, useful if overlapping */
+ wmove(window,6+i-offset,0);
+ wclrtoeol(window);
+ wmove(window, 6+INTER_DIR, 51);
+ wclrtoeol(window);
+ if(current_file!=NULL)
+ wprintw(window, "Next");
+ if(dir_list==NULL)
+ {
+ wmove(window,6,0);
+ wprintw(window,"No file found, filesystem seems damaged.");
+ }
+ /* Redraw the bottom of the screen everytime because very long filenames may have corrupt it*/
+ mvwaddstr(window,LINES-2,0,"Use ");
+ if(depth>0)
+ {
+ if(has_colors())
+ wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
+ waddstr(window, "Left");
+ if(has_colors())
+ wbkgdset(window,' ' | COLOR_PAIR(0));
+ waddstr(window," arrow to go back, ");
+ }
+ if(has_colors())
+ wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
+ waddstr(window,"Right");
+ if(has_colors())
+ wbkgdset(window,' ' | COLOR_PAIR(0));
+ waddstr(window," arrow to change directory, ");
+ if(dir_data->copy_file!=NULL)
+ {
+ if(has_colors())
+ wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
+ waddstr(window,"c");
+ if(has_colors())
+ wbkgdset(window,' ' | COLOR_PAIR(0));
+ waddstr(window," to copy, ");
+ }
+ wmove(window,LINES-1,4);
+ if((dir_data->capabilities&CAPA_LIST_DELETED)!=0)
+ {
+ if(has_colors())
+ wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
+ waddstr(window,"h");
+ if(has_colors())
+ wbkgdset(window,' ' | COLOR_PAIR(0));
+ if((dir_data->param&FLAG_LIST_DELETED)==0)
+ waddstr(window," to unhide deleted files, ");
+ else
+ waddstr(window," to hide deleted files, ");
+ }
+ if(has_colors())
+ wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
+ waddstr(window,"q");
+ if(has_colors())
+ wbkgdset(window,' ' | COLOR_PAIR(0));
+ waddstr(window," to quit");
+ wrefresh(window);
+ /* Using gnome terminal under FC3, TERM=xterm, the screen is not always correct */
+ wredrawln(window,0,getmaxy(window)); /* redrawwin def is boggus in pdcur24 */
+ car=wgetch(window);
+ wmove(window,5,0);
+ wclrtoeol(window);
+ switch(car)
+ {
+ case key_ESC:
+ case 'q':
+ case 'M':
+ quit=1;
+ break;
+ case '-':
+ case KEY_LEFT:
+ case '4':
+ if(depth>0)
+ return 1;
+ break;
+ case 'h':
+ if((dir_data->capabilities&CAPA_LIST_DELETED)!=0)
+ dir_data->param^=FLAG_LIST_DELETED;
+ return inode;
+ }
+ if(dir_list!=NULL)
+ {
+ switch(car)
+ {
+ case KEY_UP:
+ case '8':
+ if(pos->prev!=NULL)
+ {
+ pos=pos->prev;
+ pos_num--;
+ }
+ break;
+ case KEY_DOWN:
+ case '2':
+ if(pos->next!=NULL)
+ {
+ pos=pos->next;
+ pos_num++;
+ }
+ break;
+ case 'p':
+ case 'P':
+ case '+':
+ case ' ':
+ case KEY_RIGHT:
+ case '\r':
+ case '\n':
+ case '6':
+ case KEY_ENTER:
+#ifdef PADENTER
+ case PADENTER:
+#endif
+ if((pos!=NULL) && (LINUX_S_ISDIR(pos->stat.st_mode)!=0))
+ {
+ unsigned long int new_inode=pos->stat.st_ino;
+ if((new_inode!=inode) &&(strcmp(pos->name,".")!=0))
+ {
+ if(strcmp(pos->name,"..")==0)
+ return 1;
+ if(strlen(dir_data->current_directory)+1+strlen(pos->name)+1<=sizeof(dir_data->current_directory))
+ {
+ if(strcmp(dir_data->current_directory,"/"))
+ strcat(dir_data->current_directory,"/");
+ strcat(dir_data->current_directory,pos->name);
+ return (long int)new_inode;
+ }
+ }
+ }
+ break;
+ case KEY_PPAGE:
+ for(i=0;(i<INTER_DIR-1)&&(pos->prev!=NULL);i++)
+ {
+ pos=pos->prev;
+ pos_num--;
+ }
+ break;
+ case KEY_NPAGE:
+ for(i=0;(i<INTER_DIR-1)&&(pos->next!=NULL);i++)
+ {
+ pos=pos->next;
+ pos_num++;
+ }
+ break;
+ case 'c':
+ if(dir_data->copy_file!=NULL)
+ {
+ const unsigned int current_directory_namelength=strlen(dir_data->current_directory);
+ if(strcmp(pos->name,"..")!=0 &&
+ current_directory_namelength+1+strlen(pos->name)<sizeof(dir_data->current_directory)-1)
+ {
+ if(strcmp(dir_data->current_directory,"/"))
+ strcat(dir_data->current_directory,"/");
+ if(strcmp(pos->name,".")!=0)
+ strcat(dir_data->current_directory,pos->name);
+ if(dir_data->local_dir==NULL)
+ {
+ if(LINUX_S_ISDIR(pos->stat.st_mode)!=0)
+ dir_data->local_dir=ask_location("Are you sure you want to copy %s and any files below to the directory %s ? [Y/N]",
+ dir_data->current_directory);
+ else
+ dir_data->local_dir=ask_location("Are you sure you want to copy %s to the directory %s ? [Y/N]",
+ dir_data->current_directory);
+ }
+ if(dir_data->local_dir!=NULL)
+ {
+ int res=-1;
+ wmove(window,5,0);
+ wclrtoeol(window);
+ if(has_colors())
+ wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(1));
+ wprintw(window,"Copying, please wait...");
+ if(has_colors())
+ wbkgdset(window,' ' | COLOR_PAIR(0));
+ wrefresh(window);
+ if(LINUX_S_ISDIR(pos->stat.st_mode)!=0)
+ {
+ res=copy_dir(disk, partition, dir_data, pos);
+ }
+ else if(LINUX_S_ISREG(pos->stat.st_mode)!=0)
+ {
+ res=dir_data->copy_file(disk, partition, dir_data, pos);
+ }
+ wmove(window,5,0);
+ wclrtoeol(window);
+ if(res < -1)
+ {
+ if(has_colors())
+ wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(1));
+ wprintw(window,"Copy failed!");
+ }
+ else
+ {
+ if(has_colors())
+ wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(2));
+ if(res < 0)
+ wprintw(window,"Copy done! (Failed to copy some files)");
+ else
+ wprintw(window,"Copy done!");
+ }
+ if(has_colors())
+ wbkgdset(window,' ' | COLOR_PAIR(0));
+ }
+ dir_data->current_directory[current_directory_namelength]='\0';
+ }
+ }
+ break;
+ }
+ if(pos_num<offset)
+ offset=pos_num;
+ if(pos_num>=offset+INTER_DIR)
+ offset=pos_num-INTER_DIR+1;
+ }
+ } while(quit==0 && old_LINES==LINES);
+ } while(quit==0);
+ return -1;
+}
+
+static int dir_partition_aux(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const unsigned long int inode, const unsigned int depth, char**current_cmd)
+{
+#define MAX_DIR_NBR 256
+ static unsigned long int inode_known[MAX_DIR_NBR];
+ if(depth==MAX_DIR_NBR)
+ return 1; /* subdirectories depth is too high => Back */
+ if(dir_data->verbose>0)
+ {
+ log_info("\ndir_partition inode=%lu\n",inode);
+ log_partition(disk, partition);
+ }
+ while(1)
+ {
+ const unsigned int current_directory_namelength=strlen(dir_data->current_directory);
+ long int new_inode=-1; /* Quit */
+ file_data_t *dir_list;
+ /* Not perfect for FAT32 root cluster */
+ inode_known[depth]=inode;
+ dir_list=dir_data->get_dir(disk, partition, dir_data, inode);
+ dir_aff_log(disk, partition, dir_data, dir_list);
+ if(*current_cmd!=NULL)
+ {
+ dir_data->current_directory[current_directory_namelength]='\0';
+ delete_list_file(dir_list);
+ return -1; /* Quit */
+ }
+ new_inode=dir_aff_ncurses(disk, partition, dir_data,dir_list,inode,depth);
+ if(new_inode==-1 || new_inode==1) /* -1:Quit or 1:Back */
+ {
+ delete_list_file(dir_list);
+ return new_inode;
+ }
+ if(new_inode>=2)
+ {
+ unsigned int new_inode_ok=1;
+ unsigned int i;
+ for(i=0;i<=depth && new_inode_ok!=0;i++)
+ if(new_inode==inode_known[i]) /* Avoid loop */
+ new_inode_ok=0;
+ if(new_inode_ok>0)
+ {
+ dir_partition_aux(disk, partition, dir_data, (unsigned long int)new_inode, depth+1, current_cmd);
+ }
+ }
+ /* restore current_directory name */
+ dir_data->current_directory[current_directory_namelength]='\0';
+ delete_list_file(dir_list);
+ }
+}
+
+int dir_partition_aff(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const unsigned long int inode, char **current_cmd)
+{
+ if(dir_data==NULL)
+ return -1;
+ return dir_partition_aux(disk, partition, dir_data, inode, 0, current_cmd);
+}
+
+/*
+Returns
+-2: no file copied
+-1: failed to copy some files
+0: all files has been copied
+*/
+static int copy_dir(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_data_t *dir)
+{
+ file_data_t *dir_list;
+ const unsigned int current_directory_namelength=strlen(dir_data->current_directory);
+ file_data_t *current_file;
+ char *dir_name;
+ int copy_bad=0;
+ int copy_ok=0;
+ if(dir_data->get_dir==NULL || dir_data->copy_file==NULL)
+ return -2;
+ dir_name=mkdir_local(dir_data->local_dir, dir_data->current_directory);
+ dir_list=dir_data->get_dir(disk, partition, dir_data, (const unsigned long int)dir->stat.st_ino);
+ for(current_file=dir_list;current_file!=NULL;current_file=current_file->next)
+ {
+ dir_data->current_directory[current_directory_namelength]='\0';
+ if(current_directory_namelength+1+strlen(current_file->name)<sizeof(dir_data->current_directory)-1)
+ {
+ if(strcmp(dir_data->current_directory,"/"))
+ strcat(dir_data->current_directory,"/");
+ strcat(dir_data->current_directory,current_file->name);
+ if(LINUX_S_ISDIR(current_file->stat.st_mode)!=0)
+ {
+ int tmp=0;
+ if(current_file->stat.st_ino != dir->stat.st_ino &&
+ strcmp(current_file->name,"..")!=0 && strcmp(current_file->name,".")!=0)
+ tmp=copy_dir(disk, partition, dir_data, current_file);
+ if(tmp>=-1)
+ copy_ok=1;
+ if(tmp<0)
+ copy_bad=1;
+ }
+ else if(LINUX_S_ISREG(current_file->stat.st_mode)!=0)
+ {
+// log_trace("copy_file %s\n",dir_data->current_directory);
+ int tmp;
+ tmp=dir_data->copy_file(disk, partition, dir_data, current_file);
+ if(tmp==0)
+ copy_ok=1;
+ else
+ copy_bad=1;
+ }
+ }
+ }
+ dir_data->current_directory[current_directory_namelength]='\0';
+ delete_list_file(dir_list);
+ set_date(dir_name, dir->stat.st_atime, dir->stat.st_mtime);
+ free(dir_name);
+ return (copy_bad>0?(copy_ok>0?-1:-2):0);
+}
+
+#endif
diff --git a/src/dirn.h b/src/dirn.h
new file mode 100644
index 0000000..5169098
--- /dev/null
+++ b/src/dirn.h
@@ -0,0 +1,33 @@
+/*
+
+ File: dir.h
+
+ Copyright (C) 2004-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifndef _DIRN_H
+#define _DIRN_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int dir_partition_aff(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int inode, char **current_cmd);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
+#endif
diff --git a/src/dirpart.c b/src/dirpart.c
index 4085656..e19b9a3 100644
--- a/src/dirpart.c
+++ b/src/dirpart.c
@@ -48,6 +48,7 @@
#include <stdio.h>
#endif
#include "dir.h"
+#include "dirn.h"
#include "ext2_dir.h"
#include "fat_dir.h"
#include "ntfs_dir.h"
@@ -56,6 +57,7 @@
#include "ntfs.h"
#include "adv.h"
#include "log.h"
+#include "log_part.h"
int dir_partition(disk_t *disk_car, const partition_t *partition, const int verbose, char **current_cmd)
{
@@ -172,7 +174,18 @@ int dir_partition(disk_t *disk_car, const partition_t *partition, const int verb
if(recursive>0)
dir_whole_partition_log(disk_car,partition,&dir_data,dir_data.current_inode);
else
- dir_partition_aff(disk_car,partition,&dir_data,dir_data.current_inode,current_cmd);
+ {
+#ifdef HAVE_NCURSES
+ dir_partition_aff(disk_car, partition, &dir_data, dir_data.current_inode, current_cmd);
+#else
+ {
+ file_data_t *dir_list;
+ dir_list=dir_data.get_dir(disk_car, partition, &dir_data, dir_data.current_inode);
+ dir_aff_log(disk_car, partition, &dir_data, dir_list);
+ delete_list_file(dir_list);
+ }
+#endif
+ }
dir_data.close(&dir_data);
}
break;
diff --git a/src/ext2.c b/src/ext2.c
index 96b8471..620639a 100644
--- a/src/ext2.c
+++ b/src/ext2.c
@@ -23,6 +23,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
diff --git a/src/ext2_sbn.c b/src/ext2_sbn.c
new file mode 100644
index 0000000..36c5baa
--- /dev/null
+++ b/src/ext2_sbn.c
@@ -0,0 +1,135 @@
+/*
+
+ File: ext2_sbn.c
+
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include "types.h"
+#include "common.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "fnctdsk.h"
+#include "log.h"
+#include "lang.h"
+#include "ext2.h"
+#include "ext2_sbn.h"
+
+list_part_t *search_superblock(disk_t *disk_car, const partition_t *partition, const int verbose, const int dump_ind, const int interface)
+{
+ unsigned char *buffer=(unsigned char *)MALLOC(2*0x200);
+ uint64_t hd_offset;
+ int nbr_sb=0;
+ list_part_t *list_part=NULL;
+ int ind_stop=0;
+#ifdef HAVE_NCURSES
+ unsigned long int old_percent=0;
+#endif
+ struct ext2_super_block *sb=(struct ext2_super_block *)buffer;
+ partition_t *new_partition=partition_new(disk_car->arch);
+ log_trace("search_superblock\n");
+#ifdef HAVE_NCURSES
+ if(interface>0)
+ {
+ aff_copy(stdscr);
+ wmove(stdscr,4,0);
+ wprintw(stdscr,"%s",disk_car->description(disk_car));
+ mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
+ wmove(stdscr,6,0);
+ aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
+ wmove(stdscr,22,0);
+ wattrset(stdscr, A_REVERSE);
+ waddstr(stdscr," Stop ");
+ wattroff(stdscr, A_REVERSE);
+ }
+#endif
+ for(hd_offset=0;hd_offset<partition->part_size && nbr_sb<10 && ind_stop==0;hd_offset+=DEFAULT_SECTOR_SIZE)
+ {
+#ifdef HAVE_NCURSES
+ unsigned long int percent;
+ percent=hd_offset*100/partition->part_size;
+ if(interface>0 && percent!=old_percent)
+ {
+ wmove(stdscr,9,0);
+ wclrtoeol(stdscr);
+ wprintw(stdscr,"Search ext2/ext3/ext4 superblock %10lu/%lu %lu%%", (long unsigned)(hd_offset/disk_car->sector_size),
+ (long unsigned)(partition->part_size/disk_car->sector_size),percent);
+ wrefresh(stdscr);
+ ind_stop|=check_enter_key_or_s(stdscr);
+ old_percent=percent;
+ }
+#endif
+ /* ext2/ext3/ext4 */
+ if( hd_offset==(EXT2_MIN_BLOCK_SIZE<<0) ||
+ hd_offset==(EXT2_MIN_BLOCK_SIZE<<1) ||
+ hd_offset==(EXT2_MIN_BLOCK_SIZE<<2) ||
+ hd_offset==(1*(EXT2_MIN_BLOCK_SIZE<<0)*8*(EXT2_MIN_BLOCK_SIZE<<0)+2*512) ||
+ hd_offset==(1*(EXT2_MIN_BLOCK_SIZE<<1)*8*(EXT2_MIN_BLOCK_SIZE<<1)) ||
+ hd_offset==(1*(EXT2_MIN_BLOCK_SIZE<<2)*8*(EXT2_MIN_BLOCK_SIZE<<2)) ||
+ hd_offset%(3*(EXT2_MIN_BLOCK_SIZE<<0)*8*(EXT2_MIN_BLOCK_SIZE<<0)+2*512)==0 ||
+ hd_offset%(5*(EXT2_MIN_BLOCK_SIZE<<0)*8*(EXT2_MIN_BLOCK_SIZE<<0)+2*512)==0 ||
+ hd_offset%(7*(EXT2_MIN_BLOCK_SIZE<<0)*8*(EXT2_MIN_BLOCK_SIZE<<0)+2*512)==0 ||
+ hd_offset%(3*(EXT2_MIN_BLOCK_SIZE<<1)*8*(EXT2_MIN_BLOCK_SIZE<<1))==0 ||
+ hd_offset%(5*(EXT2_MIN_BLOCK_SIZE<<1)*8*(EXT2_MIN_BLOCK_SIZE<<1))==0 ||
+ hd_offset%(7*(EXT2_MIN_BLOCK_SIZE<<1)*8*(EXT2_MIN_BLOCK_SIZE<<1))==0 ||
+ hd_offset%(3*(EXT2_MIN_BLOCK_SIZE<<2)*8*(EXT2_MIN_BLOCK_SIZE<<2))==0 ||
+ hd_offset%(5*(EXT2_MIN_BLOCK_SIZE<<2)*8*(EXT2_MIN_BLOCK_SIZE<<2))==0 ||
+ hd_offset%(7*(EXT2_MIN_BLOCK_SIZE<<2)*8*(EXT2_MIN_BLOCK_SIZE<<2))==0)
+ {
+ if(disk_car->read(disk_car,1024, buffer, partition->part_offset+hd_offset)==0)
+ {
+ if(le16(sb->s_magic)==EXT2_SUPER_MAGIC)
+ {
+ dup_partition_t(new_partition,partition);
+ new_partition->part_offset+=hd_offset;
+ if(recover_EXT2(disk_car,sb,new_partition,verbose,dump_ind)==0)
+ {
+ int insert_error=0;
+ if(hd_offset<=(EXT2_MIN_BLOCK_SIZE<<2))
+ new_partition->part_offset-=hd_offset;
+ log_info("Ext2 superblock found at sector %llu (block=%llu, blocksize=%u)\n",
+ (long long unsigned) hd_offset/DEFAULT_SECTOR_SIZE,
+ (long long unsigned) hd_offset>>(EXT2_MIN_BLOCK_LOG_SIZE+le32(sb->s_log_block_size)),
+ EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size));
+#ifdef HAVE_NCURSES
+ wmove(stdscr,10+nbr_sb,0);
+ wprintw(stdscr,"Ext2 superblock found at sector %llu (block=%llu, blocksize=%u) \n",
+ (long long unsigned) hd_offset/DEFAULT_SECTOR_SIZE,
+ (long long unsigned) hd_offset>>(EXT2_MIN_BLOCK_LOG_SIZE+le32(sb->s_log_block_size)),
+ EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size));
+#endif
+ list_part=insert_new_partition(list_part, new_partition, 1, &insert_error);
+ new_partition=partition_new(disk_car->arch);
+ nbr_sb++;
+ }
+ }
+ }
+ }
+ }
+ free(new_partition);
+ free(buffer);
+ return list_part;
+}
+
diff --git a/src/ext2_sbn.h b/src/ext2_sbn.h
new file mode 100644
index 0000000..8096c08
--- /dev/null
+++ b/src/ext2_sbn.h
@@ -0,0 +1,30 @@
+/*
+
+ file: ext2_sbn.h
+
+ Copyright (C) 2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ this software is free software; you can redistribute it and/or modify
+ it under the terms of the gnu general public license as published by
+ the free software foundation; either version 2 of the license, or
+ (at your option) any later version.
+
+ this program is distributed in the hope that it will be useful,
+ but without any warranty; without even the implied warranty of
+ merchantability or fitness for a particular purpose. see the
+ gnu general public license for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+list_part_t *search_superblock(disk_t *disk_car, const partition_t *partition, const int verbose, const int dump_ind, const int interface);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/ext2grp.c b/src/ext2grp.c
index 5af5a22..61d421e 100644
--- a/src/ext2grp.c
+++ b/src/ext2grp.c
@@ -2,7 +2,7 @@
File: ext2grp.c
- Copyright (C) 2008 Christophe GRENIER <grenier@cgsecurity.org>
+ Copyright (C) 2008-2009 Christophe GRENIER <grenier@cgsecurity.org>
This software is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -40,6 +40,7 @@
#include "ext2.h"
#include "log.h"
#include "phrecn.h"
+#include "photorec.h"
unsigned int ext2_fix_group(alloc_data_t *list_search_space, disk_t *disk, partition_t *partition)
{
@@ -51,7 +52,6 @@ unsigned int ext2_fix_group(alloc_data_t *list_search_space, disk_t *disk, parti
partition->upart_type!=UP_EXT4)
{
log_error("Not a valid ext2/ext3/ext4 filesystem");
- display_message("Not a valid ext2/ext3/ext4 filesystem");
free_search_space(list_search_space);
return 0;
}
@@ -89,7 +89,6 @@ unsigned int ext2_fix_inode(alloc_data_t *list_search_space, disk_t *disk, parti
partition->upart_type!=UP_EXT4)
{
log_error("Not a valid ext2/ext3/ext4 filesystem");
- display_message("Not a valid ext2/ext3/ext4 filesystem");
free_search_space(list_search_space);
return 0;
}
diff --git a/src/ext2p.c b/src/ext2p.c
index 9a67598..80fe951 100644
--- a/src/ext2p.c
+++ b/src/ext2p.c
@@ -34,7 +34,6 @@
#include "list.h"
#include "filegen.h"
#include "intrf.h"
-#include "intrfn.h"
#include "dir.h"
#ifdef HAVE_EXT2FS_EXT2_FS_H
#include "ext2fs/ext2_fs.h"
@@ -46,6 +45,7 @@
#include "ext2_inc.h"
#include "ext2_dir.h"
#include "log.h"
+#include "log_part.h"
#ifdef HAVE_LIBEXT2FS
unsigned int ext2_remove_used_space(disk_t *disk, const partition_t *partition, alloc_data_t *list_search_space)
@@ -55,27 +55,8 @@ unsigned int ext2_remove_used_space(disk_t *disk, const partition_t *partition,
{
case -2:
case -1:
- screen_buffer_reset();
- {
-#ifdef HAVE_NCURSES
- WINDOW *window;
- window=newwin(0,0,0,0); /* full screen */
- aff_copy(window);
- wmove(window,4,0);
- aff_part(window, AFF_PART_ORDER|AFF_PART_STATUS, disk, partition);
-#endif
- log_partition(disk, partition);
- screen_buffer_add("Can't open filesystem. Filesystem seems damaged.\n");
- screen_buffer_to_log();
-#ifdef HAVE_NCURSES
- screen_buffer_display(window,"",NULL);
- delwin(window);
- (void) clearok(stdscr, TRUE);
-#ifdef HAVE_TOUCHWIN
- touchwin(stdscr);
-#endif
-#endif
- }
+ log_partition(disk, partition);
+ log_error("Can't open filesystem. Filesystem seems damaged.\n");
return 0;
}
{
diff --git a/src/fat.c b/src/fat.c
index 5889503..d9ee496 100644
--- a/src/fat.c
+++ b/src/fat.c
@@ -24,6 +24,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#include <ctype.h>
#ifdef HAVE_STRING_H
#include <string.h>
@@ -41,12 +42,8 @@
#include "fnctdsk.h"
#include "testdisk.h"
#include "intrf.h"
-#ifdef HAVE_NCURSES
-#include "intrfn.h"
-#else
-#include <stdio.h>
-#endif
#include "log.h"
+#include "log_part.h"
/* #include "guid_cmp.h" */
extern const arch_fnct_t arch_i386;
extern const arch_fnct_t arch_mac;
@@ -57,8 +54,6 @@ static int fat32_set_part_name(disk_t *disk_car, partition_t *partition, const s
static int log_fat_info(const struct fat_boot_sector*fh1, const upart_type_t upart_type, const unsigned int sector_size);
static int test_HPFS(disk_t *disk_car,const struct fat_boot_sector *fat_header, partition_t *partition,const int verbose, const int dump_ind);
static int test_OS2MB(disk_t *disk_car,const struct fat_boot_sector *fat_header, partition_t *partition,const int verbose, const int dump_ind);
-static unsigned long int fat32_get_free_count(const unsigned char *boot_fat32, const unsigned int sector_size);
-static unsigned long int fat32_get_next_free(const unsigned char *boot_fat32, const unsigned int sector_size);
#define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */
#define IS_FREE(n) (!*(n) || *(const unsigned char *) (n) == DELETED_FLAG)
@@ -124,127 +119,6 @@ static int log_fat_info(const struct fat_boot_sector*fh1, const upart_type_t upa
return 0;
}
-#ifdef HAVE_NCURSES
-static int dump_fat_info_ncurses(const struct fat_boot_sector*fh1, const upart_type_t upart_type, const unsigned int sector_size)
-{
- switch(upart_type)
- {
- case UP_FAT12:
- wprintw(stdscr,"FAT : 12\n");
- break;
- case UP_FAT16:
- wprintw(stdscr,"FAT : 16\n");
- break;
- case UP_FAT32:
- wprintw(stdscr,"FAT : 32\n");
- break;
- default:
- wprintw(stdscr,"Not a FAT\n");
- return 0;
- }
- wprintw(stdscr,"cluster_size %u\n", fh1->sectors_per_cluster);
- wprintw(stdscr,"reserved %u\n", le16(fh1->reserved));
- if(sectors(fh1)!=0)
- wprintw(stdscr,"sectors %u\n", sectors(fh1));
- if(le32(fh1->total_sect)!=0)
- wprintw(stdscr,"total_sect %u\n", (unsigned int)le32(fh1->total_sect));
- if(upart_type==UP_FAT32)
- {
- wprintw(stdscr,"fat32_length %u\n", (unsigned int)le32(fh1->fat32_length));
- wprintw(stdscr,"root_cluster %u\n", (unsigned int)le32(fh1->root_cluster));
- wprintw(stdscr,"flags %04X\n", le16(fh1->flags));
- wprintw(stdscr,"version %u.%u\n", fh1->version[0], fh1->version[1]);
- wprintw(stdscr,"root_cluster %u\n", (unsigned int)le32(fh1->root_cluster));
- wprintw(stdscr,"info_sector %u\n", le16(fh1->info_sector));
- wprintw(stdscr,"backup_boot %u\n", le16(fh1->backup_boot));
- if(fat32_get_free_count((const unsigned char*)fh1,sector_size)==0xFFFFFFFF)
- wprintw(stdscr,"free_count uninitialised\n");
- else
- wprintw(stdscr,"free_count %lu\n",fat32_get_free_count((const unsigned char*)fh1,sector_size));
- if(fat32_get_next_free((const unsigned char*)fh1,sector_size)==0xFFFFFFFF)
- wprintw(stdscr,"next_free uninitialised\n");
- else
- wprintw(stdscr,"next_free %lu\n",fat32_get_next_free((const unsigned char*)fh1,sector_size));
- } else {
- wprintw(stdscr,"fat_length %u\n", le16(fh1->fat_length));
- wprintw(stdscr,"dir_entries %u\n", get_dir_entries(fh1));
- }
- return 0;
-}
-#endif
-
-int dump_fat_info(const struct fat_boot_sector*fh1, const upart_type_t upart_type, const unsigned int sector_size)
-{
-#ifdef HAVE_NCURSES
- return dump_fat_info_ncurses(fh1, upart_type, sector_size);
-#else
- return 0;
-#endif
-}
-
-#ifdef HAVE_NCURSES
-static int dump_2fat_info_ncurses(const struct fat_boot_sector*fh1, const struct fat_boot_sector*fh2, const upart_type_t upart_type, const unsigned int sector_size)
-{
- switch(upart_type)
- {
- case UP_FAT12:
- wprintw(stdscr,"FAT : 12\n");
- break;
- case UP_FAT16:
- wprintw(stdscr,"FAT : 16\n");
- break;
- case UP_FAT32:
- wprintw(stdscr,"FAT : 32\n");
- break;
- default:
- wprintw(stdscr,"Not a FAT\n");
- return 1;
- }
- wprintw(stdscr,"cluster_size %u %u\n", fh1->sectors_per_cluster, fh2->sectors_per_cluster);
- wprintw(stdscr,"reserved %u %u\n", le16(fh1->reserved),le16(fh2->reserved));
- if(sectors(fh1)!=0 || sectors(fh2)!=0)
- wprintw(stdscr,"sectors %u %u\n", sectors(fh1), sectors(fh2));
- if(le32(fh1->total_sect)!=0 || le32(fh2->total_sect)!=0)
- wprintw(stdscr,"total_sect %u %u\n", (unsigned int)le32(fh1->total_sect), (unsigned int)le32(fh2->total_sect));
- if(upart_type==UP_FAT32)
- {
- wprintw(stdscr,"fat32_length %u %u\n", (unsigned int)le32(fh1->fat32_length), (unsigned int)le32(fh2->fat32_length));
- wprintw(stdscr,"root_cluster %u %u\n", (unsigned int)le32(fh1->root_cluster), (unsigned int)le32(fh2->root_cluster));
- wprintw(stdscr,"free_count ");
- if(fat32_get_free_count((const unsigned char*)fh1,sector_size)==0xFFFFFFFF)
- wprintw(stdscr,"uninitialised ");
- else
- wprintw(stdscr,"%lu ",fat32_get_free_count((const unsigned char*)fh1,sector_size));
- if(fat32_get_free_count((const unsigned char*)fh2,sector_size)==0xFFFFFFFF)
- wprintw(stdscr,"uninitialised\n");
- else
- wprintw(stdscr,"%lu\n",fat32_get_free_count((const unsigned char*)fh2,sector_size));
- wprintw(stdscr,"next_free ");
- if(fat32_get_next_free((const unsigned char*)fh1,sector_size)==0xFFFFFFFF)
- wprintw(stdscr,"uninitialised ");
- else
- wprintw(stdscr,"%lu ",fat32_get_next_free((const unsigned char*)fh1,sector_size));
- if(fat32_get_next_free((const unsigned char*)fh2,sector_size)==0xFFFFFFFF)
- wprintw(stdscr,"uninitialised\n");
- else
- wprintw(stdscr,"%lu\n",fat32_get_next_free((const unsigned char*)fh2,sector_size));
- } else {
- wprintw(stdscr,"fat_length %u %u\n", le16(fh1->fat_length), le16(fh2->fat_length));
- wprintw(stdscr,"dir_entries %u %u\n", get_dir_entries(fh1), get_dir_entries(fh2));
- }
- return 0;
-}
-#endif
-
-int dump_2fat_info(const struct fat_boot_sector*fh1, const struct fat_boot_sector*fh2, const upart_type_t upart_type, const unsigned int sector_size)
-{
-#ifdef HAVE_NCURSES
- return dump_2fat_info_ncurses(fh1, fh2, upart_type, sector_size);
-#else
- return 0;
-#endif
-}
-
int log_fat2_info(const struct fat_boot_sector*fh1, const struct fat_boot_sector*fh2, const upart_type_t upart_type, const unsigned int sector_size)
{
switch(upart_type)
@@ -493,7 +367,7 @@ int set_next_cluster(disk_t *disk_car,const partition_t *partition, const upart_
}
if(disk_car->write(disk_car,buffer_size, buffer, partition->part_offset+(uint64_t)(offset+offset_s)*disk_car->sector_size)!=0)
{
- display_message("Write error: set_next_cluster write error\n");
+ log_error("Write error: set_next_cluster write error\n");
free(buffer);
return 1;
}
@@ -553,15 +427,13 @@ int test_FAT(disk_t *disk_car,const struct fat_boot_sector *fat_header, partitio
&& (fat_header->ignored[0]==0xeb || fat_header->ignored[0]==0xe9)
&& (fat_header->fats==1 || fat_header->fats==2)))
return 1; /* Obviously not a FAT */
- if(verbose>1)
+ if(verbose>1 || dump_ind!=0)
{
log_trace("test_FAT\n");
log_partition(disk_car,partition);
}
-#ifdef HAVE_NCURSES
if(dump_ind!=0)
- dump_ncurses(fat_header,DEFAULT_SECTOR_SIZE);
-#endif
+ dump_log(fat_header, DEFAULT_SECTOR_SIZE);
if(!((fat_header->ignored[0]==0xeb && fat_header->ignored[2]==0x90)||fat_header->ignored[0]==0xe9))
{
screen_buffer_add(msg_CHKFAT_BAD_JUMP);
@@ -852,12 +724,12 @@ unsigned int get_dir_entries(const struct fat_boot_sector *fat_header)
unsigned int sectors(const struct fat_boot_sector *fat_header)
{ return (fat_header->sectors[1]<<8)+fat_header->sectors[0]; }
-static unsigned long int fat32_get_free_count(const unsigned char *boot_fat32, const unsigned int sector_size)
+unsigned long int fat32_get_free_count(const unsigned char *boot_fat32, const unsigned int sector_size)
{
return (boot_fat32[sector_size+0x1E8+3]<<24)+(boot_fat32[sector_size+0x1E8+2]<<16)+(boot_fat32[sector_size+0x1E8+1]<<8)+boot_fat32[sector_size+0x1E8];
}
-static unsigned long int fat32_get_next_free(const unsigned char *boot_fat32, const unsigned int sector_size)
+unsigned long int fat32_get_next_free(const unsigned char *boot_fat32, const unsigned int sector_size)
{
return (boot_fat32[sector_size+0x1EC+3]<<24)+(boot_fat32[sector_size+0x1EC+2]<<16)+(boot_fat32[sector_size+0x1EC+1]<<8)+boot_fat32[sector_size+0x1EC];
}
@@ -954,7 +826,6 @@ static int fat32_set_part_name(disk_t *disk_car, partition_t *partition, const s
{ /* Test attribut volume name and check if the volume name is erased or not */
if(((buffer[i*0x20+0xB] & ATTR_EXT) !=ATTR_EXT) && ((buffer[i*0x20+0xB] & ATTR_VOLUME) !=0) && (buffer[i*0x20]!=0xE5))
{
- /* dump_ncurses(&buffer[i*0x20],0x20); */
fat_set_part_name(partition,&buffer[i*0x20],11);
if(check_VFAT_volume_name(partition->fsname, 11))
partition->fsname[0]='\0';
@@ -1014,10 +885,8 @@ static int test_HPFS(disk_t *disk_car,const struct fat_boot_sector *fat_header,
offset2head(disk_car,partition->part_offset),
offset2sector(disk_car,partition->part_offset));
}
-#ifdef HAVE_NCURSES
- if(dump_ind)
- dump_ncurses(buffer,DEFAULT_SECTOR_SIZE);
-#endif
+ if(dump_ind!=0)
+ dump_log(buffer, DEFAULT_SECTOR_SIZE);
partition->part_size=(uint64_t)(sectors(fat_header)>0?sectors(fat_header):le32(fat_header->total_sect)) *
fat_sector_size(fat_header);
partition->upart_type=UP_HPFS;
@@ -1078,12 +947,10 @@ static int test_OS2MB(disk_t *disk_car,const struct fat_boot_sector *fat_header,
{
if(verbose||dump_ind)
{
- log_info("\nMarker (0xAA55) at %u/%u/%u\n", offset2cylinder(disk_car,partition->part_offset),offset2head(disk_car,partition->part_offset),offset2sector(disk_car,partition->part_offset));
+ log_info("OS2MB at %u/%u/%u\n", offset2cylinder(disk_car,partition->part_offset),offset2head(disk_car,partition->part_offset),offset2sector(disk_car,partition->part_offset));
}
-#ifdef HAVE_NCURSES
if(dump_ind)
- dump_ncurses(buffer,DEFAULT_SECTOR_SIZE);
-#endif
+ dump_log(buffer,DEFAULT_SECTOR_SIZE);
partition->upart_type=UP_OS2MB;
return 0;
}
diff --git a/src/fat.h b/src/fat.h
index 5517cc0..1d46c32 100644
--- a/src/fat.h
+++ b/src/fat.h
@@ -120,12 +120,12 @@ int is_part_fat12(const partition_t *partition);
int is_part_fat16(const partition_t *partition);
int is_part_fat32(const partition_t *partition);
unsigned int get_dir_entries(const struct fat_boot_sector *fat_header);
-int dump_fat_info(const struct fat_boot_sector*fh1, const upart_type_t upart_type, const unsigned int sector_size);
-int dump_2fat_info(const struct fat_boot_sector*fh1, const struct fat_boot_sector*fh2, const upart_type_t upart_type, const unsigned int sector_size);
unsigned int fat_sector_size(const struct fat_boot_sector *fat_header);
unsigned int sectors(const struct fat_boot_sector *fat_header);
unsigned int fat32_get_prev_cluster(disk_t *disk_car,const partition_t *partition, const unsigned int fat_offset, const unsigned int cluster, const unsigned int no_of_cluster);
int fat32_free_info(disk_t *disk_car,const partition_t *partition, const unsigned int fat_offset, const unsigned int no_of_cluster, unsigned int *next_free, unsigned int*free_count);
+unsigned long int fat32_get_free_count(const unsigned char *boot_fat32, const unsigned int sector_size);
+unsigned long int fat32_get_next_free(const unsigned char *boot_fat32, const unsigned int sector_size);
#define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */
#define IS_FREE(n) (!*(n) || *(const unsigned char *) (n) == DELETED_FLAG)
diff --git a/src/fat1x.c b/src/fat1x.c
index 7432c6d..e8beaef 100644
--- a/src/fat1x.c
+++ b/src/fat1x.c
@@ -23,6 +23,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -37,6 +38,7 @@
#include "dirpart.h"
#include "fat.h"
#include "log.h"
+#include "log_part.h"
#include "fat_adv.h"
#include "fat1x.h"
diff --git a/src/fat32.c b/src/fat32.c
index d06582f..b83da0f 100644
--- a/src/fat32.c
+++ b/src/fat32.c
@@ -23,6 +23,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -39,6 +40,7 @@
#include "fat.h"
#include "io_redir.h"
#include "log.h"
+#include "log_part.h"
#include "fat_adv.h"
#include "fat32.h"
@@ -262,6 +264,7 @@ int fat32_boot_sector(disk_t *disk_car, partition_t *partition, const int verbos
free(buffer_backup_bs);
return 0;
case 'O': /* O : copy original boot sector over backup boot */
+#ifdef HAVE_NCURSES
if(ask_confirmation("Copy original FAT32 boot sector over backup boot, confirm ? (Y/N)")!=0)
{
log_info("copy original boot sector over backup boot\n");
@@ -272,8 +275,10 @@ int fat32_boot_sector(disk_t *disk_car, partition_t *partition, const int verbos
disk_car->sync(disk_car);
rescan=1;
}
+#endif
break;
case 'B': /* B : copy backup boot sector over boot sector */
+#ifdef HAVE_NCURSES
if(ask_confirmation("Copy backup FAT32 boot sector over boot sector, confirm ? (Y/N)")!=0)
{
log_info("copy backup boot sector over boot sector\n");
@@ -284,6 +289,7 @@ int fat32_boot_sector(disk_t *disk_car, partition_t *partition, const int verbos
disk_car->sync(disk_car);
rescan=1;
}
+#endif
break;
case 'C':
repair_FAT_table(disk_car,partition,verbose);
diff --git a/src/fat_adv.c b/src/fat_adv.c
index 00701f9..9e4237a 100644
--- a/src/fat_adv.c
+++ b/src/fat_adv.c
@@ -2,7 +2,7 @@
File: fat_adv.c
- Copyright (C) 1998-2008 Christophe GRENIER <grenier@cgsecurity.org>
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
This software is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,6 +24,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#include <ctype.h>
#ifdef HAVE_STRING_H
#include <string.h>
@@ -44,17 +45,17 @@
#include "fnctdsk.h"
#include "testdisk.h"
#include "intrf.h"
-#ifdef HAVE_NCURSES
#include "intrfn.h"
-#else
-#include <stdio.h>
-#endif
#include "dir.h"
#include "dirpart.h"
#include "fat_dir.h"
#include "io_redir.h"
#include "log.h"
+#include "log_part.h"
#include "fat_adv.h"
+#ifdef HAVE_NCURSES
+#include "fatn.h"
+#endif
#define INTER_FAT_ASK_X 0
#define INTER_FAT_ASK_Y 23
@@ -100,11 +101,11 @@ static int analyse_dir_entries(disk_t *disk_car,const partition_t *partition, co
static int analyse_dir_entries2(disk_t *disk_car,const partition_t *partition, const unsigned int reserved, const unsigned int fat_length,const int verbose, unsigned int root_size_max,const upart_type_t upart_type, const unsigned int fats);
static int calcul_sectors_per_cluster(const upart_type_t upart_type, const unsigned long int data_size, const unsigned int fat_length, const unsigned int sector_size);
static int check_FAT_dir_entry(const unsigned char *entry, const unsigned int entry_nr);
-static int fat32_create_rootdir(disk_t *disk_car,const partition_t *partition, const unsigned int reserved, const unsigned int fat_length, const unsigned int root_cluster, const unsigned int sectors_per_cluster, const int verbose, file_data_t *rootdir_list, const unsigned int fats);
-
-static void fat_date_unix2dos(int unix_date,unsigned short *mstime, unsigned short *msdate);
static unsigned long int get_subdirectory(disk_t *disk_car,const uint64_t hd_offset, const unsigned long int i);
+
#ifdef HAVE_NCURSES
+static void fat_date_unix2dos(int unix_date,unsigned short *mstime, unsigned short *msdate);
+static int fat32_create_rootdir(disk_t *disk_car,const partition_t *partition, const unsigned int reserved, const unsigned int fat_length, const unsigned int root_cluster, const unsigned int sectors_per_cluster, const int verbose, file_data_t *rootdir_list, const unsigned int fats);
static upart_type_t select_fat_info(const info_offset_t *info_offset, const unsigned int nbr_offset,unsigned int*reserved, unsigned int*fat_length, const unsigned long int max_sector_offset, unsigned int *fats);
#endif
@@ -552,7 +553,7 @@ static unsigned int fat32_find_root_cluster(disk_t *disk_car,const partition_t *
else
{
dir_aff_log(disk_car, partition, NULL, rootdir_list);
- /* && (ind_stop==0) */
+#ifdef HAVE_NCURSES
if(interface && (expert>0))
{
if(ask_confirmation("Create a new root cluster with %u first-level directories (Expert only) (Y/N)",dir_nbr)!=0 && ask_confirmation("Write root cluster, confirm ? (Y/N)")!=0)
@@ -561,6 +562,7 @@ static unsigned int fat32_find_root_cluster(disk_t *disk_car,const partition_t *
fat32_create_rootdir(disk_car, partition, reserved, fat_length, root_cluster, sectors_per_cluster, verbose, rootdir_list, fats);
}
}
+#endif
delete_list_file(rootdir_list);
}
free(buffer);
@@ -568,6 +570,7 @@ static unsigned int fat32_find_root_cluster(disk_t *disk_car,const partition_t *
return root_cluster;
}
+#ifdef HAVE_NCURSES
static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 };
/* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */
@@ -659,9 +662,15 @@ static int fat32_create_rootdir(disk_t *disk_car,const partition_t *partition, c
memset(buffer,0,cluster_size);
/* FIXME need to write fat32_get_next_free_cluster */
next_cluster=cluster++;
- set_next_cluster(disk_car,partition,UP_FAT32,reserved,cluster,next_cluster);
- set_next_cluster(disk_car,partition,UP_FAT32,reserved+fat_length,cluster,next_cluster);
- cluster=next_cluster;
+ if(set_next_cluster(disk_car,partition,UP_FAT32,reserved,cluster,next_cluster))
+ {
+ display_message("Can't modify the FAT entries.\n");
+ }
+ if(set_next_cluster(disk_car,partition,UP_FAT32,reserved+fat_length,cluster,next_cluster))
+ {
+ display_message("Can't modify the FAT entries.\n");
+ }
+cluster=next_cluster;
}
}
if(disk_car->write(disk_car,cluster_size, buffer,
@@ -669,8 +678,14 @@ static int fat32_create_rootdir(disk_t *disk_car,const partition_t *partition, c
{
display_message("Write error: Can't create FAT32 root cluster.\n");
}
- set_next_cluster(disk_car,partition,UP_FAT32,reserved,cluster,FAT32_EOC);
- set_next_cluster(disk_car,partition,UP_FAT32,reserved+fat_length,cluster,FAT32_EOC);
+ if(set_next_cluster(disk_car,partition,UP_FAT32,reserved,cluster,FAT32_EOC))
+ {
+ display_message("Can't modify the FAT entries.\n");
+ }
+ if(set_next_cluster(disk_car,partition,UP_FAT32,reserved+fat_length,cluster,FAT32_EOC))
+ {
+ display_message("Can't modify the FAT entries.\n");
+ }
#ifdef DEBUG
{
file_data_t *dir_list;
@@ -682,6 +697,7 @@ static int fat32_create_rootdir(disk_t *disk_car,const partition_t *partition, c
free(buffer);
return 0;
}
+#endif
static int find_dir_entries(disk_t *disk_car,const partition_t *partition, const unsigned int offset,const int verbose)
{
@@ -901,7 +917,6 @@ static void fat32_dump(disk_t *disk_car, const partition_t *partition, const upa
static void menu_write_fat_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const upart_type_t upart_type, const unsigned char *orgboot, const unsigned char*newboot, const int error, char **current_cmd)
{
- const struct fat_boot_sector *org_fat_header=(const struct fat_boot_sector *)orgboot;
const struct fat_boot_sector *fat_header=(const struct fat_boot_sector *)newboot;
#ifdef HAVE_NCURSES
struct MenuItem menuSaveBoot[]=
@@ -932,8 +947,9 @@ static void menu_write_fat_boot_sector(disk_t *disk_car, partition_t *partition,
#endif
if(memcmp(newboot,orgboot,DEFAULT_SECTOR_SIZE)) /* Only compare the first sector */
{
- dump_2fat_info(fat_header, org_fat_header, upart_type,disk_car->sector_size);
#ifdef HAVE_NCURSES
+ const struct fat_boot_sector *org_fat_header=(const struct fat_boot_sector *)orgboot;
+ dump_2fat_info_ncurses(fat_header, org_fat_header, upart_type,disk_car->sector_size);
wprintw(stdscr,"Extrapolated boot sector and current boot sector are different.\n");
if(error)
wprintw(stdscr,"Warning: Extrapolated boot sector have incorrect values.\n");
@@ -944,8 +960,8 @@ static void menu_write_fat_boot_sector(disk_t *disk_car, partition_t *partition,
}
else
{
- dump_fat_info(fat_header, upart_type,disk_car->sector_size);
#ifdef HAVE_NCURSES
+ dump_fat_info_ncurses(fat_header, upart_type,disk_car->sector_size);
wprintw(stdscr,"Extrapolated boot sector and current boot sector are identical.\n");
#endif
}
@@ -1013,7 +1029,11 @@ static void menu_write_fat_boot_sector(disk_t *disk_car, partition_t *partition,
break;
}
} while(do_write==0 && do_exit==0);
- if(do_write!=0 && (no_confirm!=0 || ask_confirmation("Write FAT boot sector, confirm ? (Y/N)")!=0))
+ if(do_write!=0 && (no_confirm!=0
+#ifdef HAVE_NCURSES
+ || ask_confirmation("Write FAT boot sector, confirm ? (Y/N)")!=0
+#endif
+ ))
{
int err=0;
log_info("Write new boot!\n");
@@ -2395,6 +2415,7 @@ int FAT_init_rootdir(disk_t *disk_car, partition_t *partition, const int verbose
free(buffer);
return 0;
}
+#ifdef HAVE_NCURSES
if(ask_confirmation("Initialize FAT root directory, confirm ? (Y/N)")!=0)
{
int err=0;
@@ -2415,6 +2436,7 @@ int FAT_init_rootdir(disk_t *disk_car, partition_t *partition, const int verbose
return 1;
}
}
+#endif
free(buffer);
return 0;
}
@@ -2588,11 +2610,13 @@ int repair_FAT_table(disk_t *disk_car, partition_t *partition, const int verbose
}
if(allow_write[fat_nbr]==FAT_REPAIR_ASK)
{
+#ifdef HAVE_NCURSES
if(ask_confirmation("Use FAT%u to repair FAT%u table, confirm ? (Y/N)",good_fat_nbr+1,fat_nbr+1)!=0)
{
allow_write[fat_nbr]=FAT_REPAIR_YES;
}
else
+#endif
{
allow_write[fat_nbr]=FAT_REPAIR_NO;
log_info("repair_FAT_table: doesn't correct FAT%u (sector %lu) using FAT%u\n",fat_nbr+1,
@@ -2618,11 +2642,13 @@ int repair_FAT_table(disk_t *disk_car, partition_t *partition, const int verbose
{
if(allow_write[fat_nbr]==FAT_REPAIR_ASK)
{
+#ifdef HAVE_NCURSES
if(ask_confirmation("Remove invalid cluster from FAT%u table, confirm ? (Y/N)",fat_nbr+1)!=0)
{
allow_write[fat_nbr]=FAT_REPAIR_YES;
}
else
+#endif
{
allow_write[fat_nbr]=FAT_REPAIR_NO;
log_info("repair_FAT_table: doesn't correct FAT%u (sector %lu)\n",fat_nbr+1,
@@ -2656,6 +2682,7 @@ int repair_FAT_table(disk_t *disk_car, partition_t *partition, const int verbose
}
if(allow_write[fat_nbr]==FAT_REPAIR_ASK)
{
+#ifdef HAVE_NCURSES
if(ask_confirmation("Remove invalid cluster from FAT%u table, confirm ? (Y/N)",fat_nbr+1)!=0)
{
allow_write[fat_nbr]=FAT_REPAIR_YES;
@@ -2663,6 +2690,7 @@ int repair_FAT_table(disk_t *disk_car, partition_t *partition, const int verbose
start_fat1+fat_length*fat_nbr+old_offset_s);
}
else
+#endif
{
allow_write[fat_nbr]=FAT_REPAIR_NO;
log_info("repair_FAT_table: doesn't correct FAT%u (sector %lu)\n",fat_nbr+1,
@@ -2826,6 +2854,7 @@ int repair_FAT_table(disk_t *disk_car, partition_t *partition, const int verbose
}
if(allow_write[fat_nbr]==FAT_REPAIR_ASK)
{
+#ifdef HAVE_NCURSES
if(ask_confirmation("Use FAT%u to repair FAT%u table, confirm ? (Y/N)",good_fat_nbr+1,fat_nbr+1)!=0)
{
allow_write[fat_nbr]=FAT_REPAIR_YES;
@@ -2833,6 +2862,7 @@ int repair_FAT_table(disk_t *disk_car, partition_t *partition, const int verbose
start_fat1+fat_length*fat_nbr+old_offset_s, good_fat_nbr+1);
}
else
+#endif
{
allow_write[fat_nbr]=FAT_REPAIR_NO;
log_info("repair_FAT_table: doesn't correct FAT%u (sector %lu) using FAT%u\n",fat_nbr+1,
@@ -2856,6 +2886,7 @@ int repair_FAT_table(disk_t *disk_car, partition_t *partition, const int verbose
{
if(allow_write[fat_nbr]==FAT_REPAIR_ASK)
{
+#ifdef HAVE_NCURSES
if(ask_confirmation("Remove invalid cluster from FAT%u table, confirm ? (Y/N)",fat_nbr+1)!=0)
{
allow_write[fat_nbr]=FAT_REPAIR_YES;
@@ -2863,6 +2894,7 @@ int repair_FAT_table(disk_t *disk_car, partition_t *partition, const int verbose
start_fat1+fat_length*fat_nbr+old_offset_s);
}
else
+#endif
{
allow_write[fat_nbr]=FAT_REPAIR_NO;
log_info("repair_FAT_table: doesn't correct FAT%u (sector %lu)\n",fat_nbr+1,
@@ -2894,6 +2926,7 @@ int repair_FAT_table(disk_t *disk_car, partition_t *partition, const int verbose
}
if(allow_write[fat_nbr]==FAT_REPAIR_ASK)
{
+#ifdef HAVE_NCURSES
if(ask_confirmation("Remove invalid cluster from FAT%u table, confirm ? (Y/N)",fat_nbr+1)!=0)
{
allow_write[fat_nbr]=FAT_REPAIR_YES;
@@ -2901,6 +2934,7 @@ int repair_FAT_table(disk_t *disk_car, partition_t *partition, const int verbose
start_fat1+fat_length*fat_nbr+old_offset_s);
}
else
+#endif
{
allow_write[fat_nbr]=FAT_REPAIR_NO;
log_info("repair_FAT_table: doesn't correct FAT%u (sector %lu)\n",fat_nbr+1,
diff --git a/src/fatn.c b/src/fatn.c
new file mode 100644
index 0000000..60662de
--- /dev/null
+++ b/src/fatn.c
@@ -0,0 +1,133 @@
+/*
+
+ File: fatn.c
+
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_NCURSES
+#include "types.h"
+#include "common.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "fat.h"
+#include "fatn.h"
+
+int dump_fat_info_ncurses(const struct fat_boot_sector*fh1, const upart_type_t upart_type, const unsigned int sector_size)
+{
+ switch(upart_type)
+ {
+ case UP_FAT12:
+ wprintw(stdscr,"FAT : 12\n");
+ break;
+ case UP_FAT16:
+ wprintw(stdscr,"FAT : 16\n");
+ break;
+ case UP_FAT32:
+ wprintw(stdscr,"FAT : 32\n");
+ break;
+ default:
+ wprintw(stdscr,"Not a FAT\n");
+ return 0;
+ }
+ wprintw(stdscr,"cluster_size %u\n", fh1->sectors_per_cluster);
+ wprintw(stdscr,"reserved %u\n", le16(fh1->reserved));
+ if(sectors(fh1)!=0)
+ wprintw(stdscr,"sectors %u\n", sectors(fh1));
+ if(le32(fh1->total_sect)!=0)
+ wprintw(stdscr,"total_sect %u\n", (unsigned int)le32(fh1->total_sect));
+ if(upart_type==UP_FAT32)
+ {
+ wprintw(stdscr,"fat32_length %u\n", (unsigned int)le32(fh1->fat32_length));
+ wprintw(stdscr,"root_cluster %u\n", (unsigned int)le32(fh1->root_cluster));
+ wprintw(stdscr,"flags %04X\n", le16(fh1->flags));
+ wprintw(stdscr,"version %u.%u\n", fh1->version[0], fh1->version[1]);
+ wprintw(stdscr,"root_cluster %u\n", (unsigned int)le32(fh1->root_cluster));
+ wprintw(stdscr,"info_sector %u\n", le16(fh1->info_sector));
+ wprintw(stdscr,"backup_boot %u\n", le16(fh1->backup_boot));
+ if(fat32_get_free_count((const unsigned char*)fh1,sector_size)==0xFFFFFFFF)
+ wprintw(stdscr,"free_count uninitialised\n");
+ else
+ wprintw(stdscr,"free_count %lu\n",fat32_get_free_count((const unsigned char*)fh1,sector_size));
+ if(fat32_get_next_free((const unsigned char*)fh1,sector_size)==0xFFFFFFFF)
+ wprintw(stdscr,"next_free uninitialised\n");
+ else
+ wprintw(stdscr,"next_free %lu\n",fat32_get_next_free((const unsigned char*)fh1,sector_size));
+ } else {
+ wprintw(stdscr,"fat_length %u\n", le16(fh1->fat_length));
+ wprintw(stdscr,"dir_entries %u\n", get_dir_entries(fh1));
+ }
+ return 0;
+}
+
+int dump_2fat_info_ncurses(const struct fat_boot_sector*fh1, const struct fat_boot_sector*fh2, const upart_type_t upart_type, const unsigned int sector_size)
+{
+ switch(upart_type)
+ {
+ case UP_FAT12:
+ wprintw(stdscr,"FAT : 12\n");
+ break;
+ case UP_FAT16:
+ wprintw(stdscr,"FAT : 16\n");
+ break;
+ case UP_FAT32:
+ wprintw(stdscr,"FAT : 32\n");
+ break;
+ default:
+ wprintw(stdscr,"Not a FAT\n");
+ return 1;
+ }
+ wprintw(stdscr,"cluster_size %u %u\n", fh1->sectors_per_cluster, fh2->sectors_per_cluster);
+ wprintw(stdscr,"reserved %u %u\n", le16(fh1->reserved),le16(fh2->reserved));
+ if(sectors(fh1)!=0 || sectors(fh2)!=0)
+ wprintw(stdscr,"sectors %u %u\n", sectors(fh1), sectors(fh2));
+ if(le32(fh1->total_sect)!=0 || le32(fh2->total_sect)!=0)
+ wprintw(stdscr,"total_sect %u %u\n", (unsigned int)le32(fh1->total_sect), (unsigned int)le32(fh2->total_sect));
+ if(upart_type==UP_FAT32)
+ {
+ wprintw(stdscr,"fat32_length %u %u\n", (unsigned int)le32(fh1->fat32_length), (unsigned int)le32(fh2->fat32_length));
+ wprintw(stdscr,"root_cluster %u %u\n", (unsigned int)le32(fh1->root_cluster), (unsigned int)le32(fh2->root_cluster));
+ wprintw(stdscr,"free_count ");
+ if(fat32_get_free_count((const unsigned char*)fh1,sector_size)==0xFFFFFFFF)
+ wprintw(stdscr,"uninitialised ");
+ else
+ wprintw(stdscr,"%lu ",fat32_get_free_count((const unsigned char*)fh1,sector_size));
+ if(fat32_get_free_count((const unsigned char*)fh2,sector_size)==0xFFFFFFFF)
+ wprintw(stdscr,"uninitialised\n");
+ else
+ wprintw(stdscr,"%lu\n",fat32_get_free_count((const unsigned char*)fh2,sector_size));
+ wprintw(stdscr,"next_free ");
+ if(fat32_get_next_free((const unsigned char*)fh1,sector_size)==0xFFFFFFFF)
+ wprintw(stdscr,"uninitialised ");
+ else
+ wprintw(stdscr,"%lu ",fat32_get_next_free((const unsigned char*)fh1,sector_size));
+ if(fat32_get_next_free((const unsigned char*)fh2,sector_size)==0xFFFFFFFF)
+ wprintw(stdscr,"uninitialised\n");
+ else
+ wprintw(stdscr,"%lu\n",fat32_get_next_free((const unsigned char*)fh2,sector_size));
+ } else {
+ wprintw(stdscr,"fat_length %u %u\n", le16(fh1->fat_length), le16(fh2->fat_length));
+ wprintw(stdscr,"dir_entries %u %u\n", get_dir_entries(fh1), get_dir_entries(fh2));
+ }
+ return 0;
+}
+#endif
diff --git a/src/fatn.h b/src/fatn.h
new file mode 100644
index 0000000..1f6d343
--- /dev/null
+++ b/src/fatn.h
@@ -0,0 +1,36 @@
+
+/*
+
+ File: fatn.h
+
+ Copyright (C) 1998-2004,2007-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+#ifndef _FATN_H
+#define _FATN_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int dump_fat_info_ncurses(const struct fat_boot_sector*fh1, const upart_type_t upart_type, const unsigned int sector_size);
+int dump_2fat_info_ncurses(const struct fat_boot_sector*fh1, const struct fat_boot_sector*fh2, const upart_type_t upart_type, const unsigned int sector_size);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
+#endif
diff --git a/src/file_jpg.h b/src/file_jpg.h
index b221f9d..129879f 100644
--- a/src/file_jpg.h
+++ b/src/file_jpg.h
@@ -19,6 +19,12 @@
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
int64_t test_jpeg(FILE *infile);
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/file_list.c b/src/file_list.c
new file mode 100644
index 0000000..09db6ef
--- /dev/null
+++ b/src/file_list.c
@@ -0,0 +1,345 @@
+/*
+
+ File: file_list.c
+
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include "types.h"
+#include "filegen.h"
+
+extern const file_hint_t file_hint_7z;
+extern const file_hint_t file_hint_a;
+extern const file_hint_t file_hint_abcdp;
+extern const file_hint_t file_hint_accdb;
+extern const file_hint_t file_hint_ace;
+extern const file_hint_t file_hint_addressbook;
+extern const file_hint_t file_hint_ahn;
+extern const file_hint_t file_hint_aif;
+extern const file_hint_t file_hint_all;
+extern const file_hint_t file_hint_als;
+extern const file_hint_t file_hint_amd;
+extern const file_hint_t file_hint_amr;
+extern const file_hint_t file_hint_ape;
+extern const file_hint_t file_hint_arj;
+extern const file_hint_t file_hint_asf;
+extern const file_hint_t file_hint_asm;
+extern const file_hint_t file_hint_atd;
+extern const file_hint_t file_hint_au;
+extern const file_hint_t file_hint_bkf;
+extern const file_hint_t file_hint_blend;
+extern const file_hint_t file_hint_bmp;
+extern const file_hint_t file_hint_bz2;
+extern const file_hint_t file_hint_cab;
+extern const file_hint_t file_hint_cam;
+extern const file_hint_t file_hint_chm;
+extern const file_hint_t file_hint_cm;
+extern const file_hint_t file_hint_compress;
+extern const file_hint_t file_hint_crw;
+extern const file_hint_t file_hint_ctg;
+extern const file_hint_t file_hint_cwk;
+extern const file_hint_t file_hint_dat;
+extern const file_hint_t file_hint_dbf;
+extern const file_hint_t file_hint_dim;
+extern const file_hint_t file_hint_dir;
+extern const file_hint_t file_hint_djv;
+extern const file_hint_t file_hint_doc;
+extern const file_hint_t file_hint_dpx;
+extern const file_hint_t file_hint_drw;
+extern const file_hint_t file_hint_ds2;
+extern const file_hint_t file_hint_dsc;
+extern const file_hint_t file_hint_dss;
+extern const file_hint_t file_hint_dta;
+extern const file_hint_t file_hint_dump;
+extern const file_hint_t file_hint_dv;
+extern const file_hint_t file_hint_dwg;
+extern const file_hint_t file_hint_elf;
+extern const file_hint_t file_hint_emf;
+extern const file_hint_t file_hint_evt;
+extern const file_hint_t file_hint_exe;
+extern const file_hint_t file_hint_ext2_sb;
+extern const file_hint_t file_hint_fbk;
+extern const file_hint_t file_hint_fcp;
+extern const file_hint_t file_hint_fcs;
+extern const file_hint_t file_hint_fdb;
+extern const file_hint_t file_hint_fh10;
+extern const file_hint_t file_hint_fh5;
+extern const file_hint_t file_hint_fits;
+extern const file_hint_t file_hint_flac;
+extern const file_hint_t file_hint_fasttxt;
+extern const file_hint_t file_hint_flv;
+extern const file_hint_t file_hint_fob;
+extern const file_hint_t file_hint_frm;
+extern const file_hint_t file_hint_fs;
+extern const file_hint_t file_hint_gho;
+extern const file_hint_t file_hint_gif;
+extern const file_hint_t file_hint_gpg;
+extern const file_hint_t file_hint_gz;
+extern const file_hint_t file_hint_ifo;
+extern const file_hint_t file_hint_imb;
+extern const file_hint_t file_hint_indd;
+extern const file_hint_t file_hint_iso;
+extern const file_hint_t file_hint_itunes;
+extern const file_hint_t file_hint_jpg;
+extern const file_hint_t file_hint_kdb;
+extern const file_hint_t file_hint_logic;
+extern const file_hint_t file_hint_lnk;
+extern const file_hint_t file_hint_m2ts;
+extern const file_hint_t file_hint_max;
+extern const file_hint_t file_hint_mb;
+extern const file_hint_t file_hint_mcd;
+extern const file_hint_t file_hint_mdb;
+extern const file_hint_t file_hint_mdf;
+extern const file_hint_t file_hint_mfa;
+extern const file_hint_t file_hint_mfg;
+extern const file_hint_t file_hint_mid;
+extern const file_hint_t file_hint_mkv;
+extern const file_hint_t file_hint_mov;
+extern const file_hint_t file_hint_mp3;
+extern const file_hint_t file_hint_mpg;
+extern const file_hint_t file_hint_mrw;
+extern const file_hint_t file_hint_mus;
+extern const file_hint_t file_hint_mysql;
+extern const file_hint_t file_hint_njx;
+extern const file_hint_t file_hint_ogg;
+extern const file_hint_t file_hint_one;
+extern const file_hint_t file_hint_orf;
+extern const file_hint_t file_hint_paf;
+extern const file_hint_t file_hint_pap;
+extern const file_hint_t file_hint_pcap;
+extern const file_hint_t file_hint_pct;
+extern const file_hint_t file_hint_pcx;
+extern const file_hint_t file_hint_pdf;
+extern const file_hint_t file_hint_pfx;
+extern const file_hint_t file_hint_png;
+extern const file_hint_t file_hint_prc;
+extern const file_hint_t file_hint_prt;
+extern const file_hint_t file_hint_ps;
+extern const file_hint_t file_hint_psd;
+extern const file_hint_t file_hint_psp;
+extern const file_hint_t file_hint_pst;
+extern const file_hint_t file_hint_ptb;
+extern const file_hint_t file_hint_qbb;
+extern const file_hint_t file_hint_qdf;
+extern const file_hint_t file_hint_qxd;
+extern const file_hint_t file_hint_ra;
+extern const file_hint_t file_hint_raf;
+extern const file_hint_t file_hint_rar;
+extern const file_hint_t file_hint_raw;
+extern const file_hint_t file_hint_rdc;
+extern const file_hint_t file_hint_reg;
+extern const file_hint_t file_hint_res;
+extern const file_hint_t file_hint_riff;
+extern const file_hint_t file_hint_rm;
+extern const file_hint_t file_hint_rns;
+extern const file_hint_t file_hint_rpm;
+extern const file_hint_t file_hint_sib;
+extern const file_hint_t file_hint_sit;
+extern const file_hint_t file_hint_skp;
+extern const file_hint_t file_hint_sp3;
+extern const file_hint_t file_hint_spe;
+extern const file_hint_t file_hint_spf;
+extern const file_hint_t file_hint_spss;
+extern const file_hint_t file_hint_sqlite;
+extern const file_hint_t file_hint_sqm;
+extern const file_hint_t file_hint_stl;
+extern const file_hint_t file_hint_stuffit;
+extern const file_hint_t file_hint_swf;
+extern const file_hint_t file_hint_tar;
+extern const file_hint_t file_hint_tax;
+extern const file_hint_t file_hint_tib;
+extern const file_hint_t file_hint_tiff;
+extern const file_hint_t file_hint_tph;
+extern const file_hint_t file_hint_txt;
+extern const file_hint_t file_hint_veg;
+extern const file_hint_t file_hint_vmdk;
+extern const file_hint_t file_hint_wks;
+extern const file_hint_t file_hint_wmf;
+extern const file_hint_t file_hint_wnk;
+extern const file_hint_t file_hint_wpd;
+extern const file_hint_t file_hint_wv;
+extern const file_hint_t file_hint_x3f;
+extern const file_hint_t file_hint_xcf;
+extern const file_hint_t file_hint_xm;
+extern const file_hint_t file_hint_xsv;
+extern const file_hint_t file_hint_zip;
+
+file_enable_t list_file_enable[]=
+{
+ { .enable=0, .file_hint=&file_hint_7z },
+ { .enable=0, .file_hint=&file_hint_a },
+ { .enable=0, .file_hint=&file_hint_abcdp},
+ { .enable=0, .file_hint=&file_hint_accdb},
+ { .enable=0, .file_hint=&file_hint_ace },
+ { .enable=0, .file_hint=&file_hint_addressbook},
+ { .enable=0, .file_hint=&file_hint_ahn },
+ { .enable=0, .file_hint=&file_hint_aif },
+ { .enable=0, .file_hint=&file_hint_all },
+ { .enable=0, .file_hint=&file_hint_als },
+ { .enable=0, .file_hint=&file_hint_amd },
+ { .enable=0, .file_hint=&file_hint_amr },
+ { .enable=0, .file_hint=&file_hint_ape },
+ { .enable=0, .file_hint=&file_hint_arj },
+ { .enable=0, .file_hint=&file_hint_asf },
+ { .enable=0, .file_hint=&file_hint_asm },
+ { .enable=0, .file_hint=&file_hint_atd },
+ { .enable=0, .file_hint=&file_hint_au },
+ { .enable=0, .file_hint=&file_hint_bkf },
+ { .enable=0, .file_hint=&file_hint_blend },
+ { .enable=0, .file_hint=&file_hint_bmp },
+ { .enable=0, .file_hint=&file_hint_bz2 },
+ { .enable=0, .file_hint=&file_hint_cab },
+ { .enable=0, .file_hint=&file_hint_cam },
+ { .enable=0, .file_hint=&file_hint_chm },
+ { .enable=0, .file_hint=&file_hint_cm },
+ { .enable=0, .file_hint=&file_hint_compress },
+ { .enable=0, .file_hint=&file_hint_crw },
+ { .enable=0, .file_hint=&file_hint_ctg },
+ { .enable=0, .file_hint=&file_hint_cwk },
+ { .enable=0, .file_hint=&file_hint_dat },
+ { .enable=0, .file_hint=&file_hint_dbf },
+ { .enable=0, .file_hint=&file_hint_dim },
+ { .enable=0, .file_hint=&file_hint_dir },
+ { .enable=0, .file_hint=&file_hint_djv },
+ { .enable=0, .file_hint=&file_hint_drw },
+ { .enable=0, .file_hint=&file_hint_doc },
+ { .enable=0, .file_hint=&file_hint_dpx },
+ { .enable=0, .file_hint=&file_hint_ds2 },
+ { .enable=0, .file_hint=&file_hint_dsc },
+ { .enable=0, .file_hint=&file_hint_dss },
+ { .enable=0, .file_hint=&file_hint_dta },
+ { .enable=0, .file_hint=&file_hint_dump },
+ { .enable=0, .file_hint=&file_hint_dv },
+ { .enable=0, .file_hint=&file_hint_dwg },
+ { .enable=0, .file_hint=&file_hint_elf },
+ { .enable=0, .file_hint=&file_hint_emf },
+ { .enable=0, .file_hint=&file_hint_evt },
+ { .enable=0, .file_hint=&file_hint_exe },
+ { .enable=0, .file_hint=&file_hint_ext2_sb },
+ { .enable=0, .file_hint=&file_hint_fbk },
+ { .enable=0, .file_hint=&file_hint_fcp },
+ { .enable=0, .file_hint=&file_hint_fcs },
+ { .enable=0, .file_hint=&file_hint_fdb },
+ { .enable=0, .file_hint=&file_hint_fh10 },
+ { .enable=0, .file_hint=&file_hint_fh5 },
+ { .enable=0, .file_hint=&file_hint_fits },
+ { .enable=0, .file_hint=&file_hint_flac },
+ { .enable=0, .file_hint=&file_hint_flv },
+ { .enable=0, .file_hint=&file_hint_fob },
+ { .enable=0, .file_hint=&file_hint_frm },
+ { .enable=0, .file_hint=&file_hint_fs },
+ { .enable=0, .file_hint=&file_hint_gho },
+ { .enable=0, .file_hint=&file_hint_gif },
+ { .enable=0, .file_hint=&file_hint_gpg },
+ { .enable=0, .file_hint=&file_hint_gz },
+ { .enable=0, .file_hint=&file_hint_ifo },
+ { .enable=0, .file_hint=&file_hint_imb },
+ { .enable=0, .file_hint=&file_hint_indd },
+ { .enable=0, .file_hint=&file_hint_iso },
+ { .enable=0, .file_hint=&file_hint_itunes },
+ { .enable=0, .file_hint=&file_hint_jpg },
+ { .enable=0, .file_hint=&file_hint_kdb },
+ { .enable=0, .file_hint=&file_hint_logic},
+ { .enable=0, .file_hint=&file_hint_lnk },
+ { .enable=0, .file_hint=&file_hint_m2ts },
+ { .enable=0, .file_hint=&file_hint_max },
+ { .enable=0, .file_hint=&file_hint_mb },
+ { .enable=0, .file_hint=&file_hint_mcd },
+ { .enable=0, .file_hint=&file_hint_mdb },
+ { .enable=0, .file_hint=&file_hint_mdf },
+ { .enable=0, .file_hint=&file_hint_mfa },
+ { .enable=0, .file_hint=&file_hint_mfg },
+ { .enable=0, .file_hint=&file_hint_mid },
+ { .enable=0, .file_hint=&file_hint_mkv },
+ { .enable=0, .file_hint=&file_hint_mov },
+ { .enable=0, .file_hint=&file_hint_mp3 },
+ { .enable=0, .file_hint=&file_hint_mpg },
+ { .enable=0, .file_hint=&file_hint_mrw },
+ { .enable=0, .file_hint=&file_hint_mus },
+ { .enable=0, .file_hint=&file_hint_mysql },
+ { .enable=0, .file_hint=&file_hint_njx },
+ { .enable=0, .file_hint=&file_hint_ogg },
+ { .enable=0, .file_hint=&file_hint_one },
+ { .enable=0, .file_hint=&file_hint_orf },
+ { .enable=0, .file_hint=&file_hint_paf },
+ { .enable=0, .file_hint=&file_hint_pap },
+ { .enable=0, .file_hint=&file_hint_pcap },
+ { .enable=0, .file_hint=&file_hint_pct },
+ { .enable=0, .file_hint=&file_hint_pcx },
+ { .enable=0, .file_hint=&file_hint_pdf },
+ { .enable=0, .file_hint=&file_hint_pfx },
+ { .enable=0, .file_hint=&file_hint_png },
+ { .enable=0, .file_hint=&file_hint_prc },
+ { .enable=0, .file_hint=&file_hint_prt },
+ { .enable=0, .file_hint=&file_hint_ps },
+ { .enable=0, .file_hint=&file_hint_psd },
+ { .enable=0, .file_hint=&file_hint_psp },
+ { .enable=0, .file_hint=&file_hint_pst },
+ { .enable=0, .file_hint=&file_hint_ptb },
+ { .enable=0, .file_hint=&file_hint_qbb },
+ { .enable=0, .file_hint=&file_hint_qdf },
+ { .enable=0, .file_hint=&file_hint_qxd },
+ { .enable=0, .file_hint=&file_hint_ra },
+ { .enable=0, .file_hint=&file_hint_raf },
+ { .enable=0, .file_hint=&file_hint_rar },
+ { .enable=0, .file_hint=&file_hint_raw },
+ { .enable=0, .file_hint=&file_hint_rdc },
+ { .enable=0, .file_hint=&file_hint_reg },
+ { .enable=0, .file_hint=&file_hint_res },
+ { .enable=0, .file_hint=&file_hint_riff },
+ { .enable=0, .file_hint=&file_hint_rm },
+ { .enable=0, .file_hint=&file_hint_rns },
+ { .enable=0, .file_hint=&file_hint_rpm },
+ { .enable=0, .file_hint=&file_hint_sib },
+ { .enable=0, .file_hint=&file_hint_sit },
+ { .enable=0, .file_hint=&file_hint_skp },
+ { .enable=0, .file_hint=&file_hint_sp3 },
+ { .enable=0, .file_hint=&file_hint_spe },
+ { .enable=0, .file_hint=&file_hint_spf },
+ { .enable=0, .file_hint=&file_hint_spss },
+ { .enable=0, .file_hint=&file_hint_sqlite },
+ { .enable=0, .file_hint=&file_hint_sqm },
+ { .enable=0, .file_hint=&file_hint_stl },
+ { .enable=0, .file_hint=&file_hint_stuffit },
+ { .enable=0, .file_hint=&file_hint_swf },
+ { .enable=0, .file_hint=&file_hint_tar },
+ { .enable=0, .file_hint=&file_hint_tax },
+ { .enable=0, .file_hint=&file_hint_tib },
+ { .enable=0, .file_hint=&file_hint_tiff },
+ { .enable=0, .file_hint=&file_hint_tph },
+ { .enable=0, .file_hint=&file_hint_fasttxt },
+ { .enable=0, .file_hint=&file_hint_txt },
+ { .enable=0, .file_hint=&file_hint_vmdk },
+ { .enable=0, .file_hint=&file_hint_veg },
+ { .enable=0, .file_hint=&file_hint_wks },
+ { .enable=0, .file_hint=&file_hint_wmf },
+ { .enable=0, .file_hint=&file_hint_wnk },
+ { .enable=0, .file_hint=&file_hint_wpd },
+ { .enable=0, .file_hint=&file_hint_wv },
+ { .enable=0, .file_hint=&file_hint_x3f },
+ { .enable=0, .file_hint=&file_hint_xcf },
+ { .enable=0, .file_hint=&file_hint_xm },
+ { .enable=0, .file_hint=&file_hint_xsv },
+ { .enable=0, .file_hint=&file_hint_zip },
+ { .enable=0, .file_hint=NULL }
+};
+
diff --git a/src/filegen.c b/src/filegen.c
index 19122a2..4dfd38d 100644
--- a/src/filegen.c
+++ b/src/filegen.c
@@ -30,6 +30,7 @@
#include <string.h>
#endif
#include <stdio.h>
+#include <ctype.h>
#include "types.h"
#include "common.h"
#include "filegen.h"
@@ -181,3 +182,117 @@ void file_allow_nl(file_recovery_t *file_recovery, const unsigned int nl_mode)
file_recovery->file_size++;
}
+void file_search_footer(file_recovery_t *file_recovery, const unsigned char*footer, const unsigned int footer_length)
+{
+ const unsigned int read_size=4096;
+ unsigned char*buffer;
+ int64_t file_size;
+ if(footer_length==0)
+ return ;
+ buffer=(unsigned char*)MALLOC(read_size+footer_length-1);
+ file_size=file_recovery->file_size;
+ memset(buffer+read_size,0,footer_length-1);
+ do
+ {
+ int i;
+ int taille;
+ if(file_size%read_size!=0)
+ file_size=file_size-(file_size%read_size);
+ else
+ file_size-=read_size;
+ if(fseek(file_recovery->handle,file_size,SEEK_SET)<0)
+ return;
+ taille=fread(buffer,1,read_size,file_recovery->handle);
+ for(i=taille-1;i>=0;i--)
+ {
+ if(buffer[i]==footer[0] && memcmp(buffer+i,footer,footer_length)==0)
+ {
+ file_recovery->file_size=file_size+i+footer_length;
+ free(buffer);
+ return;
+ }
+ }
+ memcpy(buffer+read_size,buffer,footer_length-1);
+ } while(file_size>0);
+ file_recovery->file_size=0;
+ free(buffer);
+}
+
+void file_search_lc_footer(file_recovery_t *file_recovery, const unsigned char*footer, const unsigned int footer_length)
+{
+ const unsigned int read_size=4096;
+ unsigned char*buffer;
+ int64_t file_size;
+ if(footer_length==0)
+ return ;
+ buffer=(unsigned char*)MALLOC(read_size+footer_length-1);
+ file_size=file_recovery->file_size;
+ memset(buffer+read_size,0,footer_length-1);
+ do
+ {
+ int i;
+ int taille;
+ if(file_size%read_size!=0)
+ file_size=file_size-(file_size%read_size);
+ else
+ file_size-=read_size;
+ if(fseek(file_recovery->handle,file_size,SEEK_SET)<0)
+ return;
+ taille=fread(buffer,1,read_size,file_recovery->handle);
+ for(i=0;i<taille;i++)
+ buffer[i]=tolower(buffer[i]);
+ for(i=taille-1;i>=0;i--)
+ {
+ if(buffer[i]==footer[0] && memcmp(buffer+i,footer,footer_length)==0)
+ {
+ file_recovery->file_size=file_size+i+footer_length;
+ free(buffer);
+ return;
+ }
+ }
+ memcpy(buffer+read_size,buffer,footer_length-1);
+ } while(file_size>0);
+ file_recovery->file_size=0;
+ free(buffer);
+}
+
+int data_check_size(const unsigned char *buffer, const unsigned int buffer_size, file_recovery_t *file_recovery)
+{
+ if(file_recovery->file_size>=file_recovery->calculated_file_size)
+ {
+ file_recovery->file_size=file_recovery->calculated_file_size;
+ return 2;
+ }
+ return 1;
+}
+
+void file_check_size(file_recovery_t *file_recovery)
+{
+ if(file_recovery->file_size<file_recovery->calculated_file_size)
+ file_recovery->file_size=0;
+ else
+ file_recovery->file_size=file_recovery->calculated_file_size;
+}
+
+void reset_file_recovery(file_recovery_t *file_recovery)
+{
+ file_recovery->filename[0]='\0';
+ file_recovery->time=0;
+ file_recovery->file_stat=NULL;
+ file_recovery->handle=NULL;
+ file_recovery->file_size=0;
+ file_recovery->file_size_on_disk=0;
+ file_recovery->location.list.prev=&file_recovery->location.list;
+ file_recovery->location.list.next=&file_recovery->location.list;
+ file_recovery->location.start=0;
+ file_recovery->location.end=0;
+ file_recovery->location.data=0;
+ file_recovery->extension=NULL;
+ file_recovery->min_filesize=0;
+ file_recovery->calculated_file_size=0;
+ file_recovery->data_check=NULL;
+ file_recovery->file_check=NULL;
+ file_recovery->offset_error=0;
+}
+
+
diff --git a/src/fnctdsk.c b/src/fnctdsk.c
index 3ec5738..8d065b6 100644
--- a/src/fnctdsk.c
+++ b/src/fnctdsk.c
@@ -38,6 +38,7 @@
#include "testdisk.h"
#include "analyse.h"
#include "log.h"
+#include "log_part.h"
#include "guid_cpy.h"
static unsigned int get_geometry_from_list_part_aux(const disk_t *disk_car, const list_part_t *list_part, const int verbose);
diff --git a/src/geometry.c b/src/geometry.c
index 5017b61..b65debb 100644
--- a/src/geometry.c
+++ b/src/geometry.c
@@ -38,9 +38,9 @@
#else
#include <stdio.h>
#endif
-#include "chgtype.h"
#include "log.h"
#include "hdaccess.h"
+#include "geometry.h"
static inline void set_cylinders_from_size_up(disk_t *disk_car)
{
diff --git a/src/geometry.h b/src/geometry.h
new file mode 100644
index 0000000..00f8a55
--- /dev/null
+++ b/src/geometry.h
@@ -0,0 +1,30 @@
+/*
+
+ File: geometry.h
+
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void change_geometry(disk_t *disk_car, char **current_cmd);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/godmode.c b/src/godmode.c
index a3dbc98..6cfb005 100644
--- a/src/godmode.c
+++ b/src/godmode.c
@@ -23,6 +23,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#include <ctype.h> /* tolower */
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
@@ -48,6 +49,7 @@
#include "next.h"
#include "tpartwr.h"
#include "log.h"
+#include "log_part.h"
#include "fat32.h"
#include "tntfs.h"
#include "thfs.h"
@@ -711,7 +713,9 @@ static list_part_t *search_part(disk_t *disk_car, const list_part_t *list_part_o
aff_part_buffer(AFF_PART_BASE, disk_car,partition);
if(interface)
{
+#ifdef HAVE_NCURSES
screen_buffer_to_interface();
+#endif
}
if(disk_car->arch->is_part_known(partition)!=0 &&
partition->part_size>1 &&
@@ -1342,9 +1346,31 @@ int interface_recovery(disk_t *disk_car, const list_part_t * list_part_org, cons
switch(res_interface_write)
{
case 'W':
- if(disk_car->arch->write_part!=NULL)
+ if(disk_car->arch == &arch_mac)
{
- if(no_confirm!=0 || ask_confirmation("Write partition table, confirm ? (Y/N)")!=0)
+#ifdef HAVE_NCURSES
+ write_part_mac_warning_ncurses();
+#endif
+ }
+ else if(disk_car->arch == &arch_sun)
+ {
+#ifdef HAVE_NCURSES
+ not_implemented("write_part_sun");
+#endif
+ }
+ else if(disk_car->arch == &arch_xbox)
+ {
+#ifdef HAVE_NCURSES
+ not_implemented("write_part_xbox");
+#endif
+ }
+ else if(disk_car->arch->write_part!=NULL)
+ {
+ if(no_confirm!=0
+#ifdef HAVE_NCURSES
+ || ask_confirmation("Write partition table, confirm ? (Y/N)")!=0
+#endif
+ )
{
log_info("write!\n");
if(disk_car->arch->write_part(disk_car,list_part,RW,verbose,align))
diff --git a/src/hdcache.c b/src/hdcache.c
index 1d53807..2804559 100644
--- a/src/hdcache.c
+++ b/src/hdcache.c
@@ -22,6 +22,7 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
diff --git a/src/hdwin32.c b/src/hdwin32.c
index d79ae27..0adac21 100644
--- a/src/hdwin32.c
+++ b/src/hdwin32.c
@@ -24,6 +24,7 @@
#endif
#if defined(__CYGWIN__) || defined(__MINGW32__)
+#include <stdio.h>
#include "types.h"
#include "common.h"
#ifdef HAVE_STDLIB_H
diff --git a/src/hfsp.c b/src/hfsp.c
index 493ce5f..242cb3e 100644
--- a/src/hfsp.c
+++ b/src/hfsp.c
@@ -23,6 +23,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
diff --git a/src/hidden.c b/src/hidden.c
index 3bdceb7..260784a 100644
--- a/src/hidden.c
+++ b/src/hidden.c
@@ -22,79 +22,14 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
+
+#include <stdio.h>
#include "types.h"
#include "common.h"
-#include "intrf.h"
-#ifdef HAVE_NCURSES
-#include "intrfn.h"
-#else
-#include <stdio.h>
-#endif
#include "log.h"
#include "hidden.h"
-#define INTER_DISK_X 0
-#define INTER_DISK_Y 18
-
-#ifdef HAVE_NCURSES
-static int interface_check_hidden_ncurses(disk_t *disk)
-{
- static const struct MenuItem menuHidden[]=
- {
- { 'C', "Continue", "Continue even if there are hidden data"},
- { 0,NULL,NULL}
- };
- unsigned int menu=0;
- int car;
- int line=8;
- aff_copy(stdscr);
- wmove(stdscr,4,0);
- wprintw(stdscr,"%s\n",disk->description_short(disk));
- wmove(stdscr,6,0);
- wprintw(stdscr,"Hidden sectors are present.");
- if(disk->sector_size!=0)
- {
- wmove(stdscr,line++,0);
- wprintw(stdscr, "size %llu sectors\n", (long long unsigned)(disk->disk_real_size/disk->sector_size));
- }
- if(disk->user_max!=0)
- {
- wmove(stdscr,line++,0);
- wprintw(stdscr, "user_max %llu sectors\n", (long long unsigned)disk->user_max);
- }
- if(disk->native_max!=0)
- {
- wmove(stdscr,line++,0);
- wprintw(stdscr, "native_max %llu sectors\n", (long long unsigned)(disk->native_max+1));
- }
- if(disk->dco!=0)
- {
- wmove(stdscr,line++,0);
- wprintw(stdscr, "dco %llu sectors\n", (long long unsigned)(disk->dco+1));
- }
- if(disk->user_max < disk->native_max+1)
- {
- wmove(stdscr,line++,0);
- wprintw(stdscr, "Host Protected Area (HPA) present.\n");
- }
- if(disk->native_max < disk->dco)
- {
- wmove(stdscr,line,0);
- wprintw(stdscr, "Device Configuration Overlay (DCO) present.\n");
- }
- car= wmenuSelect_ext(stdscr, 23, INTER_DISK_Y, INTER_DISK_X, menuHidden, 10,
- "CQ", MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
- if(car=='c' || car=='C')
- return 0;
- return 1;
-}
-#endif
-
-int interface_check_hidden(disk_t *disk, char **current_cmd)
+int is_hpa_or_dco(const disk_t *disk)
{
if(disk->user_max>0 && (disk->user_max < disk->native_max+1 || disk->native_max < disk->dco))
{
@@ -103,13 +38,7 @@ int interface_check_hidden(disk_t *disk, char **current_cmd)
if(disk->native_max < disk->dco)
log_warning("%s: Device Configuration Overlay (DCO) present.\n", disk->device);
log_flush();
- if(*current_cmd!=NULL)
- return 0;
-#ifdef HAVE_NCURSES
- return interface_check_hidden_ncurses(disk);
-#else
- return 0;
-#endif
+ return 1;
}
return 0;
}
diff --git a/src/hidden.h b/src/hidden.h
index 97ddc11..fe6e9f5 100644
--- a/src/hidden.h
+++ b/src/hidden.h
@@ -19,5 +19,12 @@
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
-int interface_check_hidden(disk_t *disk, char **current_cmd);
+int is_hpa_or_dco(const disk_t *disk);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/hiddenn.c b/src/hiddenn.c
new file mode 100644
index 0000000..6a3e930
--- /dev/null
+++ b/src/hiddenn.c
@@ -0,0 +1,87 @@
+/*
+
+ File: hiddenn.c
+
+ Copyright (C) 2008-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef HAVE_NCURSES
+
+#include "types.h"
+#include "common.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "hiddenn.h"
+
+#define INTER_DISK_X 0
+#define INTER_DISK_Y 18
+
+int interface_check_hidden_ncurses(disk_t *disk)
+{
+ static const struct MenuItem menuHidden[]=
+ {
+ { 'C', "Continue", "Continue even if there are hidden data"},
+ { 0,NULL,NULL}
+ };
+ unsigned int menu=0;
+ int car;
+ int line=8;
+ aff_copy(stdscr);
+ wmove(stdscr,4,0);
+ wprintw(stdscr,"%s\n",disk->description_short(disk));
+ wmove(stdscr,6,0);
+ wprintw(stdscr,"Hidden sectors are present.");
+ if(disk->sector_size!=0)
+ {
+ wmove(stdscr,line++,0);
+ wprintw(stdscr, "size %llu sectors\n", (long long unsigned)(disk->disk_real_size/disk->sector_size));
+ }
+ if(disk->user_max!=0)
+ {
+ wmove(stdscr,line++,0);
+ wprintw(stdscr, "user_max %llu sectors\n", (long long unsigned)disk->user_max);
+ }
+ if(disk->native_max!=0)
+ {
+ wmove(stdscr,line++,0);
+ wprintw(stdscr, "native_max %llu sectors\n", (long long unsigned)(disk->native_max+1));
+ }
+ if(disk->dco!=0)
+ {
+ wmove(stdscr,line++,0);
+ wprintw(stdscr, "dco %llu sectors\n", (long long unsigned)(disk->dco+1));
+ }
+ if(disk->user_max < disk->native_max+1)
+ {
+ wmove(stdscr,line++,0);
+ wprintw(stdscr, "Host Protected Area (HPA) present.\n");
+ }
+ if(disk->native_max < disk->dco)
+ {
+ wmove(stdscr,line,0);
+ wprintw(stdscr, "Device Configuration Overlay (DCO) present.\n");
+ }
+ car= wmenuSelect_ext(stdscr, 23, INTER_DISK_Y, INTER_DISK_X, menuHidden, 10,
+ "CQ", MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
+ if(car=='c' || car=='C')
+ return 0;
+ return 1;
+}
+#endif
diff --git a/src/hiddenn.h b/src/hiddenn.h
new file mode 100644
index 0000000..23f8316
--- /dev/null
+++ b/src/hiddenn.h
@@ -0,0 +1,30 @@
+/*
+
+ File: hiddenn.h
+
+ Copyright (C) 2008-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int interface_check_hidden_ncurses(disk_t *disk);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/intrf.c b/src/intrf.c
index 06b6983..d951235 100644
--- a/src/intrf.c
+++ b/src/intrf.c
@@ -2,7 +2,7 @@
File: intrf.c
- Copyright (C) 1998-2008 Christophe GRENIER <grenier@cgsecurity.org>
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
This software is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,6 +23,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#include <stdarg.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
@@ -60,34 +61,13 @@
#include "common.h"
#include "lang.h"
#include "intrf.h"
-#ifdef HAVE_NCURSES
-#include "intrfn.h"
-#else
-#include <stdio.h>
-#endif
#include "fnctdsk.h"
#include "list.h"
#include "dir.h"
#include "log.h"
-#include "hdaccess.h"
-/* Use COLS (actual number of columns) or COLUMNS (number of columns the program has been designed for) ? */
-
-#define GS_DEFAULT -1
-#define GS_key_ESCAPE -2
-extern const arch_fnct_t arch_i386;
-extern const arch_fnct_t arch_gpt;
-extern const arch_fnct_t arch_mac;
-extern const arch_fnct_t arch_none;
-extern const arch_fnct_t arch_sun;
-extern const arch_fnct_t arch_xbox;
-extern const char *monstr[];
-
-static char intr_buffer_screen[MAX_LINES][LINE_LENGTH+1];
-static int intr_nbr_line=0;
-#ifdef HAVE_NCURSES
-static void set_parent_directory(char *dst_directory);
-#endif
+char intr_buffer_screen[MAX_LINES][LINE_LENGTH+1];
+int intr_nbr_line=0;
int screen_buffer_add(const char *_format, ...)
{
@@ -124,26 +104,6 @@ int screen_buffer_add(const char *_format, ...)
return 0;
}
-void screen_buffer_to_interface()
-{
-#ifdef HAVE_NCURSES
- {
- int i;
- int pos=intr_nbr_line-DUMP_MAX_LINES<0?0:intr_nbr_line-DUMP_MAX_LINES;
- if(intr_nbr_line<MAX_LINES && intr_buffer_screen[intr_nbr_line][0]!='\0')
- intr_nbr_line++;
- /* curses interface */
- for (i=pos; i<intr_nbr_line && i<MAX_LINES && (i-pos)<DUMP_MAX_LINES; i++)
- {
- wmove(stdscr,DUMP_Y+1+i-pos,DUMP_X);
- wclrtoeol(stdscr);
- wprintw(stdscr,"%s",intr_buffer_screen[i]);
- }
- wrefresh(stdscr);
- }
-#endif
-}
-
void screen_buffer_to_stdout()
{
int i;
@@ -245,43 +205,12 @@ const char *aff_part_aux(const unsigned int newline, const disk_t *disk_car, con
}
#define PATH_SEP '/'
-#define SPATH_SEP "/"
#if defined(__CYGWIN__)
/* /cygdrive/c/ => */
#define PATH_DRIVE_LENGTH 9
#endif
-#ifdef HAVE_NCURSES
-static void set_parent_directory(char *dst_directory)
-{
- int i;
- int last_sep=-1;
- for(i=0;dst_directory[i]!='\0';i++)
- if(dst_directory[i]==PATH_SEP)
- last_sep=i;
-#ifdef __CYGWIN__
- /* /cygdrive */
- if(last_sep>PATH_DRIVE_LENGTH)
- dst_directory[last_sep]='\0';
- else
- dst_directory[PATH_DRIVE_LENGTH]='\0';
-#elif defined(DJGPP) || defined(__OS2__)
- if(last_sep > 2 )
- dst_directory[last_sep]='\0'; /* subdirectory */
- else if(last_sep == 2 && dst_directory[3]!='\0')
- dst_directory[3]='\0'; /* root directory */
- else
- dst_directory[0]='\0'; /* drive list */
-#else
- if(last_sep>1)
- dst_directory[last_sep]='\0';
- else
- dst_directory[1]='\0';
-#endif
-}
-#endif
-
-static inline char *td_getcwd(char *buf, unsigned long size)
+char *td_getcwd(char *buf, unsigned long size)
{
/* buf must non-NULL*/
#ifdef HAVE_GETCWD
@@ -300,1645 +229,6 @@ char *get_default_location(void)
return strdup(dst_directory);
}
-#ifdef HAVE_NCURSES
-#define INTER_DIR (LINES-25+16)
-static int aff_txt(int line, WINDOW *window, const char *_format, ...) __attribute__ ((format (printf, 3, 4)));
-static int vaff_txt(int line, WINDOW *window, const char *_format, va_list ap) __attribute__((format(printf, 3, 0)));
-static int wmenuUpdate(WINDOW *window, const int yinfo, int y, int x, const struct MenuItem *menuItems, const unsigned int itemLength, const char *available, const int menuType, unsigned int current);
-static void dir_aff_entry(WINDOW *window, file_info_t *file_info);
-static int wgetch_nodelay(WINDOW *window);
-
-int get_string(char *str, int len, char *def)
-{
- int c;
- int i = 0;
- int x, y;
- int use_def = FALSE;
- curs_set(1);
- getyx(stdscr, y, x);
- wclrtoeol(stdscr);
- str[0] = 0;
-
- if (def != NULL) {
- mvwaddstr(stdscr,y, x, def);
- wmove(stdscr,y, x);
- use_def = TRUE;
- }
-
- wrefresh(stdscr);
- while ((c = wgetch(stdscr)) != '\n' && c != key_CR
-#ifdef PADENTER
- && c!= PADENTER
-#endif
- )
- {
- switch (c) {
- /* escape is generated by enter from keypad */
- /*
- case key_ESC:
- wmove(stdscr,y, x);
- wclrtoeol(stdscr);
- curs_set(0);
- wrefresh(stdscr);
- return GS_key_ESCAPE;
- */
- case KEY_DC:
- case KEY_BACKSPACE:
- if (i > 0) {
- str[--i] = 0;
- mvaddch(y, x+i, ' ');
- wmove(stdscr,y, x+i);
- } else if (use_def) {
- wclrtoeol(stdscr);
- use_def = FALSE;
- }
- break;
- default:
- if (i < len && isprint(c)) {
- mvaddch(y, x+i, c);
- if (use_def) {
- wclrtoeol(stdscr);
- use_def = FALSE;
- }
- str[i++] = c;
- str[i] = 0;
- }
- }
- wrefresh(stdscr);
- }
- curs_set(0);
- wrefresh(stdscr);
- if (use_def)
- return GS_DEFAULT;
- else
- return i;
-}
-
-static int wgetch_nodelay(WINDOW *window)
-{
- int res;
- nodelay(window,TRUE);
- res=wgetch(window);
- nodelay(window,FALSE);
- return res;
-}
-
-/*
- * Actual function which prints the button bar and highlights the active button
- * Should not be called directly. Call function menuSelect instead.
- */
-
-static int wmenuUpdate(WINDOW *window, const int yinfo, int y, int x, const struct MenuItem *menuItems, const unsigned int itemLength, const char *available, const int menuType, unsigned int current)
-{
- unsigned int i, lmargin = x, ymargin = y;
- unsigned int lenNameMax=0;
- for( i = 0; menuItems[i].key!=0; i++ )
- if(strchr(available, menuItems[i].key)!=NULL )
- {
- unsigned int lenName = strlen( menuItems[i].name );
- if(lenNameMax<lenName && lenName < itemLength)
- lenNameMax=lenName;
- }
- /* Print available buttons */
- for( i = 0; menuItems[i].key!=0; i++ )
- {
- char buff[80];
- unsigned int lenName;
- const char *mi;
- wmove(window, y, x );
- wclrtoeol(window);
-
- /* Search next available button */
- while( menuItems[i].key!=0 && strchr(available, menuItems[i].key)==NULL )
- {
- i++;
- }
- if( menuItems[i].key==0 ) break; /* No more menu items */
-
- /* If selected item is not available and we have bypassed it,
- make current item selected */
- if( current < i && menuItems[current].key < 0 ) current = i;
-
- mi = menuItems[i].name;
- lenName = strlen( mi );
- if(lenName>=sizeof(buff))
- {
- log_critical("\nBUG: %s\n",mi);
- }
- if(lenName >= itemLength)
- {
- if( menuType & MENU_BUTTON )
- snprintf(buff, sizeof(buff),"[%s]",mi);
- else
- snprintf(buff, sizeof(buff),"%s",mi);
- }
- else
- {
- if( menuType & MENU_BUTTON )
- {
- if(menuType & MENU_VERT)
- snprintf( buff, sizeof(buff),"[%*s%-*s]", (itemLength - lenNameMax) / 2, "",
- (itemLength - lenNameMax + 1) / 2 + lenNameMax, mi );
- else
- snprintf( buff, sizeof(buff),"[%*s%-*s]", (itemLength - lenName) / 2, "",
- (itemLength - lenName + 1) / 2 + lenName, mi );
- }
- else
- snprintf( buff, sizeof(buff),"%*s%-*s", (itemLength - lenName) / 2, "",
- (itemLength - lenName + 1) / 2 + lenName, mi );
- }
- /* If current item is selected, highlight it */
- if( current == i )
- {
- wattrset(window, A_REVERSE);
- }
-
- /* Print item */
- mvwaddstr(window, y, x, buff );
-
- /* Lowlight after selected item */
- if( current == i )
- {
- wattroff(window, A_REVERSE);
- }
- if(menuType & MENU_VERT_WARN)
- mvwaddstr(window, y, x+itemLength+4, menuItems[i].desc);
-
- /* Calculate position for the next item */
- if( menuType & MENU_VERT )
- {
- y += 1;
- if( y >= yinfo - 1)
- {
- y = ymargin;
- x += (lenName < itemLength?itemLength:lenName) + MENU_SPACING;
- if( menuType & MENU_BUTTON ) x += 2;
- }
- }
- else
- {
- x += (lenName < itemLength?itemLength:lenName) + MENU_SPACING;
- if( menuType & MENU_BUTTON ) x += 2;
- if( x > COLUMNS - lmargin - 12 )
- {
- x = lmargin;
- y ++ ;
- }
- }
- }
- /* Print the description of selected item */
- if(!(menuType & MENU_VERT_WARN))
- {
- const char *mcd = menuItems[current].desc;
- mvwaddstr(window, yinfo, (COLUMNS - strlen( mcd )) / 2, mcd );
- }
- return y;
-}
-
-/* This function takes a list of menu items, lets the user choose one *
- * and returns the value keyboard shortcut of the selected menu item */
-
-int wmenuSelect(WINDOW *window, int yinfo, int y, int x, const struct MenuItem *menuItems, const unsigned int itemLength, const char *available, int menuType, unsigned int menuDefault)
-{
- unsigned int current=menuDefault;
- return wmenuSelect_ext(window, yinfo, y, x, menuItems, itemLength, available, menuType, &current, NULL);
-}
-
-int wmenuSelect_ext(WINDOW *window, const int yinfo, int y, int x, const struct MenuItem *menuItems, const unsigned int itemLength, const char *available, int menuType, unsigned int *current, int *real_key)
-{
- int i, ylast = y, key = 0;
- /*
- if( ( menuType & ( MENU_HORIZ | MENU_VERT ) )==0 )
- {
- wprintw(window,"Menu without direction. Defaulting horizontal.");
- menuType |= MENU_HORIZ;
- }
- */
- /* Warning: current may be out of bound, not checked */
- /* Make sure that the current is one of the available items */
- while(strchr(available, menuItems[*current].key)==NULL)
- {
- (*current)++ ;
- if( menuItems[*current].key==0 )
- {
- *current = 0;
- }
- }
- /* Repeat until allowable choice has been made */
- while( key==0 )
- {
- /* Display the menu */
- ylast = wmenuUpdate( window, yinfo, y, x, menuItems, itemLength, available,
- menuType, *current );
- wrefresh(window);
- /* Don't put wgetch after the following wclrtoeol */
- key = wgetch(window);
- if(real_key!=NULL)
- *real_key=key;
-
- /* Clear out all prompts and such */
- for( i = y; i < ylast; i ++ )
- {
- wmove(window, i, x );
- wclrtoeol(window);
- }
- wmove(window, yinfo, 0 );
- wclrtoeol(window);
- if(strchr(available, key)==NULL)
- {
- if(key=='2')
- key=KEY_DOWN;
- else if(key=='4')
- key=KEY_LEFT;
- else if(key=='5')
- key=KEY_ENTER;
- else if(key=='6')
- key=KEY_RIGHT;
- else if(key=='8')
- key=KEY_UP;
- }
- /* Cursor keys */
- switch(key)
- {
- case KEY_UP:
- if( (menuType & MENU_VERT)!=0 )
- {
- do {
- if( (*current)-- == 0 )
- {
- while( menuItems[(*current)+1].key ) (*current) ++ ;
- }
- } while( strchr( available, menuItems[*current].key )==NULL );
- key = 0;
- }
- break;
- case KEY_DOWN:
- if( (menuType & MENU_VERT)!=0 )
- {
- do {
- (*current) ++ ;
- if( menuItems[*current].key==0 ) *current = 0 ;
- } while( strchr( available, menuItems[*current].key )==NULL );
- key = 0;
- }
- break;
- case KEY_RIGHT:
- if( (menuType & MENU_HORIZ)!=0 )
- {
- do {
- (*current) ++ ;
- if( menuItems[*current].key==0 )
- {
- *current = 0 ;
- }
- } while( strchr( available, menuItems[*current].key )==NULL );
- key = 0;
- }
- break;
- case KEY_LEFT:
- if( (menuType & MENU_HORIZ) !=0)
- {
- do {
- if( (*current)-- == 0 )
- {
- while( menuItems[(*current) + 1].key ) (*current) ++ ;
- }
- } while( strchr( available, menuItems[*current].key )==NULL );
- key = 0;
- }
- break;
- }
- /* Enter equals to the keyboard shortcut of current menu item */
- if((key==13) || (key==10) || (key==KEY_ENTER) ||
- (((menuType & MENU_VERT) != 0) && ((menuType & MENU_VERT_ARROW2VALID) != 0)
- && (key==KEY_RIGHT || key==KEY_LEFT)))
- key = menuItems[*current].key;
-#ifdef PADENTER
- if(key==PADENTER)
- key = menuItems[*current].key;
-#endif
-
- /* Is pressed key among acceptable ones */
- if( key!=0 && (strchr(available, toupper(key))!=NULL || strchr(available, key)!=NULL))
- break;
- /* Should all keys to be accepted? */
- if( key && (menuType & MENU_ACCEPT_OTHERS)!=0 ) break;
- /* The key has not been accepted so far -> let's reject it */
-#ifdef DEBUG
- if( key )
- {
- wmove(window,5,0);
- wprintw(window,"key %03X",key);
- putchar( BELL );
- }
-#endif
- key = 0;
- }
- /* Clear out prompts and such */
- for( i = y; i <= ylast; i ++ )
- {
- wmove(window, i, x );
- wclrtoeol(window);
- }
- wmove(window, yinfo, 0 );
- wclrtoeol(window);
- return key;
-}
-
-/* Function menuSelect takes way too many parameters *
- * Luckily, most of time we can do with this function */
-
-int wmenuSimple(WINDOW *window,const struct MenuItem *menuItems, unsigned int menuDefault)
-{
- unsigned int i, j, itemLength = 0;
- char available[MENU_MAX_ITEMS];
-
- for(i = 0; menuItems[i].key; i++)
- {
- j = strlen(menuItems[i].name);
- if( j > itemLength ) itemLength = j;
- available[i] = menuItems[i].key;
- }
- available[i] = 0;
- return wmenuSelect(window, 23, 18, 0, menuItems, itemLength, available, MENU_HORIZ | MENU_BUTTON, menuDefault);
-}
-
-/* End of command menu support code */
-
-unsigned long long int ask_number(const unsigned long long int val_cur, const unsigned long long int val_min, const unsigned long long int val_max, const char * _format, ...)
-{
- char res[200];
- char res2[200];
- char response[LINE_LENGTH];
- char def[LINE_LENGTH];
- unsigned long int tmp_val;
- va_list ap;
- va_start(ap,_format);
- vsnprintf(res,sizeof(res),_format,ap);
- if(val_min!=val_max)
- snprintf(res2,sizeof(res2),"(%llu-%llu) :",val_min,val_max);
- else
- res2[0]='\0';
- va_end(ap);
- waddstr(stdscr, res);
- waddstr(stdscr, res2);
- sprintf(def, "%llu", val_cur);
- if (get_string(response, LINE_LENGTH, def) > 0)
- {
-#ifdef HAVE_ATOLL
- tmp_val = atoll(response);
-#else
- tmp_val = atol(response);
-#endif
- if (val_min==val_max || (tmp_val >= val_min && tmp_val <= val_max))
- return tmp_val;
- }
- return val_cur;
-}
-
-void dump_ncurses(const void *nom_dump, unsigned int lng)
-{
- WINDOW *window=newwin(0,0,0,0); /* full screen */
- keypad(window, TRUE); /* Need it to get arrow key */
- aff_copy(window);
- dump(window, nom_dump, lng);
- dump_log(nom_dump,lng);
- delwin(window);
- (void) clearok(stdscr, TRUE);
-#ifdef HAVE_TOUCHWIN
- touchwin(stdscr);
-#endif
-}
-
-void dump(WINDOW *window, const void *nom_dump,unsigned int lng)
-{
- unsigned int i,j;
- unsigned int nbr_line;
- unsigned char car;
- unsigned int pos=0;
- int done=0;
- unsigned int menu=2; /* default : quit */
- const char *options="PNQ";
- struct MenuItem menuDump[]=
- {
- { 'P', "Previous",""},
- { 'N', "Next","" },
- { 'Q',"Quit","Quit dump section"},
- { 0, NULL, NULL }
- };
- nbr_line=(lng+0x10-1)/0x10;
- if(nbr_line<=DUMP_MAX_LINES)
- {
- options="Q";
- }
- /* ncurses interface */
- mvwaddstr(window,DUMP_Y,DUMP_X,msg_DUMP_HEXA);
- /* On pourrait utiliser wscrl */
- do
- {
- for (i=pos; (i<nbr_line)&&((i-pos)<DUMP_MAX_LINES); i++)
- {
- wmove(window,DUMP_Y+i-pos,DUMP_X);
- wclrtoeol(window);
- wprintw(window,"%04X ",i*0x10);
- for(j=0; j< 0x10;j++)
- {
- if(i*0x10+j<lng)
- {
- car=*((const unsigned char*)nom_dump+i*0x10+j);
- wprintw(window,"%02x", car);
- }
- else
- wprintw(window," ");
- if(j%4==(4-1))
- wprintw(window," ");
- }
- wprintw(window," ");
- for(j=0; j< 0x10;j++)
- {
- if(i*0x10+j<lng)
- {
- car=*((const unsigned char*)nom_dump+i*0x10+j);
- if ((car<32)||(car >= 127))
- wprintw(window,".");
- else
- wprintw(window,"%c", car);
- }
- else
- wprintw(window," ");
- }
- }
- switch (wmenuSelect(window, INTER_DUMP_Y+1, INTER_DUMP_Y, INTER_DUMP_X, menuDump, 8, options, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu))
- {
- case 'p':
- case 'P':
- case KEY_UP:
- if(strchr(options,'N')!=NULL)
- {
- menu=0;
- if(pos>0)
- pos--;
- }
- break;
- case 'n':
- case 'N':
- case KEY_DOWN:
- if(strchr(options,'N')!=NULL)
- {
- menu=1;
- if(pos<nbr_line-DUMP_MAX_LINES)
- pos++;
- }
- break;
- case KEY_PPAGE:
- if(strchr(options,'N')!=NULL)
- {
- menu=0;
- if(pos>DUMP_MAX_LINES-1)
- pos-=DUMP_MAX_LINES-1;
- else
- pos=0;
- }
- break;
- case KEY_NPAGE:
- if(strchr(options,'N')!=NULL)
- {
- menu=1;
- if(pos<nbr_line-DUMP_MAX_LINES-(DUMP_MAX_LINES-1))
- pos+=DUMP_MAX_LINES-1;
- else
- pos=nbr_line-DUMP_MAX_LINES;
- }
- break;
- case key_ESC:
- case 'q':
- case 'Q':
- done = TRUE;
- break;
- }
- } while(done==FALSE);
-}
-
-void dump2(WINDOW *window, const void *dump_1, const void *dump_2, const unsigned int lng)
-{
- unsigned int i,j;
- unsigned int nbr_line;
- unsigned int pos=0;
- int done=0;
- unsigned int menu=2; /* default : quit */
- const char *options="PNQ";
- struct MenuItem menuDump[]=
- {
- { 'P', "Previous",""},
- { 'N', "Next","" },
- { 'Q',"Quit","Quit dump section"},
- { 0, NULL, NULL }
- };
- /* ncurses interface */
- nbr_line=(lng+0x08-1)/0x08;
- if(nbr_line<=DUMP_MAX_LINES)
- {
- options="Q";
- }
- do
- {
- for (i=pos; (i<nbr_line)&&((i-pos)<DUMP_MAX_LINES); i++)
- {
- wmove(window,DUMP_Y+i-pos,DUMP_X);
- wclrtoeol(window);
- wprintw(window,"%04X ",i*0x08);
- for(j=0; j<0x08;j++)
- {
- if(i*0x08+j<lng)
- {
- unsigned char car1=*((const unsigned char*)dump_1+i*0x08+j);
- unsigned char car2=*((const unsigned char*)dump_2+i*0x08+j);
- if(car1!=car2)
- wattrset(window, A_REVERSE);
- wprintw(window,"%02x", car1);
- if(car1!=car2)
- wattroff(window, A_REVERSE);
- }
- else
- wprintw(window," ");
- if(j%4==(4-1))
- wprintw(window," ");
- }
- wprintw(window," ");
- for(j=0; j<0x08;j++)
- {
- if(i*0x08+j<lng)
- {
- unsigned char car1=*((const unsigned char*)dump_1+i*0x08+j);
- unsigned char car2=*((const unsigned char*)dump_2+i*0x08+j);
- if(car1!=car2)
- wattrset(window, A_REVERSE);
- if ((car1<32)||(car1 >= 127))
- wprintw(window,".");
- else
- wprintw(window,"%c", car1);
- if(car1!=car2)
- wattroff(window, A_REVERSE);
- }
- else
- wprintw(window," ");
- }
- wprintw(window," ");
- for(j=0; j<0x08;j++)
- {
- if(i*0x08+j<lng)
- {
- unsigned char car1=*((const unsigned char*)dump_1+i*0x08+j);
- unsigned char car2=*((const unsigned char*)dump_2+i*0x08+j);
- if(car1!=car2)
- wattrset(window, A_REVERSE);
- wprintw(window,"%02x", car2);
- if(car1!=car2)
- wattroff(window, A_REVERSE);
- if(j%4==(4-1))
- wprintw(window," ");
- }
- else
- wprintw(window," ");
- }
- wprintw(window," ");
- for(j=0; j<0x08;j++)
- {
- if(i*0x08+j<lng)
- {
- unsigned char car1=*((const unsigned char*)dump_1+i*0x08+j);
- unsigned char car2=*((const unsigned char*)dump_2+i*0x08+j);
- if(car1!=car2)
- wattrset(window, A_REVERSE);
- if ((car2<32)||(car2 >= 127))
- wprintw(window,".");
- else
- wprintw(window,"%c", car2);
- if(car1!=car2)
- wattroff(window, A_REVERSE);
- }
- else
- wprintw(window," ");
- }
- }
- switch (wmenuSelect(window, INTER_DUMP_Y+1, INTER_DUMP_Y, INTER_DUMP_X, menuDump, 8, options, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu))
- {
- case 'p':
- case 'P':
- case KEY_UP:
- if(strchr(options,'N')!=NULL)
- {
- menu=0;
- if(pos>0)
- pos--;
- }
- break;
- case 'n':
- case 'N':
- case KEY_DOWN:
- if(strchr(options,'N')!=NULL)
- {
- menu=1;
- if(pos<nbr_line-DUMP_MAX_LINES)
- pos++;
- }
- break;
- case KEY_PPAGE:
- if(strchr(options,'N')!=NULL)
- {
- menu=0;
- if(pos>DUMP_MAX_LINES-1)
- pos-=DUMP_MAX_LINES-1;
- else
- pos=0;
- }
- break;
- case KEY_NPAGE:
- if(strchr(options,'N')!=NULL)
- {
- menu=1;
- if(pos<nbr_line-DUMP_MAX_LINES-(DUMP_MAX_LINES-1))
- pos+=DUMP_MAX_LINES-1;
- else
- pos=nbr_line-DUMP_MAX_LINES;
- }
- break;
- case key_ESC:
- case 'q':
- case 'Q':
- done = TRUE;
- break;
- }
- } while(done==FALSE);
-}
-
-int screen_buffer_display(WINDOW *window, const char *options_org, const struct MenuItem *menuItems)
-{
- unsigned int menu=0;
- return screen_buffer_display_ext(window,options_org,menuItems,&menu);
-}
-
-#define INTER_ANALYSE_X 0
-#define INTER_ANALYSE_Y 8
-#define INTER_ANALYSE_MENU_X 0
-#define INTER_ANALYSE_MENU_Y (LINES-2)
-#define INTER_MAX_LINES (INTER_ANALYSE_MENU_Y-INTER_ANALYSE_Y-2)
-int screen_buffer_display_ext(WINDOW *window, const char *options_org, const struct MenuItem *menuItems, unsigned int *menu)
-{
- int i;
- int first_line_to_display=0;
- int current_line=0;
- int done=0;
- char options[20];
- struct MenuItem menuDefault[]=
- {
- { 'P', "Previous",""},
- { 'N', "Next","" },
- { 'Q', "Quit","Quit this section"},
- { 0, NULL, NULL }
- };
- const unsigned int itemLength=8;
- /* FIXME itemLength */
- strncpy(options,"Q",sizeof(options));
- strncat(options,options_org,sizeof(options)-strlen(options));
- if(intr_buffer_screen[intr_nbr_line][0]!='\0')
- intr_nbr_line++;
- /* curses interface */
- do
- {
- int key;
- wmove(window, INTER_ANALYSE_Y-1, INTER_ANALYSE_X+4);
- wclrtoeol(window);
- if(first_line_to_display>0)
- wprintw(window, "Previous");
- if(intr_nbr_line>INTER_MAX_LINES && has_colors())
- {
- for (i=first_line_to_display; i<intr_nbr_line && (i-first_line_to_display)<INTER_MAX_LINES; i++)
- {
- wmove(window,INTER_ANALYSE_Y+i-first_line_to_display,INTER_ANALYSE_X);
- wclrtoeol(window);
- if(i==current_line)
- wattrset(window, A_REVERSE);
- wprintw(window,"%s",intr_buffer_screen[i]);
- if(i==current_line)
- wattroff(window, A_REVERSE);
- }
- }
- else
- {
- for (i=first_line_to_display; i<intr_nbr_line && (i-first_line_to_display)<INTER_MAX_LINES; i++)
- {
- wmove(window,INTER_ANALYSE_Y+i-first_line_to_display,INTER_ANALYSE_X);
- wclrtoeol(window);
- wprintw(window,"%s",intr_buffer_screen[i]);
- }
- }
- wmove(window, INTER_ANALYSE_Y+INTER_MAX_LINES, INTER_ANALYSE_X+4);
- wclrtoeol(window);
- if(i<intr_nbr_line)
- wprintw(window, "Next");
- key=wmenuSelect_ext(window, INTER_ANALYSE_MENU_Y+1,
- INTER_ANALYSE_MENU_Y, INTER_ANALYSE_MENU_X,
- (menuItems!=NULL?menuItems:menuDefault), itemLength, options,
- MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu,NULL);
- switch (key)
- {
- case key_ESC:
- case 'q':
- case 'Q':
- done = TRUE;
- break;
- case 'p':
- case 'P':
- case KEY_UP:
- if(current_line>0)
- current_line--;
- break;
- case 'n':
- case 'N':
- case KEY_DOWN:
- if(current_line<intr_nbr_line-1)
- current_line++;
- break;
- case KEY_PPAGE:
- if(current_line>INTER_MAX_LINES-1)
- current_line-=INTER_MAX_LINES-1;
- else
- current_line=0;
- break;
- case KEY_NPAGE:
- if(current_line+INTER_MAX_LINES-1 < intr_nbr_line-1)
- current_line+=INTER_MAX_LINES-1;
- else
- current_line=intr_nbr_line-1;
- break;
- default:
- if(strchr(options,toupper(key))!=NULL)
- return toupper(key);
- break;
- }
- if(current_line<first_line_to_display)
- first_line_to_display=current_line;
- if(current_line>=first_line_to_display+INTER_MAX_LINES)
- first_line_to_display=current_line-INTER_MAX_LINES+1;
- } while(done!=TRUE);
- return 0;
-}
-
-void aff_part(WINDOW *window,const unsigned int newline,const disk_t *disk_car,const partition_t *partition)
-{
- const char *msg;
- msg=aff_part_aux(newline, disk_car, partition);
- wprintw(window,"%s",msg);
-}
-
-void aff_LBA2CHS(const disk_t *disk_car, const unsigned long int pos_LBA)
-{
- unsigned long int tmp;
- unsigned long int cylinder, head, sector;
- tmp=disk_car->geom.sectors_per_head;
- sector=(pos_LBA%tmp)+1;
- tmp=pos_LBA/tmp;
- cylinder=tmp / disk_car->geom.heads_per_cylinder;
- head=tmp % disk_car->geom.heads_per_cylinder;
- wprintw(stdscr, "%lu/%lu/%lu", cylinder, head, sector);
-}
-
-int ask_YN(WINDOW *window)
-{
- char res;
- curs_set(1);
- wrefresh(window);
- do
- {
- res=toupper(wgetch(window));
- } while((res!=c_NO)&&(res!=c_YES));
- curs_set(0);
- wprintw(window,"%c\n",res);
- return (res==c_YES);
-}
-
-int ask_confirmation(const char*_format, ...)
-{
- va_list ap;
- int res;
- WINDOW *window=newwin(0,0,0,0); /* full screen */
- aff_copy(window);
- va_start(ap,_format);
- vaff_txt(4, window, _format, ap);
- va_end(ap);
- res=ask_YN(window);
- delwin(window);
- (void) clearok(stdscr, TRUE);
-#ifdef HAVE_TOUCHWIN
- touchwin(stdscr);
-#endif
- return res;
-}
-
-static int display_message_ncurses(const char*msg)
-{
- int pipo=0;
- static struct MenuItem menuGeometry[]=
- {
- { 'Q', "Ok", "" },
- { 0, NULL, NULL }
- };
- WINDOW *window=newwin(0,0,0,0); /* full screen */
- aff_copy(window);
- mvwaddstr(window,5,0,msg);
- wmenuSimple(window,menuGeometry, pipo);
- delwin(window);
- (void) clearok(stdscr, TRUE);
-#ifdef HAVE_TOUCHWIN
- touchwin(stdscr);
-#endif
- return 0;
-}
-
-void not_implemented(const char *msg)
-{
- WINDOW *window=newwin(0,0,0,0); /* full screen */
- aff_copy(window);
- wmove(window,7,0);
- wprintw(window,"Function %s not implemented",msg);
- log_warning("Function %s not implemented\n",msg);
- wmove(window,22,0);
- wattrset(window, A_REVERSE);
- wprintw(window,"[ Abort ]");
- wattroff(window, A_REVERSE);
- wrefresh(window);
- while(wgetch(window)==ERR);
- delwin(window);
- (void) clearok(stdscr, TRUE);
-#ifdef HAVE_TOUCHWIN
- touchwin(stdscr);
-#endif
-}
-
-#if defined(DJGPP) || defined(__MINGW32__)
-#else
-static SCREEN *screenp=NULL;
-#endif
-
-static char *filename_to_directory(const char *filename)
-{
- char buf[2048];
- char *res;
-#ifdef HAVE_READLINK
- int len;
- len=readlink(filename,buf,sizeof(buf)-1);
- if(len>=0)
- buf[len]='\0';
- else
- {
- strncpy(buf,filename,sizeof(buf)-1);
- buf[sizeof(buf)-1]='\0';
- }
-#else
- strncpy(buf,filename,sizeof(buf)-1);
- buf[sizeof(buf)-1]='\0';
-#endif
- res=dirname(buf);
- if(res==NULL)
- return NULL;
-#ifdef HAVE_GETCWD
- if(strcmp(res,".")==0 && getcwd(buf, sizeof(buf)-1)!=NULL)
- {
- buf[sizeof(buf)-1]='\0';
- res=buf;
- }
-#endif
-#ifdef __CYGWIN__
- {
- char beautifull_dst_directory[2048];
- cygwin_conv_to_win32_path(res, beautifull_dst_directory);
- return strdup(beautifull_dst_directory);
- }
-#else
- return strdup(res);
-#endif
-}
-
-int start_ncurses(const char *prog_name, const char *real_prog_name)
-{
-#if defined(DJGPP) || defined(__MINGW32__)
- if(initscr()==NULL)
- {
- log_critical("initscr() has failed. Exiting\n");
- printf("initscr() has failed. Exiting\n");
- printf("Press Enter key to quit.\n");
- getchar();
- return 1;
- }
-#else
- {
- int term_overwrite;
- char *terminfo=filename_to_directory(real_prog_name);
- for(term_overwrite=0;screenp==NULL && term_overwrite<=1;term_overwrite++)
- {
-#ifdef HAVE_SETENV
-#if defined(TARGET_BSD)
- setenv("TERM","cons25",term_overwrite);
-#elif defined(TARGET_LINUX)
- setenv("TERM","linux",term_overwrite);
-#elif defined(__CYGWIN__)
- setenv("TERM","cygwin",term_overwrite);
-#elif defined(__OS2__)
- setenv("TERM","ansi",term_overwrite);
-#elif defined(__APPLE__)
- setenv("TERM","xterm-color",term_overwrite);
-#endif
-#endif
- screenp=newterm(NULL,stdout,stdin);
-#ifdef HAVE_SETENV
- if(screenp==NULL && terminfo!=NULL)
- {
- setenv("TERMINFO", terminfo, 1);
- screenp=newterm(NULL,stdout,stdin);
- }
- if(screenp==NULL)
- {
- setenv("TERMINFO",".",1);
- screenp=newterm(NULL,stdout,stdin);
- }
- if(screenp==NULL)
- unsetenv("TERMINFO");
-#endif
- }
- if(screenp==NULL)
- {
- log_critical("Terminfo file is missing.\n");
-#if defined(__CYGWIN__)
- printf("The terminfo file '%s\\c\\cygwin' is missing.\n", terminfo);
-#else
- printf("Terminfo file is missing.\n");
-#endif
- printf("Extract all files and subdirectories before running the program.\n");
- printf("Press Enter key to quit.\n");
- getchar();
- free(terminfo);
- return 1;
- }
- free(terminfo);
- }
-#endif
- noecho();
-#ifndef DJGPP
- nonl(); /*don't use for Dos version but enter will work with it... dilema */
-#endif
- /* intrflush(stdscr, FALSE); */
- cbreak();
- /* Should solve a problem with users who redefined the colors */
- if(has_colors())
- {
- start_color();
- init_pair(1, COLOR_RED, COLOR_BLACK);
- init_pair(2, COLOR_GREEN, COLOR_BLACK);
- }
- curs_set(0);
- {
- int quit=0;
- while(LINES>=8 && LINES<24 && quit==0)
- {
- aff_copy(stdscr);
- wmove(stdscr,4,0);
- wprintw(stdscr,"%s need 24 lines to work.", prog_name);
- wmove(stdscr,5,0);
- wprintw(stdscr,"Please enlarge the terminal.");
- wmove(stdscr,LINES-2,0);
- wattrset(stdscr, A_REVERSE);
- wprintw(stdscr,"[ Quit ]");
- wattroff(stdscr, A_REVERSE);
- wrefresh(stdscr);
- switch(wgetch(stdscr))
- {
- case 'q':
- case 'Q':
- case KEY_ENTER:
-#ifdef PADENTER
- case PADENTER:
-#endif
- case '\n':
- case '\r':
- quit=1;
- break;
- }
- }
- }
- if(LINES<24)
- {
- end_ncurses();
- printf("%s need 24 lines to work.\nPlease enlarge the terminal and restart %s.\n",prog_name,prog_name);
- log_critical("Terminal has only %u lines\n",LINES);
- return 1;
- }
- return 0;
-}
-
-int end_ncurses()
-{
- wclear(stdscr);
- wrefresh(stdscr);
- nl();
- endwin();
-#if defined(DJGPP) || defined(__MINGW32__)
-#else
-#ifdef HAVE_DELSCREEN
- if(screenp!=NULL)
- delscreen(screenp);
-#endif
-#endif
- return 0;
-}
-
-char *ask_log_location(const char*filename)
-{
- static char response[LINE_LENGTH];
- aff_copy(stdscr);
- if(filename!=NULL)
- {
- wmove(stdscr,6,0);
- wprintw(stdscr,"Cannot open %s: %s\n",filename, strerror(errno));
- }
- wmove(stdscr,8,0);
- wprintw(stdscr,"Please enter the full log filename or press ");
- if(has_colors())
- wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
- wprintw(stdscr,"Enter");
- if(has_colors())
- wbkgdset(stdscr,' ' | COLOR_PAIR(0));
- wmove(stdscr,9,0);
- wprintw(stdscr,"to abort log file creation.\n");
- if (get_string(response, LINE_LENGTH, NULL) > 0)
- return response;
- return NULL;
-}
-
-static int intrf_no_disk_ncurses(const char *prog_name)
-{
- aff_copy(stdscr);
- wmove(stdscr,4,0);
- wprintw(stdscr," %s is free software, and",prog_name);
- wmove(stdscr,5,0);
- wprintw(stdscr,"comes with ABSOLUTELY NO WARRANTY.");
- wmove(stdscr,7,0);
- wprintw(stdscr,"No harddisk found\n");
-#if defined(__CYGWIN__) || defined(__MINGW32__)
- wmove(stdscr,8,0);
- wprintw(stdscr,"You need to be administrator to use %s.\n", prog_name);
- wmove(stdscr,9,0);
- wprintw(stdscr,"Under Win9x, use the DOS version instead.\n");
- wmove(stdscr,10,0);
- wprintw(stdscr,"Under Vista, select %s, right-click and choose \"Run as administrator\".\n", prog_name);
-#elif defined(DJGPP)
-#else
-#ifdef HAVE_GETEUID
- if(geteuid()!=0)
- {
- wmove(stdscr,8,0);
- wprintw(stdscr,"You need to be root to use %s.\n", prog_name);
-#ifdef SUDO_BIN
- {
- static const struct MenuItem menuSudo[]=
- {
- {'S',"Sudo","Use the sudo command to restart as root"},
- {'Q',"Quit",""},
- {0,NULL,NULL}
- };
- unsigned int menu=0;
- int command;
- command = wmenuSelect_ext(stdscr,23, 20, 0, menuSudo, 8,
- "SQ", MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
- if(command=='s' || command=='S')
- return 1;
- return 0;
- }
-#endif
- }
-#endif
-#endif
- wmove(stdscr,22,0);
- wattrset(stdscr, A_REVERSE);
- wprintw(stdscr,"[ Quit ]");
- wattroff(stdscr, A_REVERSE);
- wrefresh(stdscr);
- while(wgetch(stdscr)==ERR);
- return 0;
-}
-
-int check_enter_key_or_s(WINDOW *window)
-{
- switch(wgetch_nodelay(window))
- {
- case KEY_ENTER:
-#ifdef PADENTER
- case PADENTER:
-#endif
- case '\n':
- case '\r':
- case 's':
- case 'S':
- return 1;
- }
- return 0;
-}
-
-static int interface_partition_type_ncurses(disk_t *disk_car)
-{
- /* arch_list must match the order from menuOptions */
- const arch_fnct_t *arch_list[]={&arch_i386, &arch_gpt, &arch_mac, &arch_none, &arch_sun, &arch_xbox, NULL};
- unsigned int menu;
- for(menu=0;arch_list[menu]!=NULL && disk_car->arch!=arch_list[menu];menu++);
- if(arch_list[menu]==NULL)
- {
- menu=0;
- disk_car->arch=arch_list[menu];
- }
- /* ncurses interface */
- {
- int car;
- int real_key;
- struct MenuItem menuOptions[]=
- {
- { 'I', arch_i386.part_name, "Intel/PC partition" },
- { 'G', arch_gpt.part_name, "EFI GPT partition map (Mac i386, some x86_64...)" },
- { 'M', arch_mac.part_name, "Apple partition map" },
- { 'N', arch_none.part_name, "Non partitioned media" },
- { 'S', arch_sun.part_name, "Sun Solaris partition"},
- { 'X', arch_xbox.part_name, "XBox partition"},
- { 'Q', "Return", "Return to disk selection"},
- { 0, NULL, NULL }
- };
- aff_copy(stdscr);
- wmove(stdscr,5,0);
- wprintw(stdscr,"%s\n",disk_car->description_short(disk_car));
- wmove(stdscr,INTER_PARTITION_Y-1,0);
- wprintw(stdscr,"Please select the partition table type, press Enter when done.");
- wmove(stdscr,20,0);
- wprintw(stdscr,"Note: Do NOT select 'None' for media with only a single partition. It's very");
- wmove(stdscr,21,0);
- wprintw(stdscr,"rare for a drive to be 'Non-partitioned'.");
- car=wmenuSelect_ext(stdscr, 23, INTER_PARTITION_Y, INTER_PARTITION_X, menuOptions, 7, "IGMNSXQ", MENU_BUTTON | MENU_VERT | MENU_VERT_WARN, &menu,&real_key);
- switch(car)
- {
- case 'i':
- case 'I':
- disk_car->arch=&arch_i386;
- break;
- case 'g':
- case 'G':
- disk_car->arch=&arch_gpt;
- break;
- case 'm':
- case 'M':
- disk_car->arch=&arch_mac;
- break;
- case 'n':
- case 'N':
- disk_car->arch=&arch_none;
- break;
- case 's':
- case 'S':
- disk_car->arch=&arch_sun;
- break;
- case 'x':
- case 'X':
- disk_car->arch=&arch_xbox;
- break;
- case 'q':
- case 'Q':
- return 1;
- }
- }
- autoset_unit(disk_car);
- return 0;
-}
-
-#if defined(DJGPP) || defined(__OS2__)
-void get_dos_drive_list(struct td_list_head *list);
-
-void get_dos_drive_list(struct td_list_head *list)
-{
- int i;
- for(i='a';i<='z';i++)
- {
- file_info_t *new_drive;
- new_drive=(file_info_t*)MALLOC(sizeof(*new_drive));
- new_drive->name[0]=i;
- new_drive->name[1]=':';
- new_drive->name[2]=PATH_SEP;
- new_drive->name[3]='\0';
- new_drive->stat.st_mode=LINUX_S_IFDIR|LINUX_S_IRWXUGO;
- td_list_add_tail(&new_drive->list, list);
- }
-}
-#endif
-
-#define ASK_LOCATION_WAITKEY 0
-#define ASK_LOCATION_UPDATE 1
-#define ASK_LOCATION_NEWDIR 2
-#define ASK_LOCATION_QUIT 3
-
-char *ask_location(const char*msg, const char *src_dir)
-{
- char dst_directory[4096];
- char *res=NULL;
- int quit;
- WINDOW *window=newwin(0,0,0,0); /* full screen */
- aff_copy(window);
- td_getcwd(dst_directory, sizeof(dst_directory));
- do
- {
- DIR* dir;
- static file_info_t dir_list = {
- .list = TD_LIST_HEAD_INIT(dir_list.list),
- .name = {0}
- };
- wmove(window,7,0);
- wclrtoeol(window); /* before addstr for BSD compatibility */
- if(has_colors())
- wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0));
- waddstr(window,"Directory listing in progress...");
- if(has_colors())
- wbkgdset(window,' ' | COLOR_PAIR(0));
- wrefresh(window);
-#if defined(DJGPP) || defined(__OS2__)
- if(dst_directory[0]=='\0')
- {
- get_dos_drive_list(&dir_list.list);
- dir=NULL;
- }
- else
- dir=opendir(dst_directory);
-#else
- dir=opendir(dst_directory);
-#endif
- if(dir!=NULL)
- {
- struct dirent *dir_entrie;
- file_info_t *file_info;
- file_info=(file_info_t*)MALLOC(sizeof(*file_info));
- do
- {
- char current_file[4096];
- dir_entrie=readdir(dir);
- /* if dir_entrie exists
- * there is enough room to store the filename
- * dir_entrie->d_name is ".", ".." or something that doesn't begin by a "."
- * */
- if(dir_entrie!=NULL
- && strlen(dst_directory)+1+strlen(file_info->name)+1<=sizeof(current_file) &&
- (dir_entrie->d_name[0]!='.' ||
- dir_entrie->d_name[1]=='\0' ||
- (dir_entrie->d_name[1]=='.' && dir_entrie->d_name[2]=='\0'))
-#ifdef __CYGWIN__
- && (strlen(dst_directory)>PATH_DRIVE_LENGTH || dir_entrie->d_name[0]!='.')
-#endif
- )
- {
- strcpy(current_file,dst_directory);
-#if defined(DJGPP) || defined(__OS2__)
- if(current_file[0]!='\0'&&current_file[1]!='\0'&&current_file[2]!='\0'&&current_file[3]!='\0')
-#else
- if(current_file[1]!='\0')
-#endif
- strcat(current_file,SPATH_SEP);
- strcat(current_file,dir_entrie->d_name);
-#ifdef HAVE_LSTAT
- if(lstat(current_file,&file_info->stat)==0)
-#else
- if(stat(current_file,&file_info->stat)==0)
-#endif
- {
-#if defined(DJGPP) || defined(__OS2__)
- /* If the C library doesn't use posix definition, st_mode need to be fixed */
- if(S_ISDIR(file_info->stat.st_mode))
- file_info->stat.st_mode=LINUX_S_IFDIR|LINUX_S_IRWXUGO;
- else
- file_info->stat.st_mode=LINUX_S_IFREG|LINUX_S_IRWXUGO;
-#endif
-#ifdef __CYGWIN__
- /* Fix Drive list */
- if(strlen(dst_directory)<=PATH_DRIVE_LENGTH)
- {
- file_info->stat.st_mode=LINUX_S_IFDIR|LINUX_S_IRWXUGO;
- file_info->stat.st_mtime=0;
- file_info->stat.st_uid=0;
- file_info->stat.st_gid=0;
- }
-#endif
- strncpy(file_info->name,dir_entrie->d_name,sizeof(file_info->name));
- td_list_add_sorted(&file_info->list, &dir_list.list, filesort);
- file_info=(file_info_t*)MALLOC(sizeof(*file_info));
- }
- }
- } while(dir_entrie!=NULL);
- free(file_info);
- closedir(dir);
- }
- if(dir_list.list.next!=&dir_list.list)
- {
- struct td_list_head *current_file=dir_list.list.next;
- int offset=0;
- int pos_num=0;
- int old_LINES=LINES;
- do
- {
- int dst_directory_ok=0;
- if(old_LINES!=LINES)
- { /* Screen size has changed, reset to initial values */
- current_file=dir_list.list.next;
- offset=0;
- pos_num=0;
- old_LINES=LINES;
- }
- aff_copy(window);
- wmove(window,7,0);
-#ifdef __CYGWIN__
- if(strlen(dst_directory)<=PATH_DRIVE_LENGTH)
- wprintw(window,"To select a drive, use the arrow keys.");
- else
- wprintw(window,"To select another directory, use the arrow keys.");
-#elif defined(DJGPP) || defined(__OS2__)
- if(dst_directory[0]=='\0')
- wprintw(window,"To select a drive, use the arrow keys.");
- else
- wprintw(window,"To select another directory, use the arrow keys.");
-#else
- wprintw(window,"To select another directory, use the arrow keys.");
-#endif
- {
- struct td_list_head *file_walker = NULL;
- int i=0;
- td_list_for_each(file_walker,&dir_list.list)
- {
- if(i++<offset)
- continue;
- {
- file_info_t *file_info;
- file_info=td_list_entry(file_walker, file_info_t, list);
- wmove(window,8-1+i-offset,0);
- wclrtoeol(window); /* before addstr for BSD compatibility */
- if(file_walker==current_file)
- wattrset(window, A_REVERSE);
- dir_aff_entry(window,file_info);
- if(file_walker==current_file)
- wattroff(window, A_REVERSE);
- }
- if(offset+INTER_DIR<=i)
- break;
- }
- wmove(window, 8+INTER_DIR, 4);
- wclrtoeol(window);
- if(file_walker!=&dir_list.list && file_walker->next!=&dir_list.list)
- wprintw(window, "Next");
- }
- if(strcmp(dst_directory,".")==0)
- {
- aff_txt(4, window, msg, src_dir, "the program is running from");
- dst_directory_ok=1;
- }
- else
- {
-#ifdef __CYGWIN__
- if(strlen(dst_directory)>PATH_DRIVE_LENGTH)
- {
- char beautifull_dst_directory[4096];
- cygwin_conv_to_win32_path(dst_directory, beautifull_dst_directory);
- aff_txt(4, window, msg, src_dir, beautifull_dst_directory);
- dst_directory_ok=1;
- }
-#elif defined(DJGPP) || defined(__OS2__)
- if(strlen(dst_directory)>0)
- {
- aff_txt(4, window, msg, src_dir, dst_directory);
- dst_directory_ok=1;
- }
-#else
- aff_txt(4, window, msg, src_dir, dst_directory);
- dst_directory_ok=1;
-#endif
- }
- wclrtoeol(window); /* before addstr for BSD compatibility */
- wrefresh(window);
- do
- {
- quit=ASK_LOCATION_WAITKEY;
- switch(wgetch(window))
- {
- case 'y':
- case 'Y':
- if(dst_directory_ok>0)
- {
- res=strdup(dst_directory);
- quit=ASK_LOCATION_QUIT;
- }
- break;
- case 'n':
- case 'N':
- res=NULL;
- quit=ASK_LOCATION_QUIT;
- break;
- case KEY_UP:
- case '8':
- if(current_file->prev!=&dir_list.list)
- {
- current_file=current_file->prev;
- pos_num--;
- quit=ASK_LOCATION_UPDATE;
- }
- break;
- case KEY_DOWN:
- case '2':
- if(current_file->next!=&dir_list.list)
- {
- current_file=current_file->next;
- pos_num++;
- quit=ASK_LOCATION_UPDATE;
- }
- break;
- case KEY_PPAGE:
- {
- int i;
- for(i=0; i<INTER_DIR-1 && current_file->prev!=&dir_list.list; i++)
- {
- current_file=current_file->prev;
- pos_num--;
- quit=ASK_LOCATION_UPDATE;
- }
- }
- break;
- case KEY_NPAGE:
- {
- int i;
- for(i=0; i<INTER_DIR-1 && current_file->next!=&dir_list.list; i++)
- {
- current_file=current_file->next;
- pos_num++;
- quit=ASK_LOCATION_UPDATE;
- }
- }
- break;
- case KEY_LEFT:
- case '4':
- set_parent_directory(dst_directory);
- quit=ASK_LOCATION_NEWDIR;
- break;
- case KEY_RIGHT:
- case '\r':
- case '\n':
- case '6':
- case KEY_ENTER:
-#ifdef PADENTER
- case PADENTER:
-#endif
- {
- file_info_t *file_info;
- file_info=td_list_entry(current_file, file_info_t, list);
- if(current_file!=&dir_list.list &&
- (LINUX_S_ISDIR(file_info->stat.st_mode) || LINUX_S_ISLNK(file_info->stat.st_mode)))
- if(current_file!=&dir_list.list)
- {
- if(strcmp(file_info->name,".")==0)
- {
- }
- else if(strcmp(file_info->name,"..")==0)
- {
- set_parent_directory(dst_directory);
- quit=ASK_LOCATION_NEWDIR;
- }
- else if(strlen(dst_directory)+1+strlen(file_info->name)+1<=sizeof(dst_directory))
- {
-#if defined(DJGPP) || defined(__OS2__)
- if(dst_directory[0]!='\0'&&dst_directory[1]!='\0'&&dst_directory[2]!='\0'&&dst_directory[3]!='\0')
-#else
- if(dst_directory[1]!='\0')
-#endif
- strcat(dst_directory,SPATH_SEP);
- strcat(dst_directory,file_info->name);
- quit=ASK_LOCATION_NEWDIR;
- }
- }
- }
- break;
-
- }
- if(pos_num<offset)
- offset=pos_num;
- if(pos_num>=offset+INTER_DIR)
- offset=pos_num-INTER_DIR+1;
- } while(quit==ASK_LOCATION_WAITKEY && old_LINES==LINES);
- } while(quit==ASK_LOCATION_UPDATE || old_LINES!=LINES);
- delete_list_file_info(&dir_list.list);
- }
- else
- {
- set_parent_directory(dst_directory);
- quit=ASK_LOCATION_NEWDIR;
- }
- } while(quit==ASK_LOCATION_NEWDIR);
- delwin(window);
- (void) clearok(stdscr, TRUE);
-#ifdef HAVE_TOUCHWIN
- touchwin(stdscr);
-#endif
- return res;
-}
-
-static int vaff_txt(int line, WINDOW *window, const char *_format, va_list ap)
-{
- char buffer[1024];
- int i;
- vsnprintf(buffer,sizeof(buffer),_format,ap);
- buffer[sizeof(buffer)-1]='\0';
- for(i=0;buffer[i]!='\0';)
- {
- char buffer2[1024];
- int j,end=i,end2=i;
- for(j=i;buffer[j]!='\0' && (j-i)<COLUMNS;j++)
- if((buffer[j]==' ' || buffer[j]=='\t') && buffer[j+1]!='?' && buffer[j+1]!='[')
- {
- end=j;
- end2=j;
- }
- else if(buffer[j]=='\n')
- {
- end=j;
- end2=j;
- break;
- }
- else if(buffer[j]=='\\' || buffer[j]=='/')
- end2=j;
- if(end2>end && end-i<COLUMNS*3/4)
- end=end2;
- if(end==i)
- end=j-1;
- if(buffer[j]=='\0')
- end=j;
- wmove(window,line,0);
- line++;
- memcpy(buffer2,&buffer[i],end-i+1);
- buffer2[end-i+1]='\0';
- waddstr(window,buffer2);
- for(i=end;buffer[i]==' ' || buffer[i]=='\t' || buffer[i]=='\n'; i++);
- }
- return line;
-}
-
-static int aff_txt(int line, WINDOW *window, const char *_format, ...)
-{
- va_list ap;
- va_start(ap,_format);
- line=vaff_txt(line, window, _format, ap);
- va_end(ap);
- return line;
-}
-
-static void dir_aff_entry(WINDOW *window, file_info_t *file_info)
-{
- struct tm *tm_p;
- char str[11];
- char datestr[80];
- if(file_info->stat.st_mtime!=0)
- {
- tm_p = localtime(&file_info->stat.st_mtime);
- snprintf(datestr, sizeof(datestr),"%2d-%s-%4d %02d:%02d",
- tm_p->tm_mday, monstr[tm_p->tm_mon],
- 1900 + tm_p->tm_year, tm_p->tm_hour,
- tm_p->tm_min);
- /* May have to use %d instead of %e */
- } else {
- strncpy(datestr, " ",sizeof(datestr));
- }
- mode_string(file_info->stat.st_mode,str);
- wprintw(window, "%s %5u %5u ",
- str, (unsigned int)file_info->stat.st_uid, (unsigned int)file_info->stat.st_gid);
- wprintw(window, "%7llu", (long long unsigned int)file_info->stat.st_size);
- /* screen may overlap due to long filename */
- wprintw(window, " %s %s", datestr, file_info->name);
-}
-#else
-char *ask_log_location(const char*filename)
-{
- return NULL;
-}
-
-void not_implemented(const char *msg)
-{
-}
-
-int ask_confirmation(const char*_format, ...)
-{ /* Don't confirm */
- return 0;
-}
-
-char *ask_location(const char*msg, const char *src_dir)
-{
- return get_default_location();
-}
-#endif
-
unsigned long long int ask_number_cli(char **current_cmd, const unsigned long long int val_cur, const unsigned long long int val_min, const unsigned long long int val_max, const char * _format, ...)
{
if(*current_cmd!=NULL)
@@ -1989,66 +279,3 @@ void log_CHS_from_LBA(const disk_t *disk_car, const unsigned long int pos_LBA)
head=tmp % disk_car->geom.heads_per_cylinder;
log_info("%lu/%lu/%lu", cylinder, head, sector);
}
-
-int display_message(const char*msg)
-{
- log_info("%s",msg);
-#ifdef HAVE_NCURSES
- return display_message_ncurses(msg);
-#else
- return 0;
-#endif
-}
-
-int intrf_no_disk(const char *prog_name)
-{
- log_critical("No disk found\n");
-#ifdef HAVE_NCURSES
- return intrf_no_disk_ncurses(prog_name);
-#else
- printf("No disk found\n");
- return 0;
-#endif
-}
-
-int interface_partition_type(disk_t *disk_car, const int verbose, char**current_cmd)
-{
- const arch_fnct_t *arch_list[]={&arch_i386, &arch_gpt, &arch_none, &arch_sun, &arch_mac, NULL};
- int ask_user=1;
- if(*current_cmd!=NULL)
- {
- int keep_asking;
- do
- {
- int i;
- ask_user=0;
- keep_asking=0;
- while(*current_cmd[0]==',')
- (*current_cmd)++;
- for(i=0;arch_list[i]!=NULL;i++)
- if(strncmp(*current_cmd, arch_list[i]->part_name_option, strlen(arch_list[i]->part_name_option))==0)
- {
- (*current_cmd)+=strlen(arch_list[i]->part_name_option);
- disk_car->arch=arch_list[i];
- autoset_unit(disk_car);
- keep_asking=1;
- }
- if(strncmp(*current_cmd, "ask_type", 8)==0)
- {
- (*current_cmd)+=8;
- ask_user=1;
- }
- } while(keep_asking>0);
- }
- if(ask_user>0)
- {
-#ifdef HAVE_NCURSES
- if(interface_partition_type_ncurses(disk_car))
- return 1;
-#endif
- }
- log_info("%s\n",disk_car->description_short(disk_car));
- log_info("Partition table type: %s\n",disk_car->arch->part_name);
- hd_update_geometry(disk_car, 0,verbose);
- return 0;
-}
diff --git a/src/intrf.h b/src/intrf.h
index 708a32d..5f837d0 100644
--- a/src/intrf.h
+++ b/src/intrf.h
@@ -19,6 +19,9 @@
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
struct MenuItem
{
@@ -72,7 +75,6 @@ int ask_confirmation(const char*_format, ...) __attribute__ ((format (printf, 1,
unsigned long long int ask_number(const unsigned long long int val_cur, const unsigned long long int val_min, const unsigned long long int val_max, const char * _format, ...) __attribute__ ((format (printf, 4, 5)));
unsigned long long int ask_number_cli(char **current_cmd, const unsigned long long int val_cur, const unsigned long long int val_min, const unsigned long long int val_max, const char * _format, ...) __attribute__ ((format (printf, 5, 6)));
int display_message_aux(const char*_format,...) __attribute__ ((format (printf, 1, 2)));
-int display_message(const char*msg);
int get_string(char *str, int len, char *def);
void not_implemented(const char *msg);
void screen_buffer_reset(void);
@@ -80,9 +82,11 @@ int screen_buffer_add(const char *_format, ...) __attribute__ ((format (printf,
void screen_buffer_to_log(void);
void screen_buffer_to_interface(void);
void screen_buffer_to_stdout(void);
-int interface_partition_type(disk_t *disk_car, const int verbose, char**current_cmd);
int intrf_no_disk(const char *prog_name);
-char *ask_log_location(const char*filename);
-char *ask_location(const char*msg, const char *src_dir);
char *get_default_location(void);
void dump_ncurses(const void *nom_dump, unsigned int lng);
+char *td_getcwd(char *buf, unsigned long size);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/intrface.c b/src/intrface.c
index 305c51c..05de5d8 100644
--- a/src/intrface.c
+++ b/src/intrface.c
@@ -2,7 +2,7 @@
File: intrface.c
- Copyright (C) 1998-2008 Christophe GRENIER <grenier@cgsecurity.org>
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
This software is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -37,17 +37,20 @@
#endif
#include "godmode.h"
#include "fnctdsk.h"
-#include "chgtype.h"
+#include "chgtypen.h"
#include "savehdr.h"
#include "dirpart.h"
#include "log.h"
#include "io_redir.h"
#include "tload.h"
#include "intrface.h"
+#include "addpart.h"
#define INTER_DISK_X 0
#define INTER_DISK_Y 7
+extern const arch_fnct_t arch_none;
+
void interface_list(disk_t *disk_car, const int verbose, const int saveheader, const int backup, char **current_cmd)
{
list_part_t *list_part;
@@ -195,7 +198,7 @@ static list_part_t *ask_structure_ncurses(disk_t *disk_car,list_part_t *list_par
wclrtoeol(stdscr); /* before addstr for BSD compatibility */
waddstr(stdscr,"Keys ");
/* If the disk can't be partionned, there is no partition to add and no partition to save */
- if(disk_car->arch->add_partition!=NULL)
+ if(disk_car->arch != &arch_none)
{
if(has_colors())
wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
@@ -321,9 +324,9 @@ static list_part_t *ask_structure_ncurses(disk_t *disk_car,list_part_t *list_par
break;
case 'a':
case 'A':
- if(disk_car->arch->add_partition!=NULL)
+ if(disk_car->arch != &arch_none)
{
- list_part=disk_car->arch->add_partition(disk_car,list_part, verbose, current_cmd);
+ list_part=add_partition(disk_car,list_part, verbose, current_cmd);
rewrite=1;
offset=0;
pos_num=0;
@@ -359,7 +362,7 @@ static list_part_t *ask_structure_ncurses(disk_t *disk_car,list_part_t *list_par
break;
case 'l':
case 'L':
- if(disk_car->arch->add_partition!=NULL)
+ if(disk_car->arch != &arch_none)
{
list_part=interface_load(disk_car,list_part,verbose);
rewrite=1;
diff --git a/src/intrface.h b/src/intrface.h
index a2eff2d..54f1996 100644
--- a/src/intrface.h
+++ b/src/intrface.h
@@ -19,6 +19,13 @@
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
list_part_t *ask_structure(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd);
void interface_list(disk_t *disk_car, const int verbose, const int saveheader, const int backup, char **current_cmd);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/intrfn.c b/src/intrfn.c
new file mode 100644
index 0000000..69983a3
--- /dev/null
+++ b/src/intrfn.c
@@ -0,0 +1,1313 @@
+/*
+
+ File: intrfn.c
+
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_NCURSES
+#include <stdarg.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <ctype.h>
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_CYGWIN_H
+#include <sys/cygwin.h>
+#endif
+#ifdef HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#include <errno.h>
+#include "types.h"
+#include "common.h"
+#include "lang.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "fnctdsk.h"
+#include "list.h"
+#include "dir.h"
+#include "log.h"
+#include "hdaccess.h"
+#include "askloc.h"
+
+extern const arch_fnct_t arch_i386;
+extern const arch_fnct_t arch_gpt;
+extern const arch_fnct_t arch_mac;
+extern const arch_fnct_t arch_none;
+extern const arch_fnct_t arch_sun;
+extern const arch_fnct_t arch_xbox;
+extern char intr_buffer_screen[MAX_LINES][LINE_LENGTH+1];
+extern int intr_nbr_line;
+
+/* Use COLS (actual number of columns) or COLUMNS (number of columns the program has been designed for) ? */
+#define INTER_DIR (LINES-25+16)
+#define GS_DEFAULT -1
+#define GS_key_ESCAPE -2
+
+static int wmenuUpdate(WINDOW *window, const int yinfo, int y, int x, const struct MenuItem *menuItems, const unsigned int itemLength, const char *available, const int menuType, unsigned int current);
+static int wgetch_nodelay(WINDOW *window);
+
+int get_string(char *str, int len, char *def)
+{
+ int c;
+ int i = 0;
+ int x, y;
+ int use_def = FALSE;
+ curs_set(1);
+ getyx(stdscr, y, x);
+ wclrtoeol(stdscr);
+ str[0] = 0;
+
+ if (def != NULL) {
+ mvwaddstr(stdscr,y, x, def);
+ wmove(stdscr,y, x);
+ use_def = TRUE;
+ }
+
+ wrefresh(stdscr);
+ while ((c = wgetch(stdscr)) != '\n' && c != key_CR
+#ifdef PADENTER
+ && c!= PADENTER
+#endif
+ )
+ {
+ switch (c) {
+ /* escape is generated by enter from keypad */
+ /*
+ case key_ESC:
+ wmove(stdscr,y, x);
+ wclrtoeol(stdscr);
+ curs_set(0);
+ wrefresh(stdscr);
+ return GS_key_ESCAPE;
+ */
+ case KEY_DC:
+ case KEY_BACKSPACE:
+ if (i > 0) {
+ str[--i] = 0;
+ mvaddch(y, x+i, ' ');
+ wmove(stdscr,y, x+i);
+ } else if (use_def) {
+ wclrtoeol(stdscr);
+ use_def = FALSE;
+ }
+ break;
+ default:
+ if (i < len && isprint(c)) {
+ mvaddch(y, x+i, c);
+ if (use_def) {
+ wclrtoeol(stdscr);
+ use_def = FALSE;
+ }
+ str[i++] = c;
+ str[i] = 0;
+ }
+ }
+ wrefresh(stdscr);
+ }
+ curs_set(0);
+ wrefresh(stdscr);
+ if (use_def)
+ return GS_DEFAULT;
+ else
+ return i;
+}
+
+static int wgetch_nodelay(WINDOW *window)
+{
+ int res;
+ nodelay(window,TRUE);
+ res=wgetch(window);
+ nodelay(window,FALSE);
+ return res;
+}
+
+/*
+ * Actual function which prints the button bar and highlights the active button
+ * Should not be called directly. Call function menuSelect instead.
+ */
+
+static int wmenuUpdate(WINDOW *window, const int yinfo, int y, int x, const struct MenuItem *menuItems, const unsigned int itemLength, const char *available, const int menuType, unsigned int current)
+{
+ unsigned int i, lmargin = x, ymargin = y;
+ unsigned int lenNameMax=0;
+ for( i = 0; menuItems[i].key!=0; i++ )
+ if(strchr(available, menuItems[i].key)!=NULL )
+ {
+ unsigned int lenName = strlen( menuItems[i].name );
+ if(lenNameMax<lenName && lenName < itemLength)
+ lenNameMax=lenName;
+ }
+ /* Print available buttons */
+ for( i = 0; menuItems[i].key!=0; i++ )
+ {
+ char buff[80];
+ unsigned int lenName;
+ const char *mi;
+ wmove(window, y, x );
+ wclrtoeol(window);
+
+ /* Search next available button */
+ while( menuItems[i].key!=0 && strchr(available, menuItems[i].key)==NULL )
+ {
+ i++;
+ }
+ if( menuItems[i].key==0 ) break; /* No more menu items */
+
+ /* If selected item is not available and we have bypassed it,
+ make current item selected */
+ if( current < i && menuItems[current].key < 0 ) current = i;
+
+ mi = menuItems[i].name;
+ lenName = strlen( mi );
+ if(lenName>=sizeof(buff))
+ {
+ log_critical("\nBUG: %s\n",mi);
+ }
+ if(lenName >= itemLength)
+ {
+ if( menuType & MENU_BUTTON )
+ snprintf(buff, sizeof(buff),"[%s]",mi);
+ else
+ snprintf(buff, sizeof(buff),"%s",mi);
+ }
+ else
+ {
+ if( menuType & MENU_BUTTON )
+ {
+ if(menuType & MENU_VERT)
+ snprintf( buff, sizeof(buff),"[%*s%-*s]", (itemLength - lenNameMax) / 2, "",
+ (itemLength - lenNameMax + 1) / 2 + lenNameMax, mi );
+ else
+ snprintf( buff, sizeof(buff),"[%*s%-*s]", (itemLength - lenName) / 2, "",
+ (itemLength - lenName + 1) / 2 + lenName, mi );
+ }
+ else
+ snprintf( buff, sizeof(buff),"%*s%-*s", (itemLength - lenName) / 2, "",
+ (itemLength - lenName + 1) / 2 + lenName, mi );
+ }
+ /* If current item is selected, highlight it */
+ if( current == i )
+ {
+ wattrset(window, A_REVERSE);
+ }
+
+ /* Print item */
+ mvwaddstr(window, y, x, buff );
+
+ /* Lowlight after selected item */
+ if( current == i )
+ {
+ wattroff(window, A_REVERSE);
+ }
+ if(menuType & MENU_VERT_WARN)
+ mvwaddstr(window, y, x+itemLength+4, menuItems[i].desc);
+
+ /* Calculate position for the next item */
+ if( menuType & MENU_VERT )
+ {
+ y += 1;
+ if( y >= yinfo - 1)
+ {
+ y = ymargin;
+ x += (lenName < itemLength?itemLength:lenName) + MENU_SPACING;
+ if( menuType & MENU_BUTTON ) x += 2;
+ }
+ }
+ else
+ {
+ x += (lenName < itemLength?itemLength:lenName) + MENU_SPACING;
+ if( menuType & MENU_BUTTON ) x += 2;
+ if( x > COLUMNS - lmargin - 12 )
+ {
+ x = lmargin;
+ y ++ ;
+ }
+ }
+ }
+ /* Print the description of selected item */
+ if(!(menuType & MENU_VERT_WARN))
+ {
+ const char *mcd = menuItems[current].desc;
+ mvwaddstr(window, yinfo, (COLUMNS - strlen( mcd )) / 2, mcd );
+ }
+ return y;
+}
+
+/* This function takes a list of menu items, lets the user choose one *
+ * and returns the value keyboard shortcut of the selected menu item */
+
+int wmenuSelect(WINDOW *window, int yinfo, int y, int x, const struct MenuItem *menuItems, const unsigned int itemLength, const char *available, int menuType, unsigned int menuDefault)
+{
+ unsigned int current=menuDefault;
+ return wmenuSelect_ext(window, yinfo, y, x, menuItems, itemLength, available, menuType, &current, NULL);
+}
+
+int wmenuSelect_ext(WINDOW *window, const int yinfo, int y, int x, const struct MenuItem *menuItems, const unsigned int itemLength, const char *available, int menuType, unsigned int *current, int *real_key)
+{
+ int i, ylast = y, key = 0;
+ /*
+ if( ( menuType & ( MENU_HORIZ | MENU_VERT ) )==0 )
+ {
+ wprintw(window,"Menu without direction. Defaulting horizontal.");
+ menuType |= MENU_HORIZ;
+ }
+ */
+ /* Warning: current may be out of bound, not checked */
+ /* Make sure that the current is one of the available items */
+ while(strchr(available, menuItems[*current].key)==NULL)
+ {
+ (*current)++ ;
+ if( menuItems[*current].key==0 )
+ {
+ *current = 0;
+ }
+ }
+ /* Repeat until allowable choice has been made */
+ while( key==0 )
+ {
+ /* Display the menu */
+ ylast = wmenuUpdate( window, yinfo, y, x, menuItems, itemLength, available,
+ menuType, *current );
+ wrefresh(window);
+ /* Don't put wgetch after the following wclrtoeol */
+ key = wgetch(window);
+ if(real_key!=NULL)
+ *real_key=key;
+
+ /* Clear out all prompts and such */
+ for( i = y; i < ylast; i ++ )
+ {
+ wmove(window, i, x );
+ wclrtoeol(window);
+ }
+ wmove(window, yinfo, 0 );
+ wclrtoeol(window);
+ if(strchr(available, key)==NULL)
+ {
+ if(key=='2')
+ key=KEY_DOWN;
+ else if(key=='4')
+ key=KEY_LEFT;
+ else if(key=='5')
+ key=KEY_ENTER;
+ else if(key=='6')
+ key=KEY_RIGHT;
+ else if(key=='8')
+ key=KEY_UP;
+ }
+ /* Cursor keys */
+ switch(key)
+ {
+ case KEY_UP:
+ if( (menuType & MENU_VERT)!=0 )
+ {
+ do {
+ if( (*current)-- == 0 )
+ {
+ while( menuItems[(*current)+1].key ) (*current) ++ ;
+ }
+ } while( strchr( available, menuItems[*current].key )==NULL );
+ key = 0;
+ }
+ break;
+ case KEY_DOWN:
+ if( (menuType & MENU_VERT)!=0 )
+ {
+ do {
+ (*current) ++ ;
+ if( menuItems[*current].key==0 ) *current = 0 ;
+ } while( strchr( available, menuItems[*current].key )==NULL );
+ key = 0;
+ }
+ break;
+ case KEY_RIGHT:
+ if( (menuType & MENU_HORIZ)!=0 )
+ {
+ do {
+ (*current) ++ ;
+ if( menuItems[*current].key==0 )
+ {
+ *current = 0 ;
+ }
+ } while( strchr( available, menuItems[*current].key )==NULL );
+ key = 0;
+ }
+ break;
+ case KEY_LEFT:
+ if( (menuType & MENU_HORIZ) !=0)
+ {
+ do {
+ if( (*current)-- == 0 )
+ {
+ while( menuItems[(*current) + 1].key ) (*current) ++ ;
+ }
+ } while( strchr( available, menuItems[*current].key )==NULL );
+ key = 0;
+ }
+ break;
+ }
+ /* Enter equals to the keyboard shortcut of current menu item */
+ if((key==13) || (key==10) || (key==KEY_ENTER) ||
+ (((menuType & MENU_VERT) != 0) && ((menuType & MENU_VERT_ARROW2VALID) != 0)
+ && (key==KEY_RIGHT || key==KEY_LEFT)))
+ key = menuItems[*current].key;
+#ifdef PADENTER
+ if(key==PADENTER)
+ key = menuItems[*current].key;
+#endif
+
+ /* Is pressed key among acceptable ones */
+ if( key!=0 && (strchr(available, toupper(key))!=NULL || strchr(available, key)!=NULL))
+ break;
+ /* Should all keys to be accepted? */
+ if( key && (menuType & MENU_ACCEPT_OTHERS)!=0 ) break;
+ /* The key has not been accepted so far -> let's reject it */
+#ifdef DEBUG
+ if( key )
+ {
+ wmove(window,5,0);
+ wprintw(window,"key %03X",key);
+ putchar( BELL );
+ }
+#endif
+ key = 0;
+ }
+ /* Clear out prompts and such */
+ for( i = y; i <= ylast; i ++ )
+ {
+ wmove(window, i, x );
+ wclrtoeol(window);
+ }
+ wmove(window, yinfo, 0 );
+ wclrtoeol(window);
+ return key;
+}
+
+/* Function menuSelect takes way too many parameters *
+ * Luckily, most of time we can do with this function */
+
+int wmenuSimple(WINDOW *window,const struct MenuItem *menuItems, unsigned int menuDefault)
+{
+ unsigned int i, j, itemLength = 0;
+ char available[MENU_MAX_ITEMS];
+
+ for(i = 0; menuItems[i].key; i++)
+ {
+ j = strlen(menuItems[i].name);
+ if( j > itemLength ) itemLength = j;
+ available[i] = menuItems[i].key;
+ }
+ available[i] = 0;
+ return wmenuSelect(window, 23, 18, 0, menuItems, itemLength, available, MENU_HORIZ | MENU_BUTTON, menuDefault);
+}
+
+/* End of command menu support code */
+
+unsigned long long int ask_number(const unsigned long long int val_cur, const unsigned long long int val_min, const unsigned long long int val_max, const char * _format, ...)
+{
+ char res[200];
+ char res2[200];
+ char response[LINE_LENGTH];
+ char def[LINE_LENGTH];
+ unsigned long int tmp_val;
+ va_list ap;
+ va_start(ap,_format);
+ vsnprintf(res,sizeof(res),_format,ap);
+ if(val_min!=val_max)
+ snprintf(res2,sizeof(res2),"(%llu-%llu) :",val_min,val_max);
+ else
+ res2[0]='\0';
+ va_end(ap);
+ waddstr(stdscr, res);
+ waddstr(stdscr, res2);
+ sprintf(def, "%llu", val_cur);
+ if (get_string(response, LINE_LENGTH, def) > 0)
+ {
+#ifdef HAVE_ATOLL
+ tmp_val = atoll(response);
+#else
+ tmp_val = atol(response);
+#endif
+ if (val_min==val_max || (tmp_val >= val_min && tmp_val <= val_max))
+ return tmp_val;
+ }
+ return val_cur;
+}
+
+void dump_ncurses(const void *nom_dump, unsigned int lng)
+{
+ WINDOW *window=newwin(0,0,0,0); /* full screen */
+ keypad(window, TRUE); /* Need it to get arrow key */
+ aff_copy(window);
+ dump(window, nom_dump, lng);
+ dump_log(nom_dump,lng);
+ delwin(window);
+ (void) clearok(stdscr, TRUE);
+#ifdef HAVE_TOUCHWIN
+ touchwin(stdscr);
+#endif
+}
+
+void dump(WINDOW *window, const void *nom_dump,unsigned int lng)
+{
+ unsigned int i,j;
+ unsigned int nbr_line;
+ unsigned char car;
+ unsigned int pos=0;
+ int done=0;
+ unsigned int menu=2; /* default : quit */
+ const char *options="PNQ";
+ struct MenuItem menuDump[]=
+ {
+ { 'P', "Previous",""},
+ { 'N', "Next","" },
+ { 'Q',"Quit","Quit dump section"},
+ { 0, NULL, NULL }
+ };
+ nbr_line=(lng+0x10-1)/0x10;
+ if(nbr_line<=DUMP_MAX_LINES)
+ {
+ options="Q";
+ }
+ /* ncurses interface */
+ mvwaddstr(window,DUMP_Y,DUMP_X,msg_DUMP_HEXA);
+ /* On pourrait utiliser wscrl */
+ do
+ {
+ for (i=pos; (i<nbr_line)&&((i-pos)<DUMP_MAX_LINES); i++)
+ {
+ wmove(window,DUMP_Y+i-pos,DUMP_X);
+ wclrtoeol(window);
+ wprintw(window,"%04X ",i*0x10);
+ for(j=0; j< 0x10;j++)
+ {
+ if(i*0x10+j<lng)
+ {
+ car=*((const unsigned char*)nom_dump+i*0x10+j);
+ wprintw(window,"%02x", car);
+ }
+ else
+ wprintw(window," ");
+ if(j%4==(4-1))
+ wprintw(window," ");
+ }
+ wprintw(window," ");
+ for(j=0; j< 0x10;j++)
+ {
+ if(i*0x10+j<lng)
+ {
+ car=*((const unsigned char*)nom_dump+i*0x10+j);
+ if ((car<32)||(car >= 127))
+ wprintw(window,".");
+ else
+ wprintw(window,"%c", car);
+ }
+ else
+ wprintw(window," ");
+ }
+ }
+ switch (wmenuSelect(window, INTER_DUMP_Y+1, INTER_DUMP_Y, INTER_DUMP_X, menuDump, 8, options, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu))
+ {
+ case 'p':
+ case 'P':
+ case KEY_UP:
+ if(strchr(options,'N')!=NULL)
+ {
+ menu=0;
+ if(pos>0)
+ pos--;
+ }
+ break;
+ case 'n':
+ case 'N':
+ case KEY_DOWN:
+ if(strchr(options,'N')!=NULL)
+ {
+ menu=1;
+ if(pos<nbr_line-DUMP_MAX_LINES)
+ pos++;
+ }
+ break;
+ case KEY_PPAGE:
+ if(strchr(options,'N')!=NULL)
+ {
+ menu=0;
+ if(pos>DUMP_MAX_LINES-1)
+ pos-=DUMP_MAX_LINES-1;
+ else
+ pos=0;
+ }
+ break;
+ case KEY_NPAGE:
+ if(strchr(options,'N')!=NULL)
+ {
+ menu=1;
+ if(pos<nbr_line-DUMP_MAX_LINES-(DUMP_MAX_LINES-1))
+ pos+=DUMP_MAX_LINES-1;
+ else
+ pos=nbr_line-DUMP_MAX_LINES;
+ }
+ break;
+ case key_ESC:
+ case 'q':
+ case 'Q':
+ done = TRUE;
+ break;
+ }
+ } while(done==FALSE);
+}
+
+void dump2(WINDOW *window, const void *dump_1, const void *dump_2, const unsigned int lng)
+{
+ unsigned int i,j;
+ unsigned int nbr_line;
+ unsigned int pos=0;
+ int done=0;
+ unsigned int menu=2; /* default : quit */
+ const char *options="PNQ";
+ struct MenuItem menuDump[]=
+ {
+ { 'P', "Previous",""},
+ { 'N', "Next","" },
+ { 'Q',"Quit","Quit dump section"},
+ { 0, NULL, NULL }
+ };
+ /* ncurses interface */
+ nbr_line=(lng+0x08-1)/0x08;
+ if(nbr_line<=DUMP_MAX_LINES)
+ {
+ options="Q";
+ }
+ do
+ {
+ for (i=pos; (i<nbr_line)&&((i-pos)<DUMP_MAX_LINES); i++)
+ {
+ wmove(window,DUMP_Y+i-pos,DUMP_X);
+ wclrtoeol(window);
+ wprintw(window,"%04X ",i*0x08);
+ for(j=0; j<0x08;j++)
+ {
+ if(i*0x08+j<lng)
+ {
+ unsigned char car1=*((const unsigned char*)dump_1+i*0x08+j);
+ unsigned char car2=*((const unsigned char*)dump_2+i*0x08+j);
+ if(car1!=car2)
+ wattrset(window, A_REVERSE);
+ wprintw(window,"%02x", car1);
+ if(car1!=car2)
+ wattroff(window, A_REVERSE);
+ }
+ else
+ wprintw(window," ");
+ if(j%4==(4-1))
+ wprintw(window," ");
+ }
+ wprintw(window," ");
+ for(j=0; j<0x08;j++)
+ {
+ if(i*0x08+j<lng)
+ {
+ unsigned char car1=*((const unsigned char*)dump_1+i*0x08+j);
+ unsigned char car2=*((const unsigned char*)dump_2+i*0x08+j);
+ if(car1!=car2)
+ wattrset(window, A_REVERSE);
+ if ((car1<32)||(car1 >= 127))
+ wprintw(window,".");
+ else
+ wprintw(window,"%c", car1);
+ if(car1!=car2)
+ wattroff(window, A_REVERSE);
+ }
+ else
+ wprintw(window," ");
+ }
+ wprintw(window," ");
+ for(j=0; j<0x08;j++)
+ {
+ if(i*0x08+j<lng)
+ {
+ unsigned char car1=*((const unsigned char*)dump_1+i*0x08+j);
+ unsigned char car2=*((const unsigned char*)dump_2+i*0x08+j);
+ if(car1!=car2)
+ wattrset(window, A_REVERSE);
+ wprintw(window,"%02x", car2);
+ if(car1!=car2)
+ wattroff(window, A_REVERSE);
+ if(j%4==(4-1))
+ wprintw(window," ");
+ }
+ else
+ wprintw(window," ");
+ }
+ wprintw(window," ");
+ for(j=0; j<0x08;j++)
+ {
+ if(i*0x08+j<lng)
+ {
+ unsigned char car1=*((const unsigned char*)dump_1+i*0x08+j);
+ unsigned char car2=*((const unsigned char*)dump_2+i*0x08+j);
+ if(car1!=car2)
+ wattrset(window, A_REVERSE);
+ if ((car2<32)||(car2 >= 127))
+ wprintw(window,".");
+ else
+ wprintw(window,"%c", car2);
+ if(car1!=car2)
+ wattroff(window, A_REVERSE);
+ }
+ else
+ wprintw(window," ");
+ }
+ }
+ switch (wmenuSelect(window, INTER_DUMP_Y+1, INTER_DUMP_Y, INTER_DUMP_X, menuDump, 8, options, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu))
+ {
+ case 'p':
+ case 'P':
+ case KEY_UP:
+ if(strchr(options,'N')!=NULL)
+ {
+ menu=0;
+ if(pos>0)
+ pos--;
+ }
+ break;
+ case 'n':
+ case 'N':
+ case KEY_DOWN:
+ if(strchr(options,'N')!=NULL)
+ {
+ menu=1;
+ if(pos<nbr_line-DUMP_MAX_LINES)
+ pos++;
+ }
+ break;
+ case KEY_PPAGE:
+ if(strchr(options,'N')!=NULL)
+ {
+ menu=0;
+ if(pos>DUMP_MAX_LINES-1)
+ pos-=DUMP_MAX_LINES-1;
+ else
+ pos=0;
+ }
+ break;
+ case KEY_NPAGE:
+ if(strchr(options,'N')!=NULL)
+ {
+ menu=1;
+ if(pos<nbr_line-DUMP_MAX_LINES-(DUMP_MAX_LINES-1))
+ pos+=DUMP_MAX_LINES-1;
+ else
+ pos=nbr_line-DUMP_MAX_LINES;
+ }
+ break;
+ case key_ESC:
+ case 'q':
+ case 'Q':
+ done = TRUE;
+ break;
+ }
+ } while(done==FALSE);
+}
+
+int screen_buffer_display(WINDOW *window, const char *options_org, const struct MenuItem *menuItems)
+{
+ unsigned int menu=0;
+ return screen_buffer_display_ext(window,options_org,menuItems,&menu);
+}
+
+#define INTER_ANALYSE_X 0
+#define INTER_ANALYSE_Y 8
+#define INTER_ANALYSE_MENU_X 0
+#define INTER_ANALYSE_MENU_Y (LINES-2)
+#define INTER_MAX_LINES (INTER_ANALYSE_MENU_Y-INTER_ANALYSE_Y-2)
+int screen_buffer_display_ext(WINDOW *window, const char *options_org, const struct MenuItem *menuItems, unsigned int *menu)
+{
+ int i;
+ int first_line_to_display=0;
+ int current_line=0;
+ int done=0;
+ char options[20];
+ struct MenuItem menuDefault[]=
+ {
+ { 'P', "Previous",""},
+ { 'N', "Next","" },
+ { 'Q', "Quit","Quit this section"},
+ { 0, NULL, NULL }
+ };
+ const unsigned int itemLength=8;
+ /* FIXME itemLength */
+ strncpy(options,"Q",sizeof(options));
+ strncat(options,options_org,sizeof(options)-strlen(options));
+ if(intr_buffer_screen[intr_nbr_line][0]!='\0')
+ intr_nbr_line++;
+ /* curses interface */
+ do
+ {
+ int key;
+ wmove(window, INTER_ANALYSE_Y-1, INTER_ANALYSE_X+4);
+ wclrtoeol(window);
+ if(first_line_to_display>0)
+ wprintw(window, "Previous");
+ if(intr_nbr_line>INTER_MAX_LINES && has_colors())
+ {
+ for (i=first_line_to_display; i<intr_nbr_line && (i-first_line_to_display)<INTER_MAX_LINES; i++)
+ {
+ wmove(window,INTER_ANALYSE_Y+i-first_line_to_display,INTER_ANALYSE_X);
+ wclrtoeol(window);
+ if(i==current_line)
+ wattrset(window, A_REVERSE);
+ wprintw(window,"%s",intr_buffer_screen[i]);
+ if(i==current_line)
+ wattroff(window, A_REVERSE);
+ }
+ }
+ else
+ {
+ for (i=first_line_to_display; i<intr_nbr_line && (i-first_line_to_display)<INTER_MAX_LINES; i++)
+ {
+ wmove(window,INTER_ANALYSE_Y+i-first_line_to_display,INTER_ANALYSE_X);
+ wclrtoeol(window);
+ wprintw(window,"%s",intr_buffer_screen[i]);
+ }
+ }
+ wmove(window, INTER_ANALYSE_Y+INTER_MAX_LINES, INTER_ANALYSE_X+4);
+ wclrtoeol(window);
+ if(i<intr_nbr_line)
+ wprintw(window, "Next");
+ key=wmenuSelect_ext(window, INTER_ANALYSE_MENU_Y+1,
+ INTER_ANALYSE_MENU_Y, INTER_ANALYSE_MENU_X,
+ (menuItems!=NULL?menuItems:menuDefault), itemLength, options,
+ MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu,NULL);
+ switch (key)
+ {
+ case key_ESC:
+ case 'q':
+ case 'Q':
+ done = TRUE;
+ break;
+ case 'p':
+ case 'P':
+ case KEY_UP:
+ if(current_line>0)
+ current_line--;
+ break;
+ case 'n':
+ case 'N':
+ case KEY_DOWN:
+ if(current_line<intr_nbr_line-1)
+ current_line++;
+ break;
+ case KEY_PPAGE:
+ if(current_line>INTER_MAX_LINES-1)
+ current_line-=INTER_MAX_LINES-1;
+ else
+ current_line=0;
+ break;
+ case KEY_NPAGE:
+ if(current_line+INTER_MAX_LINES-1 < intr_nbr_line-1)
+ current_line+=INTER_MAX_LINES-1;
+ else
+ current_line=intr_nbr_line-1;
+ break;
+ default:
+ if(strchr(options,toupper(key))!=NULL)
+ return toupper(key);
+ break;
+ }
+ if(current_line<first_line_to_display)
+ first_line_to_display=current_line;
+ if(current_line>=first_line_to_display+INTER_MAX_LINES)
+ first_line_to_display=current_line-INTER_MAX_LINES+1;
+ } while(done!=TRUE);
+ return 0;
+}
+
+void aff_part(WINDOW *window,const unsigned int newline,const disk_t *disk_car,const partition_t *partition)
+{
+ const char *msg;
+ msg=aff_part_aux(newline, disk_car, partition);
+ wprintw(window,"%s",msg);
+}
+
+void aff_LBA2CHS(const disk_t *disk_car, const unsigned long int pos_LBA)
+{
+ unsigned long int tmp;
+ unsigned long int cylinder, head, sector;
+ tmp=disk_car->geom.sectors_per_head;
+ sector=(pos_LBA%tmp)+1;
+ tmp=pos_LBA/tmp;
+ cylinder=tmp / disk_car->geom.heads_per_cylinder;
+ head=tmp % disk_car->geom.heads_per_cylinder;
+ wprintw(stdscr, "%lu/%lu/%lu", cylinder, head, sector);
+}
+
+int ask_YN(WINDOW *window)
+{
+ char res;
+ curs_set(1);
+ wrefresh(window);
+ do
+ {
+ res=toupper(wgetch(window));
+ } while((res!=c_NO)&&(res!=c_YES));
+ curs_set(0);
+ wprintw(window,"%c\n",res);
+ return (res==c_YES);
+}
+
+int ask_confirmation(const char*_format, ...)
+{
+ va_list ap;
+ int res;
+ WINDOW *window=newwin(0,0,0,0); /* full screen */
+ aff_copy(window);
+ va_start(ap,_format);
+ vaff_txt(4, window, _format, ap);
+ va_end(ap);
+ res=ask_YN(window);
+ delwin(window);
+ (void) clearok(stdscr, TRUE);
+#ifdef HAVE_TOUCHWIN
+ touchwin(stdscr);
+#endif
+ return res;
+}
+
+void not_implemented(const char *msg)
+{
+ WINDOW *window=newwin(0,0,0,0); /* full screen */
+ aff_copy(window);
+ wmove(window,7,0);
+ wprintw(window,"Function %s not implemented",msg);
+ log_warning("Function %s not implemented\n",msg);
+ wmove(window,22,0);
+ wattrset(window, A_REVERSE);
+ wprintw(window,"[ Abort ]");
+ wattroff(window, A_REVERSE);
+ wrefresh(window);
+ while(wgetch(window)==ERR);
+ delwin(window);
+ (void) clearok(stdscr, TRUE);
+#ifdef HAVE_TOUCHWIN
+ touchwin(stdscr);
+#endif
+}
+
+#if defined(DJGPP) || defined(__MINGW32__)
+#else
+static SCREEN *screenp=NULL;
+#endif
+
+static char *filename_to_directory(const char *filename)
+{
+ char buf[2048];
+ char *res;
+#ifdef HAVE_READLINK
+ int len;
+ len=readlink(filename,buf,sizeof(buf)-1);
+ if(len>=0)
+ buf[len]='\0';
+ else
+ {
+ strncpy(buf,filename,sizeof(buf)-1);
+ buf[sizeof(buf)-1]='\0';
+ }
+#else
+ strncpy(buf,filename,sizeof(buf)-1);
+ buf[sizeof(buf)-1]='\0';
+#endif
+ res=dirname(buf);
+ if(res==NULL)
+ return NULL;
+#ifdef HAVE_GETCWD
+ if(strcmp(res,".")==0 && getcwd(buf, sizeof(buf)-1)!=NULL)
+ {
+ buf[sizeof(buf)-1]='\0';
+ res=buf;
+ }
+#endif
+#ifdef __CYGWIN__
+ {
+ char beautifull_dst_directory[2048];
+ cygwin_conv_to_win32_path(res, beautifull_dst_directory);
+ return strdup(beautifull_dst_directory);
+ }
+#else
+ return strdup(res);
+#endif
+}
+
+int start_ncurses(const char *prog_name, const char *real_prog_name)
+{
+#if defined(DJGPP) || defined(__MINGW32__)
+ if(initscr()==NULL)
+ {
+ log_critical("initscr() has failed. Exiting\n");
+ printf("initscr() has failed. Exiting\n");
+ printf("Press Enter key to quit.\n");
+ getchar();
+ return 1;
+ }
+#else
+ {
+ int term_overwrite;
+ char *terminfo=filename_to_directory(real_prog_name);
+ for(term_overwrite=0;screenp==NULL && term_overwrite<=1;term_overwrite++)
+ {
+#ifdef HAVE_SETENV
+#if defined(TARGET_BSD)
+ setenv("TERM","cons25",term_overwrite);
+#elif defined(TARGET_LINUX)
+ setenv("TERM","linux",term_overwrite);
+#elif defined(__CYGWIN__)
+ setenv("TERM","cygwin",term_overwrite);
+#elif defined(__OS2__)
+ setenv("TERM","ansi",term_overwrite);
+#elif defined(__APPLE__)
+ setenv("TERM","xterm-color",term_overwrite);
+#endif
+#endif
+ screenp=newterm(NULL,stdout,stdin);
+#ifdef HAVE_SETENV
+ if(screenp==NULL && terminfo!=NULL)
+ {
+ setenv("TERMINFO", terminfo, 1);
+ screenp=newterm(NULL,stdout,stdin);
+ }
+ if(screenp==NULL)
+ {
+ setenv("TERMINFO",".",1);
+ screenp=newterm(NULL,stdout,stdin);
+ }
+ if(screenp==NULL)
+ unsetenv("TERMINFO");
+#endif
+ }
+ if(screenp==NULL)
+ {
+ log_critical("Terminfo file is missing.\n");
+#if defined(__CYGWIN__)
+ printf("The terminfo file '%s\\c\\cygwin' is missing.\n", terminfo);
+#else
+ printf("Terminfo file is missing.\n");
+#endif
+ printf("Extract all files and subdirectories before running the program.\n");
+ printf("Press Enter key to quit.\n");
+ getchar();
+ free(terminfo);
+ return 1;
+ }
+ free(terminfo);
+ }
+#endif
+ noecho();
+#ifndef DJGPP
+ nonl(); /*don't use for Dos version but enter will work with it... dilema */
+#endif
+ /* intrflush(stdscr, FALSE); */
+ cbreak();
+ /* Should solve a problem with users who redefined the colors */
+ if(has_colors())
+ {
+ start_color();
+ init_pair(1, COLOR_RED, COLOR_BLACK);
+ init_pair(2, COLOR_GREEN, COLOR_BLACK);
+ }
+ curs_set(0);
+ {
+ int quit=0;
+ while(LINES>=8 && LINES<24 && quit==0)
+ {
+ aff_copy(stdscr);
+ wmove(stdscr,4,0);
+ wprintw(stdscr,"%s need 24 lines to work.", prog_name);
+ wmove(stdscr,5,0);
+ wprintw(stdscr,"Please enlarge the terminal.");
+ wmove(stdscr,LINES-2,0);
+ wattrset(stdscr, A_REVERSE);
+ wprintw(stdscr,"[ Quit ]");
+ wattroff(stdscr, A_REVERSE);
+ wrefresh(stdscr);
+ switch(wgetch(stdscr))
+ {
+ case 'q':
+ case 'Q':
+ case KEY_ENTER:
+#ifdef PADENTER
+ case PADENTER:
+#endif
+ case '\n':
+ case '\r':
+ quit=1;
+ break;
+ }
+ }
+ }
+ if(LINES<24)
+ {
+ end_ncurses();
+ printf("%s need 24 lines to work.\nPlease enlarge the terminal and restart %s.\n",prog_name,prog_name);
+ log_critical("Terminal has only %u lines\n",LINES);
+ return 1;
+ }
+ return 0;
+}
+
+int end_ncurses()
+{
+ wclear(stdscr);
+ wrefresh(stdscr);
+ nl();
+ endwin();
+#if defined(DJGPP) || defined(__MINGW32__)
+#else
+#ifdef HAVE_DELSCREEN
+ if(screenp!=NULL)
+ delscreen(screenp);
+#endif
+#endif
+ return 0;
+}
+
+char *ask_log_location(const char*filename)
+{
+ static char response[LINE_LENGTH];
+ aff_copy(stdscr);
+ if(filename!=NULL)
+ {
+ wmove(stdscr,6,0);
+ wprintw(stdscr,"Cannot open %s: %s\n",filename, strerror(errno));
+ }
+ wmove(stdscr,8,0);
+ wprintw(stdscr,"Please enter the full log filename or press ");
+ if(has_colors())
+ wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
+ wprintw(stdscr,"Enter");
+ if(has_colors())
+ wbkgdset(stdscr,' ' | COLOR_PAIR(0));
+ wmove(stdscr,9,0);
+ wprintw(stdscr,"to abort log file creation.\n");
+ if (get_string(response, LINE_LENGTH, NULL) > 0)
+ return response;
+ return NULL;
+}
+
+int check_enter_key_or_s(WINDOW *window)
+{
+ switch(wgetch_nodelay(window))
+ {
+ case KEY_ENTER:
+#ifdef PADENTER
+ case PADENTER:
+#endif
+ case '\n':
+ case '\r':
+ case 's':
+ case 'S':
+ return 1;
+ }
+ return 0;
+}
+
+int interface_partition_type_ncurses(disk_t *disk_car)
+{
+ /* arch_list must match the order from menuOptions */
+ const arch_fnct_t *arch_list[]={&arch_i386, &arch_gpt, &arch_mac, &arch_none, &arch_sun, &arch_xbox, NULL};
+ unsigned int menu;
+ for(menu=0;arch_list[menu]!=NULL && disk_car->arch!=arch_list[menu];menu++);
+ if(arch_list[menu]==NULL)
+ {
+ menu=0;
+ disk_car->arch=arch_list[menu];
+ }
+ /* ncurses interface */
+ {
+ int car;
+ int real_key;
+ struct MenuItem menuOptions[]=
+ {
+ { 'I', arch_i386.part_name, "Intel/PC partition" },
+ { 'G', arch_gpt.part_name, "EFI GPT partition map (Mac i386, some x86_64...)" },
+ { 'M', arch_mac.part_name, "Apple partition map" },
+ { 'N', arch_none.part_name, "Non partitioned media" },
+ { 'S', arch_sun.part_name, "Sun Solaris partition"},
+ { 'X', arch_xbox.part_name, "XBox partition"},
+ { 'Q', "Return", "Return to disk selection"},
+ { 0, NULL, NULL }
+ };
+ aff_copy(stdscr);
+ wmove(stdscr,5,0);
+ wprintw(stdscr,"%s\n",disk_car->description_short(disk_car));
+ wmove(stdscr,INTER_PARTITION_Y-1,0);
+ wprintw(stdscr,"Please select the partition table type, press Enter when done.");
+ wmove(stdscr,20,0);
+ wprintw(stdscr,"Note: Do NOT select 'None' for media with only a single partition. It's very");
+ wmove(stdscr,21,0);
+ wprintw(stdscr,"rare for a drive to be 'Non-partitioned'.");
+ car=wmenuSelect_ext(stdscr, 23, INTER_PARTITION_Y, INTER_PARTITION_X, menuOptions, 7, "IGMNSXQ", MENU_BUTTON | MENU_VERT | MENU_VERT_WARN, &menu,&real_key);
+ switch(car)
+ {
+ case 'i':
+ case 'I':
+ disk_car->arch=&arch_i386;
+ break;
+ case 'g':
+ case 'G':
+ disk_car->arch=&arch_gpt;
+ break;
+ case 'm':
+ case 'M':
+ disk_car->arch=&arch_mac;
+ break;
+ case 'n':
+ case 'N':
+ disk_car->arch=&arch_none;
+ break;
+ case 's':
+ case 'S':
+ disk_car->arch=&arch_sun;
+ break;
+ case 'x':
+ case 'X':
+ disk_car->arch=&arch_xbox;
+ break;
+ case 'q':
+ case 'Q':
+ return 1;
+ }
+ }
+ autoset_unit(disk_car);
+ return 0;
+}
+
+void screen_buffer_to_interface()
+{
+ {
+ int i;
+ int pos=intr_nbr_line-DUMP_MAX_LINES<0?0:intr_nbr_line-DUMP_MAX_LINES;
+ if(intr_nbr_line<MAX_LINES && intr_buffer_screen[intr_nbr_line][0]!='\0')
+ intr_nbr_line++;
+ /* curses interface */
+ for (i=pos; i<intr_nbr_line && i<MAX_LINES && (i-pos)<DUMP_MAX_LINES; i++)
+ {
+ wmove(stdscr,DUMP_Y+1+i-pos,DUMP_X);
+ wclrtoeol(stdscr);
+ wprintw(stdscr,"%s",intr_buffer_screen[i]);
+ }
+ wrefresh(stdscr);
+ }
+}
+
+int vaff_txt(int line, WINDOW *window, const char *_format, va_list ap)
+{
+ char buffer[1024];
+ int i;
+ vsnprintf(buffer,sizeof(buffer),_format,ap);
+ buffer[sizeof(buffer)-1]='\0';
+ for(i=0;buffer[i]!='\0';)
+ {
+ char buffer2[1024];
+ int j,end=i,end2=i;
+ for(j=i;buffer[j]!='\0' && (j-i)<COLUMNS;j++)
+ if((buffer[j]==' ' || buffer[j]=='\t') && buffer[j+1]!='?' && buffer[j+1]!='[')
+ {
+ end=j;
+ end2=j;
+ }
+ else if(buffer[j]=='\n')
+ {
+ end=j;
+ end2=j;
+ break;
+ }
+ else if(buffer[j]=='\\' || buffer[j]=='/')
+ end2=j;
+ if(end2>end && end-i<COLUMNS*3/4)
+ end=end2;
+ if(end==i)
+ end=j-1;
+ if(buffer[j]=='\0')
+ end=j;
+ wmove(window,line,0);
+ line++;
+ memcpy(buffer2,&buffer[i],end-i+1);
+ buffer2[end-i+1]='\0';
+ waddstr(window,buffer2);
+ for(i=end;buffer[i]==' ' || buffer[i]=='\t' || buffer[i]=='\n'; i++);
+ }
+ return line;
+}
+
+void display_message(const char*msg)
+{
+ int pipo=0;
+ static struct MenuItem menuGeometry[]=
+ {
+ { 'Q', "Ok", "" },
+ { 0, NULL, NULL }
+ };
+ WINDOW *window=newwin(0,0,0,0); /* full screen */
+ log_info("%s",msg);
+ aff_copy(window);
+ mvwaddstr(window,5,0,msg);
+ wmenuSimple(window,menuGeometry, pipo);
+ delwin(window);
+ (void) clearok(stdscr, TRUE);
+#ifdef HAVE_TOUCHWIN
+ touchwin(stdscr);
+#endif
+}
+
+#else
+#include <stdio.h>
+#include "log.h"
+#include "intrfn.h"
+
+void display_message(const char*msg)
+{
+ log_info("%s",msg);
+}
+#endif
+
+
diff --git a/src/intrfn.h b/src/intrfn.h
index e72330b..603d5b1 100644
--- a/src/intrfn.h
+++ b/src/intrfn.h
@@ -20,6 +20,10 @@
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifdef HAVE_NCURSES
#ifdef HAVE_NCURSES_H
#include <ncurses.h>
@@ -46,4 +50,13 @@ int wmenuSelect(WINDOW *window, const int yinfo, int y, int x, const struct Menu
int wmenuSimple(WINDOW *window, const struct MenuItem *menuItems, unsigned int menuDefault);
int start_ncurses(const char *prog_name, const char *real_prog_name);
int end_ncurses(void);
+int interface_partition_type_ncurses(disk_t *disk_car);
+int vaff_txt(int line, WINDOW *window, const char *_format, va_list ap) __attribute__((format(printf, 3, 0)));
+char *ask_log_location(const char*filename);
+#endif
+
+void display_message(const char*msg);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
#endif
diff --git a/src/io_redir.c b/src/io_redir.c
index 006061a..7e57f8e 100644
--- a/src/io_redir.c
+++ b/src/io_redir.c
@@ -23,6 +23,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
diff --git a/src/log.c b/src/log.c
index d011bd1..81bbb81 100644
--- a/src/log.c
+++ b/src/log.c
@@ -42,8 +42,6 @@
#include "types.h"
#include "common.h"
#include "log.h"
-#include "intrf.h" /* ask_log_location */
-#include "fnctdsk.h"
static FILE *log_handle=NULL;
static int f_status=0;
@@ -58,62 +56,47 @@ int log_set_levels(const unsigned int levels)
return old_levels;
}
-int log_open(const char*default_filename, const int mode, const int ncurses_interface, const char *prog_name, int argc, char**argv)
+FILE *log_open(const char*default_filename, const int mode)
{
- const char*filename=default_filename;
- if(mode!=TD_LOG_CREATE && mode!=TD_LOG_APPEND)
- return mode;
- log_handle=fopen(filename,(mode==TD_LOG_CREATE?"w":"a"));
- if(log_handle==NULL && ncurses_interface==0)
- {
- printf("Can't create %s file\n", filename);
- }
+ log_handle=fopen(default_filename,(mode==TD_LOG_CREATE?"w":"a"));
+ return log_handle;
+}
+
#if defined(__CYGWIN__) || defined(__MINGW32__)
- if(log_handle==NULL)
- {
- char *path;
- path = getenv("USERPROFILE");
- if (path == NULL)
- path = getenv("HOMEPATH");
- if(path!=NULL)
- {
- FILE*handle;
- filename=(char*)MALLOC(strlen(path)+strlen(default_filename)+2);
- strcpy(filename, path);
- strcat(filename, "\\");
- strcat(filename, default_filename);
- handle=fopen(filename,(mode==TD_LOG_CREATE?"w":"a"));
- /* WARN: filename: memory leak */
- }
- }
-#endif
- if(log_handle==NULL && ncurses_interface==0)
- {
- return mode;
- }
- while(log_handle==NULL)
- {
- filename=ask_log_location(filename);
- if(filename==NULL)
- return TD_LOG_REFUSED;
- log_handle=fopen(filename,(mode==TD_LOG_CREATE?"w":"a"));
- }
- {
- int i;
- time_t my_time;
-#ifdef HAVE_DUP2
- dup2(fileno(log_handle),2);
-#endif
- my_time=time(NULL);
- fprintf(log_handle,"\n\n%s",ctime(&my_time));
- fprintf(log_handle,"Command line: %s", prog_name);
- for(i=1;i<argc;i++)
- fprintf(log_handle," %s", argv[i]);
- fprintf(log_handle,"\n\n");
- fflush(log_handle);
- }
- return TD_LOG_DONE;
+FILE *log_open_default(const char*default_filename, const int mode)
+{
+ char*filename;
+ char *path;
+ path = getenv("USERPROFILE");
+ if (path == NULL)
+ path = getenv("HOMEPATH");
+ if(path == NULL)
+ return NULL;
+ filename=(char*)MALLOC(strlen(path)+strlen(default_filename)+2);
+ strcpy(filename, path);
+ strcat(filename, "\\");
+ strcat(filename, default_filename);
+ log_handle=fopen(filename,(mode==TD_LOG_CREATE?"w":"a"));
+ free(filename);
+ return log_handle;
+}
+#else
+FILE *log_open_default(const char*default_filename, const int mode)
+{
+ char*filename;
+ char *path;
+ path = getenv("HOME");
+ if(path == NULL)
+ return NULL;
+ filename=(char*)MALLOC(strlen(path)+strlen(default_filename)+2);
+ strcpy(filename, path);
+ strcat(filename, "/");
+ strcat(filename, default_filename);
+ log_handle=fopen(filename,(mode==TD_LOG_CREATE?"w":"a"));
+ free(filename);
+ return log_handle;
}
+#endif
int log_flush(void)
{
@@ -270,15 +253,3 @@ void dump2_log(const void *dump_1, const void *dump_2, const unsigned int lng)
log_info("\n");
}
}
-
-void log_partition(const disk_t *disk_car,const partition_t *partition)
-{
- const char *msg;
- char buffer_part_size[100];
- msg=aff_part_aux(AFF_PART_ORDER|AFF_PART_STATUS, disk_car, partition);
- log_info("%s",msg);
- if(partition->info[0]!='\0')
- log_info("\n %s, %s",partition->info,size_to_unit(partition->part_size,buffer_part_size));
- log_info("\n");
-}
-
diff --git a/src/log.h b/src/log.h
index ae1789b..e68abf7 100644
--- a/src/log.h
+++ b/src/log.h
@@ -2,7 +2,7 @@
File: log.h
- Copyright (C) 2007 Christophe GRENIER <grenier@cgsecurity.org>
+ Copyright (C) 2007-2009 Christophe GRENIER <grenier@cgsecurity.org>
This software is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,16 +21,18 @@
*/
#ifndef _LOG_H
#define _LOG_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
int log_set_levels(const unsigned int levels);
-int log_open(const char*default_filename, const int mode, const int ncurses_interface, const char *prog_name, int argc, char**argv);
+FILE *log_open(const char*default_filename, const int mode);
+FILE *log_open_default(const char*default_filename, const int mode);
int log_flush(void);
int log_close(void);
int log_redirect(unsigned int level, const char *format, ...) __attribute__((format(printf, 2, 3)));
void dump_log(const void *nom_dump,unsigned int lng);
void dump2_log(const void *dump_1, const void *dump_2,const unsigned int lng);
-#ifdef _COMMON_H
-void log_partition(const disk_t *disk_car,const partition_t *partition);
-#endif
#define TD_LOG_NONE 0
#define TD_LOG_CREATE 1
@@ -59,4 +61,8 @@ void log_partition(const disk_t *disk_car,const partition_t *partition);
#define log_error(FORMAT, ARGS...) log_redirect(LOG_LEVEL_ERROR,FORMAT,##ARGS)
#define log_perror(FORMAT, ARGS...) log_redirect(LOG_LEVEL_PERROR,FORMAT,##ARGS)
#define log_critical(FORMAT, ARGS...) log_redirect(LOG_LEVEL_CRITICAL,FORMAT,##ARGS)
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
#endif
diff --git a/src/log_part.c b/src/log_part.c
new file mode 100644
index 0000000..5d4f9a1
--- /dev/null
+++ b/src/log_part.c
@@ -0,0 +1,43 @@
+/*
+
+ File: log_part.c
+
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include "types.h"
+#include "common.h"
+#include "fnctdsk.h"
+#include "log.h"
+#include "log_part.h"
+#include "intrf.h" /* aff_part_aux */
+
+void log_partition(const disk_t *disk_car, const partition_t *partition)
+{
+ const char *msg;
+ char buffer_part_size[100];
+ msg=aff_part_aux(AFF_PART_ORDER|AFF_PART_STATUS, disk_car, partition);
+ log_info("%s",msg);
+ if(partition->info[0]!='\0')
+ log_info("\n %s, %s",partition->info,size_to_unit(partition->part_size,buffer_part_size));
+ log_info("\n");
+}
diff --git a/src/log_part.h b/src/log_part.h
new file mode 100644
index 0000000..52ea10a
--- /dev/null
+++ b/src/log_part.h
@@ -0,0 +1,33 @@
+/*
+
+ File: log_part.h
+
+ Copyright (C) 2007-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifndef _LOG_PART_H
+#define _LOG_PART_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void log_partition(const disk_t *disk_car,const partition_t *partition);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
+#endif
diff --git a/src/msdos.c b/src/msdos.c
index 0bc864c..d641e5b 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -23,6 +23,7 @@
#include <config.h>
#endif
#ifdef DJGPP
+#include <stdio.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
diff --git a/src/nodisk.c b/src/nodisk.c
new file mode 100644
index 0000000..47d0a38
--- /dev/null
+++ b/src/nodisk.c
@@ -0,0 +1,87 @@
+/*
+
+ File: nodisk.c
+
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_NCURSES
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include "types.h"
+#include "common.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "nodisk.h"
+
+int intrf_no_disk_ncurses(const char *prog_name)
+{
+ aff_copy(stdscr);
+ wmove(stdscr,4,0);
+ wprintw(stdscr," %s is free software, and",prog_name);
+ wmove(stdscr,5,0);
+ wprintw(stdscr,"comes with ABSOLUTELY NO WARRANTY.");
+ wmove(stdscr,7,0);
+ wprintw(stdscr,"No harddisk found\n");
+#if defined(__CYGWIN__) || defined(__MINGW32__)
+ wmove(stdscr,8,0);
+ wprintw(stdscr,"You need to be administrator to use %s.\n", prog_name);
+ wmove(stdscr,9,0);
+ wprintw(stdscr,"Under Win9x, use the DOS version instead.\n");
+ wmove(stdscr,10,0);
+ wprintw(stdscr,"Under Vista, select %s, right-click and choose \"Run as administrator\".\n", prog_name);
+#elif defined(DJGPP)
+#else
+#ifdef HAVE_GETEUID
+ if(geteuid()!=0)
+ {
+ wmove(stdscr,8,0);
+ wprintw(stdscr,"You need to be root to use %s.\n", prog_name);
+#ifdef SUDO_BIN
+ {
+ static const struct MenuItem menuSudo[]=
+ {
+ {'S',"Sudo","Use the sudo command to restart as root"},
+ {'Q',"Quit",""},
+ {0,NULL,NULL}
+ };
+ unsigned int menu=0;
+ int command;
+ command = wmenuSelect_ext(stdscr,23, 20, 0, menuSudo, 8,
+ "SQ", MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
+ if(command=='s' || command=='S')
+ return 1;
+ return 0;
+ }
+#endif
+ }
+#endif
+#endif
+ wmove(stdscr,22,0);
+ wattrset(stdscr, A_REVERSE);
+ wprintw(stdscr,"[ Quit ]");
+ wattroff(stdscr, A_REVERSE);
+ wrefresh(stdscr);
+ while(wgetch(stdscr)==ERR);
+ return 0;
+}
+#endif
diff --git a/src/nodisk.h b/src/nodisk.h
new file mode 100644
index 0000000..71f899d
--- /dev/null
+++ b/src/nodisk.h
@@ -0,0 +1,29 @@
+/*
+
+ File: nodisk.h
+
+ Copyright (C) 2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+int intrf_no_disk_ncurses(const char *prog_name);
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
+
diff --git a/src/ntfs_adv.c b/src/ntfs_adv.c
index 682a0e0..fc736f3 100644
--- a/src/ntfs_adv.c
+++ b/src/ntfs_adv.c
@@ -23,6 +23,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
@@ -40,6 +41,7 @@
#include "lang.h"
#include "io_redir.h"
#include "log.h"
+#include "log_part.h"
#define INTER_NTFS_X 0
#define INTER_NTFS_Y 23
@@ -131,7 +133,11 @@ static void menu_write_ntfs_boot_sector_cli(disk_t *disk_car, partition_t *parti
else if(strncmp(*current_cmd,"write",5)==0)
{
(*current_cmd)+=5;
- if(no_confirm!=0 || ask_confirmation("Write new NTFS boot sector, confirm ? (Y/N)")!=0)
+ if(no_confirm!=0
+#ifdef HAVE_NCURSES
+ || ask_confirmation("Write new NTFS boot sector, confirm ? (Y/N)")!=0
+#endif
+ )
{
log_info("Write new boot!\n");
/* Write boot sector and backup boot sector */
@@ -199,6 +205,7 @@ static void menu_write_ntfs_boot_sector_ncurses(disk_t *disk_car, partition_t *p
{
case 'w':
case 'W':
+#ifdef HAVE_NCURSES
if(strchr(options,'W')!=NULL && ask_confirmation("Write new NTFS boot sector, confirm ? (Y/N)")!=0)
{
log_info("Write new boot!\n");
@@ -213,6 +220,7 @@ static void menu_write_ntfs_boot_sector_ncurses(disk_t *disk_car, partition_t *p
}
disk_car->sync(disk_car);
}
+#endif
return;
case 'd':
case 'D':
@@ -472,7 +480,11 @@ int rebuild_NTFS_BS(disk_t *disk_car, partition_t *partition, const int verbose,
{
log_info("ntfs_find_mft: mft_lcn %lu\n",(long unsigned int)mft_lcn);
log_info("ntfs_find_mft: mftmirr_lcn %lu\n",(long unsigned int)mftmirr_lcn);
- if(expert==0 || ask_confirmation("Use MFT from %lu, confirm ? (Y/N)",(long unsigned int)mft_lcn)!=0)
+ if(expert==0
+#ifdef HAVE_NCURSES
+ || ask_confirmation("Use MFT from %lu, confirm ? (Y/N)",(long unsigned int)mft_lcn)!=0
+#endif
+ )
ind_stop=1;
}
else if(tmp==3)
@@ -522,7 +534,11 @@ int rebuild_NTFS_BS(disk_t *disk_car, partition_t *partition, const int verbose,
{
log_info("ntfs_find_mft: mft_lcn %lu\n",(long unsigned int)mft_lcn);
log_info("ntfs_find_mft: mftmirr_lcn %lu\n",(long unsigned int)mftmirr_lcn);
- if(expert==0 || ask_confirmation("Use MFT from %lu, confirm ? (Y/N)",(long unsigned int)mft_lcn)!=0)
+ if(expert==0
+#ifdef HAVE_NCURSES
+ || ask_confirmation("Use MFT from %lu, confirm ? (Y/N)",(long unsigned int)mft_lcn)!=0
+#endif
+ )
ind_stop=1;
}
else if(tmp==3)
diff --git a/src/ntfs_udl.c b/src/ntfs_udl.c
index 976104d..78a0786 100644
--- a/src/ntfs_udl.c
+++ b/src/ntfs_udl.c
@@ -28,6 +28,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_FEATURES_H
#include <features.h>
#endif
@@ -68,6 +69,7 @@
#include "list.h"
#include "log.h"
+#include "log_part.h"
#include "ntfs_udl.h"
#include "intrf.h"
#include "intrfn.h"
@@ -92,6 +94,7 @@
#include "ntfs_dir.h"
#include "ntfs_utl.h"
#include "dir.h"
+#include "askloc.h"
extern const char *monstr[];
diff --git a/src/ntfs_utl.c b/src/ntfs_utl.c
index a34e932..c4e3582 100644
--- a/src/ntfs_utl.c
+++ b/src/ntfs_utl.c
@@ -27,6 +27,7 @@
#include <config.h>
#endif
#ifdef HAVE_LIBNTFS
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
diff --git a/src/ntfsp.c b/src/ntfsp.c
index b7b4898..7a12ac8 100644
--- a/src/ntfsp.c
+++ b/src/ntfsp.c
@@ -42,12 +42,12 @@
#include "ntfsp.h"
#endif
#include "intrf.h"
-#include "intrfn.h"
#include "dir.h"
#include "ntfs.h"
#include "ntfs_dir.h"
#include "ntfs_inc.h"
#include "log.h"
+#include "log_part.h"
#ifdef HAVE_LIBNTFS
#define SIZEOF_BUFFER ((const unsigned int)512)
@@ -59,27 +59,8 @@ unsigned int ntfs_remove_used_space(disk_t *disk_car,const partition_t *partitio
{
case -2:
case -1:
- screen_buffer_reset();
- {
-#ifdef HAVE_NCURSES
- WINDOW *window;
- window=newwin(0,0,0,0); /* full screen */
- aff_copy(window);
- wmove(window,4,0);
- aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
-#endif
log_partition(disk_car,partition);
- screen_buffer_add("Can't open filesystem. Filesystem seems damaged.\n");
- screen_buffer_to_log();
-#ifdef HAVE_NCURSES
- screen_buffer_display(window,"",NULL);
- delwin(window);
- (void) clearok(stdscr, TRUE);
-#ifdef HAVE_TOUCHWIN
- touchwin(stdscr);
-#endif
-#endif
- }
+ log_error("Can't open filesystem. Filesystem seems damaged.\n");
return 0;
}
{
diff --git a/src/partauto.c b/src/partauto.c
index 9f3accb..50c204b 100644
--- a/src/partauto.c
+++ b/src/partauto.c
@@ -23,6 +23,7 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
diff --git a/src/partgpt.c b/src/partgpt.c
index 5e04ee5..9772c4a 100644
--- a/src/partgpt.c
+++ b/src/partgpt.c
@@ -24,7 +24,8 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-
+
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -46,7 +47,6 @@
#include "fnctdsk.h"
#include "lang.h"
#include "intrf.h"
-#include "intrfn.h"
#include "chgtype.h"
#include "partgpt.h"
#include "savehdr.h"
@@ -61,18 +61,19 @@
#include "rfs.h"
#include "xfs.h"
#include "log.h"
+#include "log_part.h"
#include "guid_cmp.h"
#include "guid_cpy.h"
#include "unicode.h"
#include "crc.h"
-/* #include "partnone.h" */
+#include "partgptn.h"
+
extern const arch_fnct_t arch_i386;
static int check_part_gpt(disk_t *disk_car, const int verbose,partition_t *partition,const int saveheader);
static list_part_t *read_part_gpt(disk_t *disk_car, const int verbose, const int saveheader);
static int write_part_gpt(disk_t *disk_car, const list_part_t *list_part, const int ro , const int verbose, const int align);
static list_part_t *init_part_order_gpt(const disk_t *disk_car, list_part_t *list_part);
-static list_part_t *add_partition_gpt(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd);
static void set_next_status_gpt(const disk_t *disk_car, partition_t *partition);
static int test_structure_gpt(list_part_t *list_part);
static int is_part_known_gpt(const partition_t *partition);
@@ -134,7 +135,6 @@ arch_fnct_t arch_gpt=
.get_geometry_from_mbr=NULL,
.check_part=check_part_gpt,
.write_MBR_code=NULL,
- .add_partition=add_partition_gpt,
.set_prev_status=set_next_status_gpt,
.set_next_status=set_next_status_gpt,
.test_structure=test_structure_gpt,
@@ -527,7 +527,7 @@ static list_part_t *init_part_order_gpt(const disk_t *disk_car, list_part_t *lis
return list_part;
}
-static list_part_t *add_partition_gpt_cli(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
+list_part_t *add_partition_gpt_cli(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
{
partition_t *new_partition=partition_new(&arch_gpt);
new_partition->part_offset=disk_car->sector_size;
@@ -565,7 +565,7 @@ static list_part_t *add_partition_gpt_cli(disk_t *disk_car,list_part_t *list_par
else if(strncmp(*current_cmd,"T,",2)==0)
{
(*current_cmd)+=2;
- change_part_type(disk_car,new_partition,current_cmd);
+ change_part_type_cli(disk_car,new_partition,current_cmd);
}
else if(new_partition->part_size>0 && guid_cmp(new_partition->part_type_gpt, GPT_ENT_TYPE_UNUSED)!=0)
{
@@ -589,106 +589,6 @@ static list_part_t *add_partition_gpt_cli(disk_t *disk_car,list_part_t *list_par
}
}
-#ifdef HAVE_NCURSES
-static list_part_t *add_partition_gpt_ncurses(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
-{
- int position=0;
- int done = FALSE;
- partition_t *new_partition=partition_new(&arch_gpt);
- new_partition->part_offset=disk_car->sector_size;
- new_partition->part_size=disk_car->disk_size-disk_car->sector_size;
- while (done==FALSE)
- {
- int command;
- static struct MenuItem menuGeometry[]=
- {
- { 's', "Sector", "Change starting sector" },
- { 'S', "Sector", "Change ending sector" },
- { 'T' ,"Type", "Change partition type"},
- { 'd', "Done", "" },
- { 0, NULL, NULL }
- };
- aff_copy(stdscr);
- wmove(stdscr,4,0);
- wprintw(stdscr,"%s",disk_car->description(disk_car));
- wmove(stdscr,10, 0);
- wclrtoeol(stdscr);
- aff_part(stdscr, AFF_PART_BASE, disk_car, new_partition);
- wmove(stdscr,INTER_GEOM_Y, INTER_GEOM_X);
- wclrtoeol(stdscr);
- wrefresh(stdscr);
- command=wmenuSimple(stdscr,menuGeometry, position);
- switch (command) {
- case 's':
- {
- uint64_t part_offset;
- part_offset=new_partition->part_offset;
- wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
- new_partition->part_offset=(uint64_t)ask_number(
- new_partition->part_offset/disk_car->sector_size,
- 1,
- (disk_car->disk_size-1)/disk_car->sector_size,
- "Enter the starting sector ") *
- (uint64_t)disk_car->sector_size;
- new_partition->part_size=new_partition->part_size + part_offset - new_partition->part_offset;
- position=1;
- }
- break;
- case 'S':
- wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
- new_partition->part_size=(uint64_t)ask_number(
- (new_partition->part_offset+new_partition->part_size-1)/disk_car->sector_size,
- new_partition->part_offset/disk_car->sector_size,
- (disk_car->disk_size-1)/disk_car->sector_size,
- "Enter the ending sector ") *
- (uint64_t)disk_car->sector_size +
- disk_car->sector_size - new_partition->part_offset;
- position=2;
- break;
- case 'T':
- case 't':
- change_part_type(disk_car,new_partition, current_cmd);
- position=3;
- break;
- case key_ESC:
- case 'd':
- case 'D':
- case 'q':
- case 'Q':
- done = TRUE;
- break;
- }
- }
- if(new_partition->part_size>0 && guid_cmp(new_partition->part_type_gpt, GPT_ENT_TYPE_UNUSED)!=0)
- {
- int insert_error=0;
- list_part_t *new_list_part=insert_new_partition(list_part, new_partition, 0, &insert_error);
- if(insert_error>0)
- {
- free(new_partition);
- return new_list_part;
- }
- new_partition->status=STATUS_PRIM;
- if(test_structure_gpt(list_part)!=0)
- new_partition->status=STATUS_DELETED;
- return new_list_part;
- }
- free(new_partition);
- return list_part;
-}
-#endif
-
-static list_part_t *add_partition_gpt(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
-{
- if(*current_cmd!=NULL)
- return add_partition_gpt_cli(disk_car, list_part, verbose, current_cmd);
-#ifdef HAVE_NCURSES
- return add_partition_gpt_ncurses(disk_car, list_part, verbose, current_cmd);
-#else
- return list_part;
-#endif
-}
-
static void set_next_status_gpt(const disk_t *disk_car, partition_t *partition)
{
if(partition->status==STATUS_DELETED)
diff --git a/src/partgpt.h b/src/partgpt.h
index 9de52c9..801e478 100644
--- a/src/partgpt.h
+++ b/src/partgpt.h
@@ -21,6 +21,9 @@
*/
#ifndef _PARTGPT_H
#define _PARTGPT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
struct gpt_hdr
{
@@ -59,5 +62,9 @@ struct systypes_gtp {
const char *name;
};
+list_part_t *add_partition_gpt_cli(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd);
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
#endif /* _PARTGPT_H */
diff --git a/src/partgptn.c b/src/partgptn.c
new file mode 100644
index 0000000..729a67f
--- /dev/null
+++ b/src/partgptn.c
@@ -0,0 +1,160 @@
+/*
+
+ File: partgptn.c
+
+ Copyright (C) 2007-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_NCURSES
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <ctype.h> /* tolower */
+#include "types.h"
+#if defined(HAVE_UUID_H)
+#include <uuid.h>
+#elif defined(HAVE_UUID_UUID_H)
+#include <uuid/uuid.h>
+#endif
+#if defined(HAVE_SYS_UUID_H)
+#include <sys/uuid.h>
+#endif
+#include "common.h"
+#include "testdisk.h"
+#include "fnctdsk.h"
+#include "lang.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "chgtypen.h"
+#include "partgpt.h"
+#include "savehdr.h"
+#include "cramfs.h"
+#include "ext2.h"
+#include "fat.h"
+#include "hfs.h"
+#include "hfsp.h"
+#include "jfs_superblock.h"
+#include "jfs.h"
+#include "ntfs.h"
+#include "rfs.h"
+#include "xfs.h"
+#include "log.h"
+#include "log_part.h"
+#include "guid_cmp.h"
+#include "guid_cpy.h"
+#include "unicode.h"
+#include "crc.h"
+#include "partgptn.h"
+
+extern const arch_fnct_t arch_gpt;
+
+list_part_t *add_partition_gpt_ncurses(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
+{
+ int position=0;
+ int done = FALSE;
+ partition_t *new_partition=partition_new(&arch_gpt);
+ new_partition->part_offset=disk_car->sector_size;
+ new_partition->part_size=disk_car->disk_size-disk_car->sector_size;
+ while (done==FALSE)
+ {
+ int command;
+ static struct MenuItem menuGeometry[]=
+ {
+ { 's', "Sector", "Change starting sector" },
+ { 'S', "Sector", "Change ending sector" },
+ { 'T' ,"Type", "Change partition type"},
+ { 'd', "Done", "" },
+ { 0, NULL, NULL }
+ };
+ aff_copy(stdscr);
+ wmove(stdscr,4,0);
+ wprintw(stdscr,"%s",disk_car->description(disk_car));
+ wmove(stdscr,10, 0);
+ wclrtoeol(stdscr);
+ aff_part(stdscr, AFF_PART_BASE, disk_car, new_partition);
+ wmove(stdscr,INTER_GEOM_Y, INTER_GEOM_X);
+ wclrtoeol(stdscr);
+ wrefresh(stdscr);
+ command=wmenuSimple(stdscr,menuGeometry, position);
+ switch (command) {
+ case 's':
+ {
+ uint64_t part_offset;
+ part_offset=new_partition->part_offset;
+ wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
+ new_partition->part_offset=(uint64_t)ask_number(
+ new_partition->part_offset/disk_car->sector_size,
+ 1,
+ (disk_car->disk_size-1)/disk_car->sector_size,
+ "Enter the starting sector ") *
+ (uint64_t)disk_car->sector_size;
+ new_partition->part_size=new_partition->part_size + part_offset - new_partition->part_offset;
+ position=1;
+ }
+ break;
+ case 'S':
+ wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
+ new_partition->part_size=(uint64_t)ask_number(
+ (new_partition->part_offset+new_partition->part_size-1)/disk_car->sector_size,
+ new_partition->part_offset/disk_car->sector_size,
+ (disk_car->disk_size-1)/disk_car->sector_size,
+ "Enter the ending sector ") *
+ (uint64_t)disk_car->sector_size +
+ disk_car->sector_size - new_partition->part_offset;
+ position=2;
+ break;
+ case 'T':
+ case 't':
+ change_part_type(disk_car,new_partition, current_cmd);
+ position=3;
+ break;
+ case key_ESC:
+ case 'd':
+ case 'D':
+ case 'q':
+ case 'Q':
+ done = TRUE;
+ break;
+ }
+ }
+ if(new_partition->part_size>0 && guid_cmp(new_partition->part_type_gpt, GPT_ENT_TYPE_UNUSED)!=0)
+ {
+ int insert_error=0;
+ list_part_t *new_list_part=insert_new_partition(list_part, new_partition, 0, &insert_error);
+ if(insert_error>0)
+ {
+ free(new_partition);
+ return new_list_part;
+ }
+ new_partition->status=STATUS_PRIM;
+ if(arch_gpt.test_structure(list_part)!=0)
+ new_partition->status=STATUS_DELETED;
+ return new_list_part;
+ }
+ free(new_partition);
+ return list_part;
+}
+#endif
diff --git a/src/partgptn.h b/src/partgptn.h
new file mode 100644
index 0000000..adef9a5
--- /dev/null
+++ b/src/partgptn.h
@@ -0,0 +1,30 @@
+/*
+
+ File: partgptn.h
+
+ Copyright (C) 2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+list_part_t *add_partition_gpt_ncurses(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/parti386.c b/src/parti386.c
index 144049a..8b4a182 100644
--- a/src/parti386.c
+++ b/src/parti386.c
@@ -25,6 +25,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -38,7 +39,6 @@
#include "fnctdsk.h"
#include "lang.h"
#include "intrf.h"
-#include "intrfn.h"
#include "chgtype.h"
#include "savehdr.h"
#include "bfs.h"
@@ -61,9 +61,9 @@
#include "ufs.h"
#include "xfs.h"
#include "log.h"
+#include "parti386.h"
static int is_extended(const unsigned int part_type);
-static int can_be_ext(const disk_t *disk_car, const partition_t *partition);
static int test_structure_i386(list_part_t *list_part);
#define pt_offset_const(b, n) ((const struct partition_dos *)((b) + 0x1be + \
(n) * sizeof(struct partition_dos)))
@@ -106,7 +106,6 @@ static int write_part_i386(disk_t *disk_car, const list_part_t *list_part, const
static list_part_t *init_part_order_i386(const disk_t *disk_car, list_part_t *list_part);
static int write_MBR_code_i386(disk_t *disk_car);
static int write_MBR_code_i386_aux(unsigned char *buffer);
-static list_part_t *add_partition_i386(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd);
static void set_prev_status_i386(const disk_t *disk_car, partition_t *partition);
static void set_next_status_i386(const disk_t *disk_car, partition_t *partition);
static int set_part_type_i386(partition_t *partition, unsigned int part_type);
@@ -228,7 +227,6 @@ arch_fnct_t arch_i386= {
.get_geometry_from_mbr=get_geometry_from_i386mbr,
.check_part=check_part_i386,
.write_MBR_code=write_MBR_code_i386,
- .add_partition=add_partition_i386,
.set_prev_status=set_prev_status_i386,
.set_next_status=set_next_status_i386,
.test_structure=test_structure_i386,
@@ -1124,7 +1122,7 @@ static void log_dos_entry(const disk_t *disk_car, const struct partition_dos *en
(long unsigned)get_start_sect(entree),(long unsigned)get_nr_sects(entree));
}
-static int can_be_ext(const disk_t *disk_car, const partition_t *partition)
+int parti386_can_be_ext(const disk_t *disk_car, const partition_t *partition)
{
return((offset2head(disk_car,partition->part_offset)>0)&&
(offset2cylinder(disk_car,partition->part_offset)!=0 ||
@@ -1181,7 +1179,7 @@ static int is_extended(const unsigned int part_type)
return (part_type==(const unsigned char)P_EXTENDX || part_type==(const unsigned char)P_EXTENDED || part_type==(const unsigned char)P_LINUXEXTENDX);
}
-static list_part_t *add_partition_i386_cli(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
+list_part_t *add_partition_i386_cli(disk_t *disk_car, list_part_t *list_part, const int verbose, char **current_cmd)
{
CHS_t start,end;
partition_t *new_partition=partition_new(&arch_i386);
@@ -1234,7 +1232,7 @@ static list_part_t *add_partition_i386_cli(disk_t *disk_car,list_part_t *list_pa
else if(strncmp(*current_cmd,"T,",2)==0)
{
(*current_cmd)+=2;
- change_part_type(disk_car,new_partition,current_cmd);
+ change_part_type_cli(disk_car,new_partition,current_cmd);
}
else if((CHS2offset(disk_car,&end)>new_partition->part_offset) &&
new_partition->part_offset>0 &&
@@ -1249,7 +1247,7 @@ static list_part_t *add_partition_i386_cli(disk_t *disk_car,list_part_t *list_pa
}
if(test_structure_i386(list_part)==0)
{ /* Check if the partition can be Logical, Bootable or Primary */
- if(can_be_ext(disk_car,new_partition)!=0)
+ if(parti386_can_be_ext(disk_car,new_partition)!=0)
{
new_partition->status=STATUS_LOG;
if(test_structure_i386(new_list_part)==0)
@@ -1273,150 +1271,13 @@ static list_part_t *add_partition_i386_cli(disk_t *disk_car,list_part_t *list_pa
}
}
-#ifdef HAVE_NCURSES
-static list_part_t *add_partition_i386_ncurses(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
-{
- int position=0;
- CHS_t start,end;
- partition_t *new_partition=partition_new(&arch_i386);
- start.cylinder=0;
- start.head=0;
- start.sector=1;
- end.cylinder=disk_car->geom.cylinders-1;
- end.head=disk_car->geom.heads_per_cylinder-1;
- end.sector=disk_car->geom.sectors_per_head;
- {
- int done = 0;
- while (done==0)
- {
- int command;
- static struct MenuItem menuGeometry[]=
- {
- { 'c', "Cylinder", "Change starting cylinder" },
- { 'h', "Head", "Change starting head" },
- { 's', "Sector", "Change starting sector" },
- { 'C', "Cylinder", "Change ending cylinder" },
- { 'H', "Head", "Change ending head" },
- { 'S', "Sector", "Change ending sector" },
- { 'T' ,"Type", "Change partition type"},
- { 'd', "Done", "" },
- { 0, NULL, NULL }
- };
- aff_copy(stdscr);
- wmove(stdscr,4,0);
- wprintw(stdscr,"%s",disk_car->description(disk_car));
- new_partition->part_offset=CHS2offset(disk_car,&start);
- new_partition->part_size=CHS2offset(disk_car,&end) - new_partition->part_offset + disk_car->sector_size;
- wmove(stdscr,10, 0);
- wclrtoeol(stdscr);
- aff_part(stdscr, AFF_PART_BASE, disk_car, new_partition);
- wmove(stdscr,INTER_GEOM_Y, INTER_GEOM_X);
- wclrtoeol(stdscr);
- wrefresh(stdscr);
- command=wmenuSimple(stdscr,menuGeometry, position);
- switch (command)
- {
- case 'c':
- wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
- start.cylinder=ask_number(start.cylinder,
- 0, disk_car->geom.cylinders-1, "Enter the starting cylinder ");
- position=1;
- break;
- case 'h':
- wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
- start.head=ask_number(start.head,
- 0, disk_car->geom.heads_per_cylinder-1, "Enter the starting head ");
- position=2;
- break;
- case 's':
- wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
- start.sector=ask_number(start.sector,
- 1, disk_car->geom.sectors_per_head, "Enter the starting sector ");
- position=3;
- break;
- case 'C':
- wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
- end.cylinder=ask_number(end.cylinder,
- start.cylinder, disk_car->geom.cylinders-1, "Enter the ending cylinder ");
- position=4;
- break;
- case 'H':
- wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
- end.head=ask_number(end.head,
- 0, disk_car->geom.heads_per_cylinder-1, "Enter the ending head ");
- position=5;
- break;
- case 'S':
- wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
- end.sector=ask_number(end.sector,
- 1, disk_car->geom.sectors_per_head, "Enter the ending sector ");
- position=6;
- break;
- case 'T':
- case 't':
- change_part_type(disk_car,new_partition,current_cmd);
- position=7;
- break;
- case key_ESC:
- case 'd':
- case 'D':
- case 'q':
- case 'Q':
- done = 1;
- break;
- }
- }
- }
- if((CHS2offset(disk_car,&end)>new_partition->part_offset)&&(new_partition->part_offset>0)&& new_partition->part_type_i386!=P_NO_OS)
- {
- int insert_error=0;
- list_part_t *new_list_part=insert_new_partition(list_part, new_partition,0, &insert_error);
- if(insert_error>0)
- {
- free(new_partition);
- return new_list_part;
- }
- if(test_structure_i386(list_part)==0)
- { /* Check if the partition can be Logical, Bootable or Primary */
- if(can_be_ext(disk_car,new_partition)!=0)
- {
- new_partition->status=STATUS_LOG;
- if(test_structure_i386(new_list_part)==0)
- return new_list_part;
- }
- new_partition->status=STATUS_PRIM_BOOT;
- if(test_structure_i386(new_list_part)==0)
- return new_list_part;
- new_partition->status=STATUS_PRIM;
- if(test_structure_i386(new_list_part)==0)
- return new_list_part;
- }
- new_partition->status=STATUS_DELETED;
- return new_list_part;
- }
- free(new_partition);
- return list_part;
-}
-#endif
-
-static list_part_t *add_partition_i386(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
-{
- if(*current_cmd!=NULL)
- return add_partition_i386_cli(disk_car, list_part, verbose, current_cmd);
-#ifdef HAVE_NCURSES
- return add_partition_i386_ncurses(disk_car, list_part, verbose, current_cmd);
-#else
- return list_part;
-#endif
-}
-
static void set_next_status_i386(const disk_t *disk_car, partition_t *partition)
{
if(partition->status==STATUS_LOG)
partition->status=STATUS_DELETED;
else
partition->status++;
- if(partition->status==STATUS_LOG && can_be_ext(disk_car,partition)==0)
+ if(partition->status==STATUS_LOG && parti386_can_be_ext(disk_car,partition)==0)
partition->status=STATUS_DELETED;
}
@@ -1426,7 +1287,7 @@ static void set_prev_status_i386(const disk_t *disk_car, partition_t *partition)
partition->status=STATUS_LOG;
else
partition->status--;
- if(partition->status==STATUS_LOG && can_be_ext(disk_car,partition)==0)
+ if(partition->status==STATUS_LOG && parti386_can_be_ext(disk_car,partition)==0)
partition->status--;
}
@@ -1490,7 +1351,7 @@ static void init_structure_i386(const disk_t *disk_car,list_part_t *list_part, c
/* Verify */
for(element=new_list_part;element!=NULL;element=element->next)
{
- if(can_be_ext(disk_car,element->part)==0)
+ if(parti386_can_be_ext(disk_car,element->part)==0)
{
nbr_prim++;
if((end_log_block!=NULL) && (end_log_block->next==element))
@@ -1524,7 +1385,7 @@ static void init_structure_i386(const disk_t *disk_car,list_part_t *list_part, c
if(nbr_prim+nbr_log_block<=4)
{
int set_prim_bootable_done=0;
- for(element=end_biggest_log_block;element!=NULL && can_be_ext(disk_car,element->part);element=element->prev)
+ for(element=end_biggest_log_block;element!=NULL && parti386_can_be_ext(disk_car,element->part);element=element->prev)
{
element->part->status=STATUS_LOG;
}
diff --git a/src/parti386.h b/src/parti386.h
new file mode 100644
index 0000000..6f4be4a
--- /dev/null
+++ b/src/parti386.h
@@ -0,0 +1,31 @@
+/*
+
+ File: parti386.h
+
+ Copyright (C) 2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int parti386_can_be_ext(const disk_t *disk_car, const partition_t *partition);
+list_part_t *add_partition_i386_cli(disk_t *disk_car, list_part_t *list_part, const int verbose, char **current_cmd);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/parti386n.c b/src/parti386n.c
new file mode 100644
index 0000000..6848553
--- /dev/null
+++ b/src/parti386n.c
@@ -0,0 +1,168 @@
+/*
+
+ File: parti386.c
+
+ Copyright (C) 1998-2008 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_NCURSES
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include "types.h"
+#include "common.h"
+#include "fnctdsk.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "chgtypen.h"
+#include "parti386.h"
+#include "parti386n.h"
+
+extern const arch_fnct_t arch_i386;
+
+list_part_t *add_partition_i386_ncurses(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
+{
+ int position=0;
+ CHS_t start,end;
+ partition_t *new_partition=partition_new(&arch_i386);
+ start.cylinder=0;
+ start.head=0;
+ start.sector=1;
+ end.cylinder=disk_car->geom.cylinders-1;
+ end.head=disk_car->geom.heads_per_cylinder-1;
+ end.sector=disk_car->geom.sectors_per_head;
+ {
+ int done = 0;
+ while (done==0)
+ {
+ int command;
+ static struct MenuItem menuGeometry[]=
+ {
+ { 'c', "Cylinder", "Change starting cylinder" },
+ { 'h', "Head", "Change starting head" },
+ { 's', "Sector", "Change starting sector" },
+ { 'C', "Cylinder", "Change ending cylinder" },
+ { 'H', "Head", "Change ending head" },
+ { 'S', "Sector", "Change ending sector" },
+ { 'T' ,"Type", "Change partition type"},
+ { 'd', "Done", "" },
+ { 0, NULL, NULL }
+ };
+ aff_copy(stdscr);
+ wmove(stdscr,4,0);
+ wprintw(stdscr,"%s",disk_car->description(disk_car));
+ new_partition->part_offset=CHS2offset(disk_car,&start);
+ new_partition->part_size=CHS2offset(disk_car,&end) - new_partition->part_offset + disk_car->sector_size;
+ wmove(stdscr,10, 0);
+ wclrtoeol(stdscr);
+ aff_part(stdscr, AFF_PART_BASE, disk_car, new_partition);
+ wmove(stdscr,INTER_GEOM_Y, INTER_GEOM_X);
+ wclrtoeol(stdscr);
+ wrefresh(stdscr);
+ command=wmenuSimple(stdscr,menuGeometry, position);
+ switch (command)
+ {
+ case 'c':
+ wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
+ start.cylinder=ask_number(start.cylinder,
+ 0, disk_car->geom.cylinders-1, "Enter the starting cylinder ");
+ position=1;
+ break;
+ case 'h':
+ wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
+ start.head=ask_number(start.head,
+ 0, disk_car->geom.heads_per_cylinder-1, "Enter the starting head ");
+ position=2;
+ break;
+ case 's':
+ wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
+ start.sector=ask_number(start.sector,
+ 1, disk_car->geom.sectors_per_head, "Enter the starting sector ");
+ position=3;
+ break;
+ case 'C':
+ wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
+ end.cylinder=ask_number(end.cylinder,
+ start.cylinder, disk_car->geom.cylinders-1, "Enter the ending cylinder ");
+ position=4;
+ break;
+ case 'H':
+ wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
+ end.head=ask_number(end.head,
+ 0, disk_car->geom.heads_per_cylinder-1, "Enter the ending head ");
+ position=5;
+ break;
+ case 'S':
+ wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
+ end.sector=ask_number(end.sector,
+ 1, disk_car->geom.sectors_per_head, "Enter the ending sector ");
+ position=6;
+ break;
+ case 'T':
+ case 't':
+ change_part_type(disk_car,new_partition,current_cmd);
+ position=7;
+ break;
+ case key_ESC:
+ case 'd':
+ case 'D':
+ case 'q':
+ case 'Q':
+ done = 1;
+ break;
+ }
+ }
+ }
+ if((CHS2offset(disk_car,&end)>new_partition->part_offset)&&(new_partition->part_offset>0)&& new_partition->part_type_i386!=P_NO_OS)
+ {
+ int insert_error=0;
+ list_part_t *new_list_part=insert_new_partition(list_part, new_partition,0, &insert_error);
+ if(insert_error>0)
+ {
+ free(new_partition);
+ return new_list_part;
+ }
+ if(arch_i386.test_structure(list_part)==0)
+ { /* Check if the partition can be Logical, Bootable or Primary */
+ if(parti386_can_be_ext(disk_car,new_partition)!=0)
+ {
+ new_partition->status=STATUS_LOG;
+ if(arch_i386.test_structure(new_list_part)==0)
+ return new_list_part;
+ }
+ new_partition->status=STATUS_PRIM_BOOT;
+ if(arch_i386.test_structure(new_list_part)==0)
+ return new_list_part;
+ new_partition->status=STATUS_PRIM;
+ if(arch_i386.test_structure(new_list_part)==0)
+ return new_list_part;
+ }
+ new_partition->status=STATUS_DELETED;
+ return new_list_part;
+ }
+ free(new_partition);
+ return list_part;
+}
+#endif
+
+
diff --git a/src/parti386n.h b/src/parti386n.h
new file mode 100644
index 0000000..a67431f
--- /dev/null
+++ b/src/parti386n.h
@@ -0,0 +1,30 @@
+/*
+
+ File: parti386n.h
+
+ Copyright (C) 2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+list_part_t *add_partition_i386_ncurses(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/partmac.c b/src/partmac.c
index e196943..91765bc 100644
--- a/src/partmac.c
+++ b/src/partmac.c
@@ -25,6 +25,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -38,7 +39,6 @@
#include "fnctdsk.h"
#include "lang.h"
#include "intrf.h"
-#include "intrfn.h"
#include "chgtype.h"
#include "partmac.h"
#include "savehdr.h"
@@ -57,9 +57,7 @@ static int check_part_mac(disk_t *disk_car, const int verbose,partition_t *parti
static list_part_t *read_part_mac(disk_t *disk_car, const int verbose, const int saveheader);
static int write_part_mac(disk_t *disk_car, const list_part_t *list_part, const int ro , const int verbose, const int align);
static list_part_t *init_part_order_mac(const disk_t *disk_car, list_part_t *list_part);
-static list_part_t *add_partition_mac(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd);
static void set_next_status_mac(const disk_t *disk_car, partition_t *partition);
-static int test_structure_mac(list_part_t *list_part);
static int set_part_type_mac(partition_t *partition, unsigned int part_type_mac);
static int is_part_known_mac(const partition_t *partition);
static void init_structure_mac(const disk_t *disk_car,list_part_t *list_part, const int verbose);
@@ -98,7 +96,6 @@ arch_fnct_t arch_mac=
.get_geometry_from_mbr=NULL,
.check_part=check_part_mac,
.write_MBR_code=NULL,
- .add_partition=add_partition_mac,
.set_prev_status=set_next_status_mac,
.set_next_status=set_next_status_mac,
.test_structure=test_structure_mac,
@@ -205,41 +202,11 @@ list_part_t *read_part_mac(disk_t *disk_car, const int verbose, const int savehe
return new_list_part;
}
-#ifdef HAVE_NCURSES
-static void write_part_mac_warning_ncurses(void)
-{
- /* not_implemented("write_part_mac"); */
- WINDOW *window=newwin(0,0,0,0); /* full screen */
- aff_copy(window);
- wmove(window,7,0);
- wprintw(window,"Function write_part_mac not implemented");
- log_warning("Function write_part_mac not implemented\n");
- wmove(window,8,0);
- wprintw(window,"Use pdisk to recreate the missing partition");
- wmove(window,9,0);
- wprintw(window,"using values displayed by TestDisk");
- wmove(window,22,0);
- wattrset(window, A_REVERSE);
- wprintw(window,"[ Abort ]");
- wattroff(window, A_REVERSE);
- wrefresh(window);
- while(wgetch(window)==ERR);
- delwin(window);
- (void) clearok(stdscr, TRUE);
-#ifdef HAVE_TOUCHWIN
- touchwin(stdscr);
-#endif
-}
-#endif
-
static int write_part_mac(disk_t *disk_car, const list_part_t *list_part, const int ro, const int verbose, const int align)
-{ /* TODO: Implement it */
+{
+ /* TODO: Implement it */
if(ro==0)
- {
-#ifdef HAVE_NCURSES
- write_part_mac_warning_ncurses();
-#endif
- }
+ return -1;
return 0;
}
@@ -248,7 +215,7 @@ static list_part_t *init_part_order_mac(const disk_t *disk_car, list_part_t *lis
return list_part;
}
-static list_part_t *add_partition_mac_cli(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
+list_part_t *add_partition_mac_cli(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
{
partition_t *new_partition=partition_new(&arch_mac);
new_partition->part_offset=disk_car->sector_size;
@@ -286,7 +253,7 @@ static list_part_t *add_partition_mac_cli(disk_t *disk_car,list_part_t *list_par
else if(strncmp(*current_cmd,"T,",2)==0)
{
(*current_cmd)+=2;
- change_part_type(disk_car,new_partition,current_cmd);
+ change_part_type_cli(disk_car,new_partition,current_cmd);
}
else if(new_partition->part_size>0 && new_partition->part_type_mac>0)
{
@@ -310,106 +277,6 @@ static list_part_t *add_partition_mac_cli(disk_t *disk_car,list_part_t *list_par
}
}
-#ifdef HAVE_NCURSES
-static list_part_t *add_partition_mac_ncurses(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
-{
- int position=0;
- int done = FALSE;
- partition_t *new_partition=partition_new(&arch_mac);
- new_partition->part_offset=disk_car->sector_size;
- new_partition->part_size=disk_car->disk_size-disk_car->sector_size;
- while (done==FALSE)
- {
- int command;
- static struct MenuItem menuGeometry[]=
- {
- { 's', "Sector", "Change starting sector" },
- { 'S', "Sector", "Change ending sector" },
- { 'T' ,"Type", "Change partition type"},
- { 'd', "Done", "" },
- { 0, NULL, NULL }
- };
- aff_copy(stdscr);
- wmove(stdscr,4,0);
- wprintw(stdscr,"%s",disk_car->description(disk_car));
- wmove(stdscr,10, 0);
- wclrtoeol(stdscr);
- aff_part(stdscr, AFF_PART_BASE, disk_car, new_partition);
- wmove(stdscr,INTER_GEOM_Y, INTER_GEOM_X);
- wclrtoeol(stdscr);
- wrefresh(stdscr);
- command=wmenuSimple(stdscr,menuGeometry, position);
- switch (command) {
- case 's':
- {
- uint64_t part_offset;
- part_offset=new_partition->part_offset;
- wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
- new_partition->part_offset=(uint64_t)ask_number(
- new_partition->part_offset/disk_car->sector_size,
- 4096/disk_car->sector_size,
- (disk_car->disk_size-1)/disk_car->sector_size,
- "Enter the starting sector ") *
- (uint64_t)disk_car->sector_size;
- new_partition->part_size=new_partition->part_size + part_offset - new_partition->part_offset;
- position=1;
- }
- break;
- case 'S':
- wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
- new_partition->part_size=(uint64_t)ask_number(
- (new_partition->part_offset+new_partition->part_size-1)/disk_car->sector_size,
- new_partition->part_offset/disk_car->sector_size,
- (disk_car->disk_size-1)/disk_car->sector_size,
- "Enter the ending sector ") *
- (uint64_t)disk_car->sector_size +
- disk_car->sector_size - new_partition->part_offset;
- position=2;
- break;
- case 'T':
- case 't':
- change_part_type(disk_car,new_partition, current_cmd);
- position=3;
- break;
- case key_ESC:
- case 'd':
- case 'D':
- case 'q':
- case 'Q':
- done = TRUE;
- break;
- }
- }
- if(new_partition->part_size>0 && new_partition->part_type_mac>0)
- {
- int insert_error=0;
- list_part_t *new_list_part=insert_new_partition(list_part, new_partition, 0, &insert_error);
- if(insert_error>0)
- {
- free(new_partition);
- return new_list_part;
- }
- new_partition->status=STATUS_PRIM;
- if(test_structure_mac(list_part)!=0)
- new_partition->status=STATUS_DELETED;
- return new_list_part;
- }
- free(new_partition);
- return list_part;
-}
-#endif
-
-static list_part_t *add_partition_mac(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
-{
- if(*current_cmd!=NULL)
- return add_partition_mac_cli(disk_car, list_part, verbose, current_cmd);
-#ifdef HAVE_NCURSES
- return add_partition_mac_ncurses(disk_car, list_part, verbose, current_cmd);
-#else
- return list_part;
-#endif
-}
-
static void set_next_status_mac(const disk_t *disk_car, partition_t *partition)
{
if(partition->status==STATUS_DELETED)
@@ -418,7 +285,7 @@ static void set_next_status_mac(const disk_t *disk_car, partition_t *partition)
partition->status=STATUS_DELETED;
}
-static int test_structure_mac(list_part_t *list_part)
+int test_structure_mac(list_part_t *list_part)
{ /* Return 1 if bad*/
list_part_t *new_list_part;
int res;
diff --git a/src/partmac.h b/src/partmac.h
index bdfdcb0..58b90f5 100644
--- a/src/partmac.h
+++ b/src/partmac.h
@@ -20,6 +20,10 @@
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define BLOCK0_SIGNATURE 0x4552 /* Signature value. */
@@ -88,4 +92,9 @@ struct dpme {
};
typedef struct dpme mac_DPME;
+int test_structure_mac(list_part_t *list_part);
+list_part_t *add_partition_mac_cli(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd);
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/partmacn.c b/src/partmacn.c
new file mode 100644
index 0000000..ab7c2d9
--- /dev/null
+++ b/src/partmacn.c
@@ -0,0 +1,153 @@
+/*
+
+ File: partmacn.c
+
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_NCURSES
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include "types.h"
+#include "common.h"
+#include "fnctdsk.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "chgtypen.h"
+#include "log.h"
+#include "partmac.h"
+#include "partmacn.h"
+extern const arch_fnct_t arch_mac;
+
+void write_part_mac_warning_ncurses(void)
+{
+ WINDOW *window=newwin(0,0,0,0); /* full screen */
+ aff_copy(window);
+ wmove(window,7,0);
+ wprintw(window,"Function write_part_mac not implemented");
+ log_warning("Function write_part_mac not implemented\n");
+ wmove(window,8,0);
+ wprintw(window,"Use pdisk to recreate the missing partition");
+ wmove(window,9,0);
+ wprintw(window,"using values displayed by TestDisk");
+ wmove(window,22,0);
+ wattrset(window, A_REVERSE);
+ wprintw(window,"[ Abort ]");
+ wattroff(window, A_REVERSE);
+ wrefresh(window);
+ while(wgetch(window)==ERR);
+ delwin(window);
+ (void) clearok(stdscr, TRUE);
+#ifdef HAVE_TOUCHWIN
+ touchwin(stdscr);
+#endif
+}
+
+list_part_t *add_partition_mac_ncurses(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
+{
+ int position=0;
+ int done = FALSE;
+ partition_t *new_partition=partition_new(&arch_mac);
+ new_partition->part_offset=disk_car->sector_size;
+ new_partition->part_size=disk_car->disk_size-disk_car->sector_size;
+ while (done==FALSE)
+ {
+ int command;
+ static struct MenuItem menuGeometry[]=
+ {
+ { 's', "Sector", "Change starting sector" },
+ { 'S', "Sector", "Change ending sector" },
+ { 'T' ,"Type", "Change partition type"},
+ { 'd', "Done", "" },
+ { 0, NULL, NULL }
+ };
+ aff_copy(stdscr);
+ wmove(stdscr,4,0);
+ wprintw(stdscr,"%s",disk_car->description(disk_car));
+ wmove(stdscr,10, 0);
+ wclrtoeol(stdscr);
+ aff_part(stdscr, AFF_PART_BASE, disk_car, new_partition);
+ wmove(stdscr,INTER_GEOM_Y, INTER_GEOM_X);
+ wclrtoeol(stdscr);
+ wrefresh(stdscr);
+ command=wmenuSimple(stdscr,menuGeometry, position);
+ switch (command) {
+ case 's':
+ {
+ uint64_t part_offset;
+ part_offset=new_partition->part_offset;
+ wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
+ new_partition->part_offset=(uint64_t)ask_number(
+ new_partition->part_offset/disk_car->sector_size,
+ 4096/disk_car->sector_size,
+ (disk_car->disk_size-1)/disk_car->sector_size,
+ "Enter the starting sector ") *
+ (uint64_t)disk_car->sector_size;
+ new_partition->part_size=new_partition->part_size + part_offset - new_partition->part_offset;
+ position=1;
+ }
+ break;
+ case 'S':
+ wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
+ new_partition->part_size=(uint64_t)ask_number(
+ (new_partition->part_offset+new_partition->part_size-1)/disk_car->sector_size,
+ new_partition->part_offset/disk_car->sector_size,
+ (disk_car->disk_size-1)/disk_car->sector_size,
+ "Enter the ending sector ") *
+ (uint64_t)disk_car->sector_size +
+ disk_car->sector_size - new_partition->part_offset;
+ position=2;
+ break;
+ case 'T':
+ case 't':
+ change_part_type(disk_car,new_partition, current_cmd);
+ position=3;
+ break;
+ case key_ESC:
+ case 'd':
+ case 'D':
+ case 'q':
+ case 'Q':
+ done = TRUE;
+ break;
+ }
+ }
+ if(new_partition->part_size>0 && new_partition->part_type_mac>0)
+ {
+ int insert_error=0;
+ list_part_t *new_list_part=insert_new_partition(list_part, new_partition, 0, &insert_error);
+ if(insert_error>0)
+ {
+ free(new_partition);
+ return new_list_part;
+ }
+ new_partition->status=STATUS_PRIM;
+ if(test_structure_mac(list_part)!=0)
+ new_partition->status=STATUS_DELETED;
+ return new_list_part;
+ }
+ free(new_partition);
+ return list_part;
+}
+#endif
diff --git a/src/partmacn.h b/src/partmacn.h
new file mode 100644
index 0000000..ac31653
--- /dev/null
+++ b/src/partmacn.h
@@ -0,0 +1,32 @@
+
+/*
+
+ File: partmacn.h
+
+ Copyright (C) 2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void write_part_mac_warning_ncurses(void);
+list_part_t *add_partition_mac_ncurses(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/partnone.c b/src/partnone.c
index 25436a9..0d0408c 100644
--- a/src/partnone.c
+++ b/src/partnone.c
@@ -25,6 +25,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -130,7 +131,6 @@ arch_fnct_t arch_none=
.get_geometry_from_mbr=get_geometry_from_nonembr,
.check_part=check_part_none,
.write_MBR_code=NULL,
- .add_partition=NULL,
.set_prev_status=set_next_status_none,
.set_next_status=set_next_status_none,
.test_structure=test_structure_none,
diff --git a/src/partsun.c b/src/partsun.c
index 922030c..8153715 100644
--- a/src/partsun.c
+++ b/src/partsun.c
@@ -25,6 +25,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -36,10 +37,8 @@
#include "common.h"
#include "testdisk.h"
#include "fnctdsk.h"
-//#include "analyse.h"
#include "lang.h"
#include "intrf.h"
-#include "intrfn.h"
#include "chgtype.h"
#include "sun.h"
#include "swap.h"
@@ -57,13 +56,13 @@
#include "xfs.h"
#include "ufs.h"
#include "log.h"
+#include "partsun.h"
static int check_part_sun(disk_t *disk_car, const int verbose,partition_t *partition,const int saveheader);
static int get_geometry_from_sunmbr(const unsigned char *buffer, const int verbose, CHSgeometry_t *geometry);
static list_part_t *read_part_sun(disk_t *disk_car, const int verbose, const int saveheader);
static int write_part_sun(disk_t *disk_car, const list_part_t *list_part, const int ro , const int verbose, const int align);
static list_part_t *init_part_order_sun(const disk_t *disk_car, list_part_t *list_part);
-static list_part_t *add_partition_sun(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd);
static void set_next_status_sun(const disk_t *disk_car, partition_t *partition);
static int test_structure_sun(list_part_t *list_part);
static int set_part_type_sun(partition_t *partition, unsigned int part_type_sun);
@@ -103,7 +102,6 @@ arch_fnct_t arch_sun=
.get_geometry_from_mbr=get_geometry_from_sunmbr,
.check_part=check_part_sun,
.write_MBR_code=NULL,
- .add_partition=add_partition_sun,
.set_prev_status=set_next_status_sun,
.set_next_status=set_next_status_sun,
.test_structure=test_structure_sun,
@@ -183,11 +181,10 @@ list_part_t *read_part_sun(disk_t *disk_car, const int verbose, const int savehe
}
static int write_part_sun(disk_t *disk_car, const list_part_t *list_part, const int ro, const int verbose, const int align)
-{ /* TODO: Implement it */
+{
+ /* TODO: Implement it */
if(ro==0)
- {
- not_implemented("write_part_sun");
- }
+ return -1;
return 0;
}
@@ -224,7 +221,7 @@ static list_part_t *init_part_order_sun(const disk_t *disk_car, list_part_t *lis
return list_part;
}
-static list_part_t *add_partition_sun_cli(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
+list_part_t *add_partition_sun_cli(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
{
CHS_t start,end;
partition_t *new_partition=partition_new(&arch_sun);
@@ -251,7 +248,7 @@ static list_part_t *add_partition_sun_cli(disk_t *disk_car,list_part_t *list_par
else if(strncmp(*current_cmd,"T,",2)==0)
{
(*current_cmd)+=2;
- change_part_type(disk_car,new_partition,current_cmd);
+ change_part_type_cli(disk_car,new_partition,current_cmd);
}
else if((CHS2offset(disk_car,&end)>new_partition->part_offset) &&
new_partition->part_type_sun>0)
@@ -276,99 +273,6 @@ static list_part_t *add_partition_sun_cli(disk_t *disk_car,list_part_t *list_par
}
}
-#ifdef HAVE_NCURSES
-static list_part_t *add_partition_sun_ncurses(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
-{
- CHS_t start,end;
- partition_t *new_partition=partition_new(&arch_sun);
- int position=0;
- start.cylinder=0;
- start.head=0;
- start.sector=1;
- end.cylinder=disk_car->geom.cylinders-1;
- end.head=disk_car->geom.heads_per_cylinder-1;
- end.sector=disk_car->geom.sectors_per_head;
- {
- int done = FALSE;
- while (done==FALSE) {
- int command;
- static struct MenuItem menuGeometry[]=
- {
- { 'c', "Cylinders", "Change starting cylinder" },
- { 'C', "Cylinders", "Change ending cylinder" },
- { 'T' ,"Type", "Change partition type"},
- { 'd', "Done", "" },
- { 0, NULL, NULL }
- };
- aff_copy(stdscr);
- wmove(stdscr,4,0);
- wprintw(stdscr,"%s",disk_car->description(disk_car));
- new_partition->part_offset=CHS2offset(disk_car,&start);
- new_partition->part_size=CHS2offset(disk_car,&end) - new_partition->part_offset + disk_car->sector_size;
- wmove(stdscr,10, 0);
- wclrtoeol(stdscr);
- aff_part(stdscr, AFF_PART_BASE, disk_car, new_partition);
- wmove(stdscr,INTER_GEOM_Y, INTER_GEOM_X);
- wclrtoeol(stdscr);
- wrefresh(stdscr);
- command=wmenuSimple(stdscr,menuGeometry, position);
- switch (command) {
- case 'c':
- wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
- start.cylinder=ask_number(start.cylinder,0,disk_car->geom.cylinders-1,"Enter the starting cylinder ");
- position=1;
- break;
- case 'C':
- wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
- end.cylinder=ask_number(end.cylinder,start.cylinder,disk_car->geom.cylinders-1,"Enter the ending cylinder ");
- position=2;
- break;
- case 'T':
- case 't':
- change_part_type(disk_car, new_partition, current_cmd);
- position=3;
- break;
- case key_ESC:
- case 'd':
- case 'D':
- case 'q':
- case 'Q':
- done = TRUE;
- break;
- }
- }
- }
- if((CHS2offset(disk_car,&end)>new_partition->part_offset) &&
- new_partition->part_type_sun>0)
- {
- int insert_error=0;
- list_part_t *new_list_part=insert_new_partition(list_part, new_partition, 0, &insert_error);
- if(insert_error>0)
- {
- free(new_partition);
- return new_list_part;
- }
- new_partition->status=STATUS_PRIM;
- if(test_structure_sun(list_part)!=0)
- new_partition->status=STATUS_DELETED;
- return new_list_part;
- }
- free(new_partition);
- return list_part;
-}
-#endif
-
-static list_part_t *add_partition_sun(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
-{
- if(*current_cmd!=NULL)
- return add_partition_sun_cli(disk_car, list_part, verbose, current_cmd);
-#ifdef HAVE_NCURSES
- return add_partition_sun_ncurses(disk_car, list_part, verbose, current_cmd);
-#else
- return list_part;
-#endif
-}
-
static void set_next_status_sun(const disk_t *disk_car, partition_t *partition)
{
if(partition->status==STATUS_DELETED)
diff --git a/src/partsun.h b/src/partsun.h
new file mode 100644
index 0000000..bc75581
--- /dev/null
+++ b/src/partsun.h
@@ -0,0 +1,30 @@
+/*
+
+ File: partsun.c
+
+ Copyright (C) 2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+list_part_t *add_partition_sun_cli(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/partsunn.c b/src/partsunn.c
new file mode 100644
index 0000000..455b198
--- /dev/null
+++ b/src/partsunn.c
@@ -0,0 +1,121 @@
+/*
+
+ File: partsunn.c
+
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_NCURSES
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include "types.h"
+#include "common.h"
+#include "fnctdsk.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "chgtypen.h"
+#include "partsunn.h"
+
+extern const arch_fnct_t arch_sun;
+
+list_part_t *add_partition_sun_ncurses(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
+{
+ CHS_t start,end;
+ partition_t *new_partition=partition_new(&arch_sun);
+ int position=0;
+ start.cylinder=0;
+ start.head=0;
+ start.sector=1;
+ end.cylinder=disk_car->geom.cylinders-1;
+ end.head=disk_car->geom.heads_per_cylinder-1;
+ end.sector=disk_car->geom.sectors_per_head;
+ {
+ int done = FALSE;
+ while (done==FALSE) {
+ int command;
+ static struct MenuItem menuGeometry[]=
+ {
+ { 'c', "Cylinders", "Change starting cylinder" },
+ { 'C', "Cylinders", "Change ending cylinder" },
+ { 'T' ,"Type", "Change partition type"},
+ { 'd', "Done", "" },
+ { 0, NULL, NULL }
+ };
+ aff_copy(stdscr);
+ wmove(stdscr,4,0);
+ wprintw(stdscr,"%s",disk_car->description(disk_car));
+ new_partition->part_offset=CHS2offset(disk_car,&start);
+ new_partition->part_size=CHS2offset(disk_car,&end) - new_partition->part_offset + disk_car->sector_size;
+ wmove(stdscr,10, 0);
+ wclrtoeol(stdscr);
+ aff_part(stdscr, AFF_PART_BASE, disk_car, new_partition);
+ wmove(stdscr,INTER_GEOM_Y, INTER_GEOM_X);
+ wclrtoeol(stdscr);
+ wrefresh(stdscr);
+ command=wmenuSimple(stdscr,menuGeometry, position);
+ switch (command) {
+ case 'c':
+ wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
+ start.cylinder=ask_number(start.cylinder,0,disk_car->geom.cylinders-1,"Enter the starting cylinder ");
+ position=1;
+ break;
+ case 'C':
+ wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
+ end.cylinder=ask_number(end.cylinder,start.cylinder,disk_car->geom.cylinders-1,"Enter the ending cylinder ");
+ position=2;
+ break;
+ case 'T':
+ case 't':
+ change_part_type(disk_car, new_partition, current_cmd);
+ position=3;
+ break;
+ case key_ESC:
+ case 'd':
+ case 'D':
+ case 'q':
+ case 'Q':
+ done = TRUE;
+ break;
+ }
+ }
+ }
+ if((CHS2offset(disk_car,&end)>new_partition->part_offset) &&
+ new_partition->part_type_sun>0)
+ {
+ int insert_error=0;
+ list_part_t *new_list_part=insert_new_partition(list_part, new_partition, 0, &insert_error);
+ if(insert_error>0)
+ {
+ free(new_partition);
+ return new_list_part;
+ }
+ new_partition->status=STATUS_PRIM;
+ if(arch_sun.test_structure(list_part)!=0)
+ new_partition->status=STATUS_DELETED;
+ return new_list_part;
+ }
+ free(new_partition);
+ return list_part;
+}
+#endif
diff --git a/src/partsunn.h b/src/partsunn.h
new file mode 100644
index 0000000..1b875eb
--- /dev/null
+++ b/src/partsunn.h
@@ -0,0 +1,30 @@
+/*
+
+ File: partsunn.h
+
+ Copyright (C) 2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+list_part_t *add_partition_sun_ncurses(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/partxbox.c b/src/partxbox.c
index 2dfdceb..e867a04 100644
--- a/src/partxbox.c
+++ b/src/partxbox.c
@@ -24,7 +24,8 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-
+
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -38,7 +39,6 @@
#include "fnctdsk.h"
#include "lang.h"
#include "intrf.h"
-#include "intrfn.h"
#include "chgtype.h"
#include "partxbox.h"
#include "savehdr.h"
@@ -49,7 +49,6 @@ static int check_part_xbox(disk_t *disk_car, const int verbose,partition_t *part
static list_part_t *read_part_xbox(disk_t *disk_car, const int verbose, const int saveheader);
static int write_part_xbox(disk_t *disk_car, const list_part_t *list_part, const int ro , const int verbose, const int align);
static list_part_t *init_part_order_xbox(const disk_t *disk_car, list_part_t *list_part);
-static list_part_t *add_partition_xbox(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd);
static void set_next_status_xbox(const disk_t *disk_car, partition_t *partition);
static int test_structure_xbox(list_part_t *list_part);
static int set_part_type_xbox(partition_t *partition, unsigned int part_type_xbox);
@@ -76,7 +75,6 @@ arch_fnct_t arch_xbox=
.get_geometry_from_mbr=NULL,
.check_part=check_part_xbox,
.write_MBR_code=NULL,
- .add_partition=add_partition_xbox,
.set_prev_status=set_next_status_xbox,
.set_next_status=set_next_status_xbox,
.test_structure=test_structure_xbox,
@@ -135,11 +133,10 @@ list_part_t *read_part_xbox(disk_t *disk_car, const int verbose, const int saveh
}
static int write_part_xbox(disk_t *disk_car, const list_part_t *list_part, const int ro, const int verbose, const int align)
-{ /* TODO: Implement it */
+{
+ /* TODO: Implement it */
if(ro==0)
- {
- not_implemented("write_part_xbox");
- }
+ return -1;
return 0;
}
@@ -148,7 +145,7 @@ static list_part_t *init_part_order_xbox(const disk_t *disk_car, list_part_t *li
return list_part;
}
-static list_part_t *add_partition_xbox_cli(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
+list_part_t *add_partition_xbox_cli(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
{
partition_t *new_partition=partition_new(&arch_xbox);
new_partition->part_offset=disk_car->sector_size;
@@ -186,7 +183,7 @@ static list_part_t *add_partition_xbox_cli(disk_t *disk_car,list_part_t *list_pa
else if(strncmp(*current_cmd,"T,",2)==0)
{
(*current_cmd)+=2;
- change_part_type(disk_car,new_partition,current_cmd);
+ change_part_type_cli(disk_car,new_partition,current_cmd);
}
else if(new_partition->part_size>0 && new_partition->part_type_xbox>0)
{
@@ -210,106 +207,6 @@ static list_part_t *add_partition_xbox_cli(disk_t *disk_car,list_part_t *list_pa
}
}
-#ifdef HAVE_NCURSES
-static list_part_t *add_partition_xbox_ncurses(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
-{
- int position=0;
- int done = FALSE;
- partition_t *new_partition=partition_new(&arch_xbox);
- new_partition->part_offset=disk_car->sector_size;
- new_partition->part_size=disk_car->disk_size-disk_car->sector_size;
- while (done==FALSE)
- {
- int command;
- static struct MenuItem menuGeometry[]=
- {
- { 's', "Sector", "Change starting sector" },
- { 'S', "Sector", "Change ending sector" },
- { 'T' ,"Type", "Change partition type"},
- { 'd', "Done", "" },
- { 0, NULL, NULL }
- };
- aff_copy(stdscr);
- wmove(stdscr,4,0);
- wprintw(stdscr,"%s",disk_car->description(disk_car));
- wmove(stdscr,10, 0);
- wclrtoeol(stdscr);
- aff_part(stdscr, AFF_PART_BASE, disk_car, new_partition);
- wmove(stdscr,INTER_GEOM_Y, INTER_GEOM_X);
- wclrtoeol(stdscr);
- wrefresh(stdscr);
- command=wmenuSimple(stdscr,menuGeometry, position);
- switch (command) {
- case 's':
- {
- uint64_t part_offset;
- part_offset=new_partition->part_offset;
- wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
- new_partition->part_offset=(uint64_t)ask_number(
- new_partition->part_offset/disk_car->sector_size,
- 0x800/disk_car->sector_size,
- (disk_car->disk_size-1)/disk_car->sector_size,
- "Enter the starting sector ") *
- (uint64_t)disk_car->sector_size;
- new_partition->part_size=new_partition->part_size + part_offset - new_partition->part_offset;
- position=1;
- }
- break;
- case 'S':
- wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
- new_partition->part_size=(uint64_t)ask_number(
- (new_partition->part_offset+new_partition->part_size-1)/disk_car->sector_size,
- new_partition->part_offset/disk_car->sector_size,
- (disk_car->disk_size-1)/disk_car->sector_size,
- "Enter the ending sector ") *
- (uint64_t)disk_car->sector_size +
- disk_car->sector_size - new_partition->part_offset;
- position=2;
- break;
- case 'T':
- case 't':
- change_part_type(disk_car, new_partition, current_cmd);
- position=3;
- break;
- case key_ESC:
- case 'd':
- case 'D':
- case 'q':
- case 'Q':
- done = TRUE;
- break;
- }
- }
- if(new_partition->part_size>0 && new_partition->part_type_xbox>0)
- {
- int insert_error=0;
- list_part_t *new_list_part=insert_new_partition(list_part, new_partition, 0, &insert_error);
- if(insert_error>0)
- {
- free(new_partition);
- return new_list_part;
- }
- new_partition->status=STATUS_PRIM;
- if(test_structure_xbox(list_part)!=0)
- new_partition->status=STATUS_DELETED;
- return new_list_part;
- }
- free(new_partition);
- return list_part;
-}
-#endif
-
-static list_part_t *add_partition_xbox(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
-{
- if(*current_cmd!=NULL)
- return add_partition_xbox_cli(disk_car, list_part, verbose, current_cmd);
-#ifdef HAVE_NCURSES
- return add_partition_xbox_ncurses(disk_car, list_part, verbose, current_cmd);
-#else
- return list_part;
-#endif
-}
-
static void set_next_status_xbox(const disk_t *disk_car, partition_t *partition)
{
if(partition->status==STATUS_DELETED)
diff --git a/src/partxbox.h b/src/partxbox.h
index e1c2cb2..b0d0d63 100644
--- a/src/partxbox.h
+++ b/src/partxbox.h
@@ -20,6 +20,9 @@
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
struct xbox_partition
{
@@ -27,3 +30,9 @@ struct xbox_partition
char magic[4];
uint32_t bootnbr;
} __attribute__ ((__packed__));
+
+list_part_t *add_partition_xbox_cli(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/partxboxn.c b/src/partxboxn.c
new file mode 100644
index 0000000..42bfde5
--- /dev/null
+++ b/src/partxboxn.c
@@ -0,0 +1,128 @@
+/*
+
+ File: partxboxn.c
+
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_NCURSES
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include "types.h"
+#include "common.h"
+#include "fnctdsk.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "chgtypen.h"
+#include "partxboxn.h"
+
+extern const arch_fnct_t arch_xbox;
+
+list_part_t *add_partition_xbox_ncurses(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
+{
+ int position=0;
+ int done = FALSE;
+ partition_t *new_partition=partition_new(&arch_xbox);
+ new_partition->part_offset=disk_car->sector_size;
+ new_partition->part_size=disk_car->disk_size-disk_car->sector_size;
+ while (done==FALSE)
+ {
+ int command;
+ static struct MenuItem menuGeometry[]=
+ {
+ { 's', "Sector", "Change starting sector" },
+ { 'S', "Sector", "Change ending sector" },
+ { 'T' ,"Type", "Change partition type"},
+ { 'd', "Done", "" },
+ { 0, NULL, NULL }
+ };
+ aff_copy(stdscr);
+ wmove(stdscr,4,0);
+ wprintw(stdscr,"%s",disk_car->description(disk_car));
+ wmove(stdscr,10, 0);
+ wclrtoeol(stdscr);
+ aff_part(stdscr, AFF_PART_BASE, disk_car, new_partition);
+ wmove(stdscr,INTER_GEOM_Y, INTER_GEOM_X);
+ wclrtoeol(stdscr);
+ wrefresh(stdscr);
+ command=wmenuSimple(stdscr,menuGeometry, position);
+ switch (command) {
+ case 's':
+ {
+ uint64_t part_offset;
+ part_offset=new_partition->part_offset;
+ wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
+ new_partition->part_offset=(uint64_t)ask_number(
+ new_partition->part_offset/disk_car->sector_size,
+ 0x800/disk_car->sector_size,
+ (disk_car->disk_size-1)/disk_car->sector_size,
+ "Enter the starting sector ") *
+ (uint64_t)disk_car->sector_size;
+ new_partition->part_size=new_partition->part_size + part_offset - new_partition->part_offset;
+ position=1;
+ }
+ break;
+ case 'S':
+ wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
+ new_partition->part_size=(uint64_t)ask_number(
+ (new_partition->part_offset+new_partition->part_size-1)/disk_car->sector_size,
+ new_partition->part_offset/disk_car->sector_size,
+ (disk_car->disk_size-1)/disk_car->sector_size,
+ "Enter the ending sector ") *
+ (uint64_t)disk_car->sector_size +
+ disk_car->sector_size - new_partition->part_offset;
+ position=2;
+ break;
+ case 'T':
+ case 't':
+ change_part_type(disk_car, new_partition, current_cmd);
+ position=3;
+ break;
+ case key_ESC:
+ case 'd':
+ case 'D':
+ case 'q':
+ case 'Q':
+ done = TRUE;
+ break;
+ }
+ }
+ if(new_partition->part_size>0 && new_partition->part_type_xbox>0)
+ {
+ int insert_error=0;
+ list_part_t *new_list_part=insert_new_partition(list_part, new_partition, 0, &insert_error);
+ if(insert_error>0)
+ {
+ free(new_partition);
+ return new_list_part;
+ }
+ new_partition->status=STATUS_PRIM;
+ if(arch_xbox.test_structure(list_part)!=0)
+ new_partition->status=STATUS_DELETED;
+ return new_list_part;
+ }
+ free(new_partition);
+ return list_part;
+}
+#endif
diff --git a/src/partxboxn.h b/src/partxboxn.h
new file mode 100644
index 0000000..4ba71b1
--- /dev/null
+++ b/src/partxboxn.h
@@ -0,0 +1,30 @@
+/*
+
+ File: partxboxn.h
+
+ Copyright (C) 2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+list_part_t *add_partition_xbox_ncurses(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/pbanner.c b/src/pbanner.c
new file mode 100644
index 0000000..82388c2
--- /dev/null
+++ b/src/pbanner.c
@@ -0,0 +1,44 @@
+/*
+
+ File: pbanner.c
+
+ Copyright (C) 2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef HAVE_NCURSES
+#include "types.h"
+#include "common.h"
+#include "testdisk.h"
+#include "intrf.h"
+#include "intrfn.h"
+
+void aff_copy(WINDOW *window)
+{
+ wclear(window);
+ keypad(window, TRUE); /* Need it to get arrow key */
+ wmove(window,0,0);
+ wprintw(window, "PhotoRec %s, Data Recovery Utility, %s\n",VERSION,TESTDISKDATE);
+ wmove(window,1,0);
+ wprintw(window, "Christophe GRENIER <grenier@cgsecurity.org>");
+ wmove(window,2,0);
+ wprintw(window, "http://www.cgsecurity.org");
+}
+#endif
diff --git a/src/pdisksel.c b/src/pdisksel.c
index bf21c15..458efca 100644
--- a/src/pdisksel.c
+++ b/src/pdisksel.c
@@ -50,6 +50,9 @@
#include "pdisksel.h"
#include "ppartsel.h"
#include "hidden.h"
+#include "hiddenn.h"
+#include "nodisk.h"
+#include "chgtypen.h"
#ifdef HAVE_NCURSES
#define NBR_DISK_MAX (LINES-6-8)
@@ -176,7 +179,7 @@ static void photorec_disk_selection_ncurses(int verbose, const char *recup_dir,
{
disk_t *disk=current_disk->disk;
autodetect_arch(disk);
- if(interface_check_hidden(disk, &current_cmd)==0 &&
+ if((!is_hpa_or_dco(disk) || interface_check_hidden_ncurses(disk)==0) &&
interface_partition_type(disk, verbose, &current_cmd)==0)
menu_photorec(disk, verbose, recup_dir, file_enable, &current_cmd, &list_search_space);
}
@@ -201,8 +204,14 @@ int do_curses_photorec(int verbose, const char *recup_dir, const list_disk_t *li
};
if(list_disk==NULL)
{
- return intrf_no_disk("PhotoRec");
+ log_critical("No disk found\n");
+#ifdef HAVE_NCURSES
+ return intrf_no_disk_ncurses("PhotoRec");
+#else
+ return 0;
+#endif
}
+#ifdef HAVE_NCURSES
if(cmd_device==NULL)
{
char *saved_device=NULL;
@@ -221,6 +230,7 @@ int do_curses_photorec(int verbose, const char *recup_dir, const list_disk_t *li
free_list_search_space(&list_search_space);
}
}
+#endif
if(cmd_device!=NULL && *current_cmd!=NULL)
{
const list_disk_t *element_disk;
@@ -232,7 +242,12 @@ int do_curses_photorec(int verbose, const char *recup_dir, const list_disk_t *li
}
if(disk==NULL)
{
- return intrf_no_disk("PhotoRec");
+ log_critical("No disk found\n");
+#ifdef HAVE_NCURSES
+ return intrf_no_disk_ncurses("PhotoRec");
+#else
+ return 0;
+#endif
}
{
/* disk sector size is now known, fix the sector ranges */
diff --git a/src/pfree_whole.h b/src/pfree_whole.h
index fba16c9..2422b9d 100644
--- a/src/pfree_whole.h
+++ b/src/pfree_whole.h
@@ -19,6 +19,12 @@
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifdef HAVE_NCURSES
+#ifdef __cplusplus
+extern "C" {
+#endif
+
int ask_mode_ext2(const disk_t *disk_car, const partition_t *partition, unsigned int *mode_ext2, unsigned int *carve_free_space_only);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
#endif
diff --git a/src/phmain.c b/src/phmain.c
new file mode 100644
index 0000000..6ad5e8b
--- /dev/null
+++ b/src/phmain.c
@@ -0,0 +1,363 @@
+/*
+
+ File: phmain.c
+
+ Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <stdarg.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* unlink, ftruncate */
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#include <ctype.h> /* tolower */
+#ifdef HAVE_LOCALE_H
+#include <locale.h> /* setlocale */
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#include <errno.h>
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#include "types.h"
+#include "common.h"
+#include "intrf.h"
+#include "godmode.h"
+#include "fnctdsk.h"
+#ifdef HAVE_NCURSES
+#include "intrfn.h"
+#else
+#include <stdio.h>
+#endif
+#ifdef HAVE_JPEGLIB_H
+#include <jpeglib.h>
+#endif
+#include "dir.h"
+#include "filegen.h"
+#include "photorec.h"
+#include "fat.h"
+#include "hdcache.h"
+#include "ext2p.h"
+#include "fatp.h"
+#include "ntfsp.h"
+#include "ewf.h"
+#include "log.h"
+#include "phrecn.h"
+#include "hdaccess.h"
+#include "sudo.h"
+#include "phcfg.h"
+#include "misc.h"
+#include "ext2_dir.h"
+#include "ntfs_dir.h"
+#include "pdisksel.h"
+extern const arch_fnct_t arch_i386;
+extern const arch_fnct_t arch_mac;
+extern const arch_fnct_t arch_none;
+extern const arch_fnct_t arch_sun;
+extern const arch_fnct_t arch_xbox;
+extern file_enable_t list_file_enable[];
+
+int main( int argc, char **argv )
+{
+ int i;
+ int use_sudo=0;
+ int help=0, version=0, verbose=0;
+ int create_log=TD_LOG_NONE;
+ int run_setlocale=1;
+ int testdisk_mode=TESTDISK_O_RDONLY|TESTDISK_O_READAHEAD_32K;
+ const char *recup_dir=NULL;
+ list_disk_t *list_disk=NULL;
+ list_disk_t *element_disk;
+ char *cmd_device=NULL;
+ char *cmd_run=NULL;
+ const char *logfile="photorec.log";
+#ifdef TARGET_SOLARIS
+ const arch_fnct_t *arch=&arch_sun;
+#elif defined __APPLE__
+ const arch_fnct_t *arch=&arch_mac;
+#else
+ const arch_fnct_t *arch=&arch_i386;
+#endif
+#ifdef HAVE_SIGACTION
+ struct sigaction action, old_action;
+#endif
+ FILE *log_handle=NULL;
+ /* random (weak is ok) is need fot GPT */
+ srand(time(NULL));
+#ifdef HAVE_SIGACTION
+ /* set up the signal handler for SIGHUP */
+ action.sa_handler = sighup_hdlr;
+ action.sa_flags = 0;
+ if(sigaction(SIGHUP, &action, &old_action)==-1)
+ {
+ printf("Error on SIGACTION call\n");
+ return -1;
+ }
+#endif
+ printf("PhotoRec %s, Data Recovery Utility, %s\nChristophe GRENIER <grenier@cgsecurity.org>\nhttp://www.cgsecurity.org\n",VERSION,TESTDISKDATE);
+ for(i=1;i<argc;i++)
+ {
+ if((strcmp(argv[i],"/logname")==0) ||(strcmp(argv[i],"-logname")==0))
+ {
+ if(i+2>=argc)
+ help=1;
+ else
+ logfile=argv[++i];
+ }
+ else if((strcmp(argv[i],"/log")==0) ||(strcmp(argv[i],"-log")==0))
+ {
+ if(create_log==TD_LOG_NONE)
+ create_log=TD_LOG_APPEND;
+ }
+ else if((strcmp(argv[i],"/debug")==0) || (strcmp(argv[i],"-debug")==0))
+ {
+ verbose++;
+ if(create_log==TD_LOG_NONE)
+ create_log=TD_LOG_APPEND;
+ }
+ else if(((strcmp(argv[i],"/d")==0)||(strcmp(argv[i],"-d")==0)) &&(i+1<argc))
+ {
+ int len=strlen(argv[i+1]);
+ if(argv[i+1][len-1]=='\\' || argv[i+1][len-1]=='/')
+ {
+ char *new_recup_dir=(char *)MALLOC(len+strlen(DEFAULT_RECUP_DIR)+1);
+ strcpy(new_recup_dir,argv[i+1]);
+ strcat(new_recup_dir,DEFAULT_RECUP_DIR);
+ recup_dir=new_recup_dir; /* small memory leak */
+ }
+ else
+ recup_dir=argv[i+1];
+ i++;
+ }
+ else if((strcmp(argv[i],"/all")==0) || (strcmp(argv[i],"-all")==0))
+ testdisk_mode|=TESTDISK_O_ALL;
+ else if((strcmp(argv[i],"/direct")==0) || (strcmp(argv[i],"-direct")==0))
+ testdisk_mode|=TESTDISK_O_DIRECT;
+ else if((strcmp(argv[i],"/help")==0) || (strcmp(argv[i],"-help")==0) || (strcmp(argv[i],"--help")==0) ||
+ (strcmp(argv[i],"/h")==0) || (strcmp(argv[i],"-h")==0))
+ help=1;
+ else if((strcmp(argv[i],"/version")==0) || (strcmp(argv[i],"-version")==0) || (strcmp(argv[i],"--version")==0) ||
+ (strcmp(argv[i],"/v")==0) || (strcmp(argv[i],"-v")==0))
+ version=1;
+ else if((strcmp(argv[i],"/nosetlocale")==0) || (strcmp(argv[i],"-nosetlocale")==0))
+ run_setlocale=0;
+ else if(strcmp(argv[i],"/cmd")==0)
+ {
+ if(i+2>=argc)
+ help=1;
+ else
+ {
+ disk_t *disk_car;
+ cmd_device=argv[++i];
+ cmd_run=argv[++i];
+ /* There is no log currently */
+ disk_car=file_test_availability(cmd_device,verbose,arch,testdisk_mode);
+ if(disk_car==NULL)
+ {
+ printf("\nUnable to open file or device %s\n",cmd_device);
+ help=1;
+ }
+ else
+ list_disk=insert_new_disk(list_disk,disk_car);
+ }
+ }
+ else
+ {
+ disk_t *disk_car=file_test_availability(argv[i],verbose,arch,testdisk_mode);
+ if(disk_car==NULL)
+ {
+ printf("\nUnable to open file or device %s\n",argv[i]);
+ help=1;
+ }
+ else
+ list_disk=insert_new_disk(list_disk,disk_car);
+ }
+ }
+ if(version!=0)
+ {
+ printf("\n");
+ printf("Version: %s\n", VERSION);
+ printf("Compiler: %s\n", get_compiler());
+ printf("ext2fs lib: %s, ntfs lib: %s, ewf lib: %s, libjpeg: ",
+ td_ext2fs_version(), td_ntfs_version(), td_ewf_version());
+#if defined(HAVE_LIBJPEG)
+#if defined(JPEG_LIB_VERSION)
+ printf("%u", JPEG_LIB_VERSION);
+#else
+ printf("yes");
+#endif
+#else
+ printf("none");
+#endif
+ printf("\n");
+ printf("OS: %s\n" , get_os());
+ return 0;
+ }
+ if(help!=0)
+ {
+ printf("\nUsage: photorec [/log] [/debug] [/d recup_dir] [file.dd|file.e01|device]\n"\
+ " photorec /version\n" \
+ "\n" \
+ "/log : create a photorec.log file\n" \
+ "/debug : add debug information\n" \
+ "\n" \
+ "PhotoRec searches various file formats (JPEG, Office...), it stores them\n" \
+ "in recup_dir directory.\n" \
+ "\n" \
+ "If you have problems with PhotoRec or bug reports, please contact me.\n");
+ return 0;
+ }
+ if(create_log!=TD_LOG_NONE)
+ log_handle=log_open(logfile, create_log);
+#ifdef HAVE_SETLOCALE
+ if(run_setlocale>0)
+ {
+ const char *locale;
+ locale = setlocale (LC_ALL, "");
+ if (locale==NULL) {
+ locale = setlocale (LC_ALL, NULL);
+ log_error("Failed to set locale, using default '%s'.\n", locale);
+ } else {
+ log_info("Using locale '%s'.\n", locale);
+ }
+ }
+#endif
+ if(create_log!=TD_LOG_NONE && log_handle==NULL)
+ log_handle=log_open_default(logfile, create_log);
+#ifdef HAVE_NCURSES
+ /* ncurses need locale for correct unicode support */
+ if(start_ncurses("PhotoRec", argv[0]))
+ return 1;
+ {
+ const char*filename=logfile;
+ while(create_log!=TD_LOG_NONE && log_handle==NULL)
+ {
+ filename=ask_log_location(filename);
+ if(filename!=NULL)
+ log_handle=log_open(filename, create_log);
+ else
+ create_log=TD_LOG_NONE;
+ }
+ }
+ aff_copy(stdscr);
+ wmove(stdscr,5,0);
+ wprintw(stdscr, "Please wait...\n");
+ wrefresh(stdscr);
+#endif
+ if(log_handle!=NULL)
+ {
+ time_t my_time;
+#ifdef HAVE_DUP2
+ dup2(fileno(log_handle),2);
+#endif
+ my_time=time(NULL);
+ log_info("\n\n%s",ctime(&my_time));
+ log_info("Command line: PhotoRec");
+ for(i=1;i<argc;i++)
+ log_info(" %s", argv[i]);
+ log_info("\n\n");
+ log_flush();
+ }
+ log_info("PhotoRec %s, Data Recovery Utility, %s\nChristophe GRENIER <grenier@cgsecurity.org>\nhttp://www.cgsecurity.org\n", VERSION, TESTDISKDATE);
+ log_info("OS: %s\n" , get_os());
+ log_info("Compiler: %s\n", get_compiler());
+ log_info("ext2fs lib: %s, ntfs lib: %s, ewf lib: %s, libjpeg: ",
+ td_ext2fs_version(), td_ntfs_version(), td_ewf_version());
+#if defined(HAVE_LIBJPEG)
+#if defined(JPEG_LIB_VERSION)
+ log_info("%u", JPEG_LIB_VERSION);
+#else
+ log_info("yes");
+#endif
+#else
+ log_info("none");
+#endif
+ log_info("\n");
+#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(DJGPP)
+#else
+#ifdef HAVE_GETEUID
+ if(geteuid()!=0)
+ {
+ log_warning("User is not root!\n");
+ }
+#endif
+#endif
+ screen_buffer_reset();
+ /* Scan for available device only if no device or image has been supplied in parameter */
+ if(list_disk==NULL)
+ list_disk=hd_parse(list_disk,verbose,arch,testdisk_mode);
+ hd_update_all_geometry(list_disk,0,verbose);
+ /* Activate the cache, even if photorec has its own */
+ for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
+ element_disk->disk=new_diskcache(element_disk->disk,testdisk_mode);
+ /* save disk parameters to rapport */
+ log_info("Hard disk list\n");
+ for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
+ {
+ disk_t *disk=element_disk->disk;
+ if(disk->model==NULL)
+ log_info("%s, sector size=%u\n",
+ disk->description(disk), disk->sector_size);
+ else
+ log_info("%s, sector size=%u - %s\n",
+ disk->description(disk), disk->sector_size, disk->model);
+ }
+ log_info("\n");
+ file_options_load(list_file_enable);
+ use_sudo=do_curses_photorec(verbose, recup_dir, list_disk, list_file_enable, cmd_device, &cmd_run);
+#ifdef HAVE_NCURSES
+ end_ncurses();
+#endif
+ delete_list_disk(list_disk);
+ log_info("PhotoRec exited normally.\n");
+ if(log_close()!=0)
+ {
+ printf("PhotoRec: Log file corrupted!\n");
+ }
+ else
+ {
+ printf("PhotoRec exited normally.\n");
+ }
+#ifdef SUDO_BIN
+ if(use_sudo>0)
+ run_sudo(argc, argv);
+#endif
+ return 0;
+}
diff --git a/src/photorec.c b/src/photorec.c
index bc1de34..bf643bf 100644
--- a/src/photorec.c
+++ b/src/photorec.c
@@ -61,11 +61,7 @@
#include "intrf.h"
#include "godmode.h"
#include "fnctdsk.h"
-#ifdef HAVE_NCURSES
-#include "intrfn.h"
-#else
#include <stdio.h>
-#endif
#ifdef HAVE_JPEGLIB_H
#include <jpeglib.h>
#endif
@@ -92,168 +88,6 @@
/* #define DEBUG_UPDATE_SEARCH_SPACE */
/* #define DEBUG_FREE */
-extern const arch_fnct_t arch_i386;
-extern const arch_fnct_t arch_mac;
-extern const arch_fnct_t arch_none;
-extern const arch_fnct_t arch_sun;
-extern const arch_fnct_t arch_xbox;
-
-extern const file_hint_t file_hint_7z;
-extern const file_hint_t file_hint_a;
-extern const file_hint_t file_hint_abcdp;
-extern const file_hint_t file_hint_accdb;
-extern const file_hint_t file_hint_ace;
-extern const file_hint_t file_hint_addressbook;
-extern const file_hint_t file_hint_ahn;
-extern const file_hint_t file_hint_aif;
-extern const file_hint_t file_hint_all;
-extern const file_hint_t file_hint_als;
-extern const file_hint_t file_hint_amd;
-extern const file_hint_t file_hint_amr;
-extern const file_hint_t file_hint_ape;
-extern const file_hint_t file_hint_arj;
-extern const file_hint_t file_hint_asf;
-extern const file_hint_t file_hint_asm;
-extern const file_hint_t file_hint_atd;
-extern const file_hint_t file_hint_au;
-extern const file_hint_t file_hint_bkf;
-extern const file_hint_t file_hint_blend;
-extern const file_hint_t file_hint_bmp;
-extern const file_hint_t file_hint_bz2;
-extern const file_hint_t file_hint_cab;
-extern const file_hint_t file_hint_cam;
-extern const file_hint_t file_hint_chm;
-extern const file_hint_t file_hint_cm;
-extern const file_hint_t file_hint_compress;
-extern const file_hint_t file_hint_crw;
-extern const file_hint_t file_hint_ctg;
-extern const file_hint_t file_hint_cwk;
-extern const file_hint_t file_hint_dat;
-extern const file_hint_t file_hint_dbf;
-extern const file_hint_t file_hint_dim;
-extern const file_hint_t file_hint_dir;
-extern const file_hint_t file_hint_djv;
-extern const file_hint_t file_hint_doc;
-extern const file_hint_t file_hint_dpx;
-extern const file_hint_t file_hint_drw;
-extern const file_hint_t file_hint_ds2;
-extern const file_hint_t file_hint_dsc;
-extern const file_hint_t file_hint_dss;
-extern const file_hint_t file_hint_dta;
-extern const file_hint_t file_hint_dump;
-extern const file_hint_t file_hint_dv;
-extern const file_hint_t file_hint_dwg;
-extern const file_hint_t file_hint_elf;
-extern const file_hint_t file_hint_emf;
-extern const file_hint_t file_hint_evt;
-extern const file_hint_t file_hint_exe;
-extern const file_hint_t file_hint_ext2_sb;
-extern const file_hint_t file_hint_fbk;
-extern const file_hint_t file_hint_fcp;
-extern const file_hint_t file_hint_fcs;
-extern const file_hint_t file_hint_fdb;
-extern const file_hint_t file_hint_fh10;
-extern const file_hint_t file_hint_fh5;
-extern const file_hint_t file_hint_fits;
-extern const file_hint_t file_hint_flac;
-extern const file_hint_t file_hint_fasttxt;
-extern const file_hint_t file_hint_flv;
-extern const file_hint_t file_hint_fob;
-extern const file_hint_t file_hint_frm;
-extern const file_hint_t file_hint_fs;
-extern const file_hint_t file_hint_gho;
-extern const file_hint_t file_hint_gif;
-extern const file_hint_t file_hint_gpg;
-extern const file_hint_t file_hint_gz;
-extern const file_hint_t file_hint_ifo;
-extern const file_hint_t file_hint_imb;
-extern const file_hint_t file_hint_indd;
-extern const file_hint_t file_hint_iso;
-extern const file_hint_t file_hint_itunes;
-extern const file_hint_t file_hint_jpg;
-extern const file_hint_t file_hint_kdb;
-extern const file_hint_t file_hint_logic;
-extern const file_hint_t file_hint_lnk;
-extern const file_hint_t file_hint_m2ts;
-extern const file_hint_t file_hint_max;
-extern const file_hint_t file_hint_mb;
-extern const file_hint_t file_hint_mcd;
-extern const file_hint_t file_hint_mdb;
-extern const file_hint_t file_hint_mdf;
-extern const file_hint_t file_hint_mfa;
-extern const file_hint_t file_hint_mfg;
-extern const file_hint_t file_hint_mid;
-extern const file_hint_t file_hint_mkv;
-extern const file_hint_t file_hint_mov;
-extern const file_hint_t file_hint_mp3;
-extern const file_hint_t file_hint_mpg;
-extern const file_hint_t file_hint_mrw;
-extern const file_hint_t file_hint_mus;
-extern const file_hint_t file_hint_mysql;
-extern const file_hint_t file_hint_njx;
-extern const file_hint_t file_hint_ogg;
-extern const file_hint_t file_hint_one;
-extern const file_hint_t file_hint_orf;
-extern const file_hint_t file_hint_paf;
-extern const file_hint_t file_hint_pap;
-extern const file_hint_t file_hint_pcap;
-extern const file_hint_t file_hint_pct;
-extern const file_hint_t file_hint_pcx;
-extern const file_hint_t file_hint_pdf;
-extern const file_hint_t file_hint_pfx;
-extern const file_hint_t file_hint_png;
-extern const file_hint_t file_hint_prc;
-extern const file_hint_t file_hint_prt;
-extern const file_hint_t file_hint_ps;
-extern const file_hint_t file_hint_psd;
-extern const file_hint_t file_hint_psp;
-extern const file_hint_t file_hint_pst;
-extern const file_hint_t file_hint_ptb;
-extern const file_hint_t file_hint_qbb;
-extern const file_hint_t file_hint_qdf;
-extern const file_hint_t file_hint_qxd;
-extern const file_hint_t file_hint_ra;
-extern const file_hint_t file_hint_raf;
-extern const file_hint_t file_hint_rar;
-extern const file_hint_t file_hint_raw;
-extern const file_hint_t file_hint_rdc;
-extern const file_hint_t file_hint_reg;
-extern const file_hint_t file_hint_res;
-extern const file_hint_t file_hint_riff;
-extern const file_hint_t file_hint_rm;
-extern const file_hint_t file_hint_rns;
-extern const file_hint_t file_hint_rpm;
-extern const file_hint_t file_hint_sib;
-extern const file_hint_t file_hint_sit;
-extern const file_hint_t file_hint_skp;
-extern const file_hint_t file_hint_sp3;
-extern const file_hint_t file_hint_spe;
-extern const file_hint_t file_hint_spf;
-extern const file_hint_t file_hint_spss;
-extern const file_hint_t file_hint_sqlite;
-extern const file_hint_t file_hint_sqm;
-extern const file_hint_t file_hint_stl;
-extern const file_hint_t file_hint_stuffit;
-extern const file_hint_t file_hint_swf;
-extern const file_hint_t file_hint_tar;
-extern const file_hint_t file_hint_tax;
-extern const file_hint_t file_hint_tib;
-extern const file_hint_t file_hint_tiff;
-extern const file_hint_t file_hint_tph;
-extern const file_hint_t file_hint_txt;
-extern const file_hint_t file_hint_veg;
-extern const file_hint_t file_hint_vmdk;
-extern const file_hint_t file_hint_wks;
-extern const file_hint_t file_hint_wmf;
-extern const file_hint_t file_hint_wnk;
-extern const file_hint_t file_hint_wpd;
-extern const file_hint_t file_hint_wv;
-extern const file_hint_t file_hint_x3f;
-extern const file_hint_t file_hint_xcf;
-extern const file_hint_t file_hint_xm;
-extern const file_hint_t file_hint_xsv;
-extern const file_hint_t file_hint_zip;
-
static alloc_data_t *update_search_space(const file_recovery_t *file_recovery, alloc_data_t *list_search_space, alloc_data_t **new_current_search_space, uint64_t *offset, const unsigned int blocksize);
static alloc_data_t *update_search_space_aux(alloc_data_t *list_search_space, uint64_t start, uint64_t end, alloc_data_t **new_current_search_space, uint64_t *offset);
@@ -504,27 +338,6 @@ void free_list_search_space(alloc_data_t *list_search_space)
}
}
-void reset_file_recovery(file_recovery_t *file_recovery)
-{
- file_recovery->filename[0]='\0';
- file_recovery->time=0;
- file_recovery->file_stat=NULL;
- file_recovery->handle=NULL;
- file_recovery->file_size=0;
- file_recovery->file_size_on_disk=0;
- file_recovery->location.list.prev=&file_recovery->location.list;
- file_recovery->location.list.next=&file_recovery->location.list;
- file_recovery->location.start=0;
- file_recovery->location.end=0;
- file_recovery->location.data=0;
- file_recovery->extension=NULL;
- file_recovery->min_filesize=0;
- file_recovery->calculated_file_size=0;
- file_recovery->data_check=NULL;
- file_recovery->file_check=NULL;
- file_recovery->offset_error=0;
-}
-
unsigned int photorec_mkdir(const char *recup_dir, const unsigned int initial_dir_num)
{
char working_recup_dir[2048];
@@ -802,498 +615,6 @@ alloc_data_t * update_blocksize(unsigned int blocksize, alloc_data_t *list_searc
return list_search_space;
}
-int main( int argc, char **argv )
-{
- int i;
- int use_sudo=0;
- int help=0, version=0, verbose=0;
- int create_log=TD_LOG_NONE;
- int run_setlocale=1;
- int testdisk_mode=TESTDISK_O_RDONLY|TESTDISK_O_READAHEAD_32K;
- const char *recup_dir=NULL;
- list_disk_t *list_disk=NULL;
- list_disk_t *element_disk;
- char *cmd_device=NULL;
- char *cmd_run=NULL;
- const char *logfile="photorec.log";
-#ifdef TARGET_SOLARIS
- const arch_fnct_t *arch=&arch_sun;
-#elif defined __APPLE__
- const arch_fnct_t *arch=&arch_mac;
-#else
- const arch_fnct_t *arch=&arch_i386;
-#endif
-#ifdef HAVE_SIGACTION
- struct sigaction action, old_action;
-#endif
- file_enable_t list_file_enable[]=
- {
- { .enable=0, .file_hint=&file_hint_7z },
- { .enable=0, .file_hint=&file_hint_a },
- { .enable=0, .file_hint=&file_hint_abcdp},
- { .enable=0, .file_hint=&file_hint_accdb},
- { .enable=0, .file_hint=&file_hint_ace },
- { .enable=0, .file_hint=&file_hint_addressbook},
- { .enable=0, .file_hint=&file_hint_ahn },
- { .enable=0, .file_hint=&file_hint_aif },
- { .enable=0, .file_hint=&file_hint_all },
- { .enable=0, .file_hint=&file_hint_als },
- { .enable=0, .file_hint=&file_hint_amd },
- { .enable=0, .file_hint=&file_hint_amr },
- { .enable=0, .file_hint=&file_hint_ape },
- { .enable=0, .file_hint=&file_hint_arj },
- { .enable=0, .file_hint=&file_hint_asf },
- { .enable=0, .file_hint=&file_hint_asm },
- { .enable=0, .file_hint=&file_hint_atd },
- { .enable=0, .file_hint=&file_hint_au },
- { .enable=0, .file_hint=&file_hint_bkf },
- { .enable=0, .file_hint=&file_hint_blend },
- { .enable=0, .file_hint=&file_hint_bmp },
- { .enable=0, .file_hint=&file_hint_bz2 },
- { .enable=0, .file_hint=&file_hint_cab },
- { .enable=0, .file_hint=&file_hint_cam },
- { .enable=0, .file_hint=&file_hint_chm },
- { .enable=0, .file_hint=&file_hint_cm },
- { .enable=0, .file_hint=&file_hint_compress },
- { .enable=0, .file_hint=&file_hint_crw },
- { .enable=0, .file_hint=&file_hint_ctg },
- { .enable=0, .file_hint=&file_hint_cwk },
- { .enable=0, .file_hint=&file_hint_dat },
- { .enable=0, .file_hint=&file_hint_dbf },
- { .enable=0, .file_hint=&file_hint_dim },
- { .enable=0, .file_hint=&file_hint_dir },
- { .enable=0, .file_hint=&file_hint_djv },
- { .enable=0, .file_hint=&file_hint_drw },
- { .enable=0, .file_hint=&file_hint_doc },
- { .enable=0, .file_hint=&file_hint_dpx },
- { .enable=0, .file_hint=&file_hint_ds2 },
- { .enable=0, .file_hint=&file_hint_dsc },
- { .enable=0, .file_hint=&file_hint_dss },
- { .enable=0, .file_hint=&file_hint_dta },
- { .enable=0, .file_hint=&file_hint_dump },
- { .enable=0, .file_hint=&file_hint_dv },
- { .enable=0, .file_hint=&file_hint_dwg },
- { .enable=0, .file_hint=&file_hint_elf },
- { .enable=0, .file_hint=&file_hint_emf },
- { .enable=0, .file_hint=&file_hint_evt },
- { .enable=0, .file_hint=&file_hint_exe },
- { .enable=0, .file_hint=&file_hint_ext2_sb },
- { .enable=0, .file_hint=&file_hint_fbk },
- { .enable=0, .file_hint=&file_hint_fcp },
- { .enable=0, .file_hint=&file_hint_fcs },
- { .enable=0, .file_hint=&file_hint_fdb },
- { .enable=0, .file_hint=&file_hint_fh10 },
- { .enable=0, .file_hint=&file_hint_fh5 },
- { .enable=0, .file_hint=&file_hint_fits },
- { .enable=0, .file_hint=&file_hint_flac },
- { .enable=0, .file_hint=&file_hint_flv },
- { .enable=0, .file_hint=&file_hint_fob },
- { .enable=0, .file_hint=&file_hint_frm },
- { .enable=0, .file_hint=&file_hint_fs },
- { .enable=0, .file_hint=&file_hint_gho },
- { .enable=0, .file_hint=&file_hint_gif },
- { .enable=0, .file_hint=&file_hint_gpg },
- { .enable=0, .file_hint=&file_hint_gz },
- { .enable=0, .file_hint=&file_hint_ifo },
- { .enable=0, .file_hint=&file_hint_imb },
- { .enable=0, .file_hint=&file_hint_indd },
- { .enable=0, .file_hint=&file_hint_iso },
- { .enable=0, .file_hint=&file_hint_itunes },
- { .enable=0, .file_hint=&file_hint_jpg },
- { .enable=0, .file_hint=&file_hint_kdb },
- { .enable=0, .file_hint=&file_hint_logic},
- { .enable=0, .file_hint=&file_hint_lnk },
- { .enable=0, .file_hint=&file_hint_m2ts },
- { .enable=0, .file_hint=&file_hint_max },
- { .enable=0, .file_hint=&file_hint_mb },
- { .enable=0, .file_hint=&file_hint_mcd },
- { .enable=0, .file_hint=&file_hint_mdb },
- { .enable=0, .file_hint=&file_hint_mdf },
- { .enable=0, .file_hint=&file_hint_mfa },
- { .enable=0, .file_hint=&file_hint_mfg },
- { .enable=0, .file_hint=&file_hint_mid },
- { .enable=0, .file_hint=&file_hint_mkv },
- { .enable=0, .file_hint=&file_hint_mov },
- { .enable=0, .file_hint=&file_hint_mp3 },
- { .enable=0, .file_hint=&file_hint_mpg },
- { .enable=0, .file_hint=&file_hint_mrw },
- { .enable=0, .file_hint=&file_hint_mus },
- { .enable=0, .file_hint=&file_hint_mysql },
- { .enable=0, .file_hint=&file_hint_njx },
- { .enable=0, .file_hint=&file_hint_ogg },
- { .enable=0, .file_hint=&file_hint_one },
- { .enable=0, .file_hint=&file_hint_orf },
- { .enable=0, .file_hint=&file_hint_paf },
- { .enable=0, .file_hint=&file_hint_pap },
- { .enable=0, .file_hint=&file_hint_pcap },
- { .enable=0, .file_hint=&file_hint_pct },
- { .enable=0, .file_hint=&file_hint_pcx },
- { .enable=0, .file_hint=&file_hint_pdf },
- { .enable=0, .file_hint=&file_hint_pfx },
- { .enable=0, .file_hint=&file_hint_png },
- { .enable=0, .file_hint=&file_hint_prc },
- { .enable=0, .file_hint=&file_hint_prt },
- { .enable=0, .file_hint=&file_hint_ps },
- { .enable=0, .file_hint=&file_hint_psd },
- { .enable=0, .file_hint=&file_hint_psp },
- { .enable=0, .file_hint=&file_hint_pst },
- { .enable=0, .file_hint=&file_hint_ptb },
- { .enable=0, .file_hint=&file_hint_qbb },
- { .enable=0, .file_hint=&file_hint_qdf },
- { .enable=0, .file_hint=&file_hint_qxd },
- { .enable=0, .file_hint=&file_hint_ra },
- { .enable=0, .file_hint=&file_hint_raf },
- { .enable=0, .file_hint=&file_hint_rar },
- { .enable=0, .file_hint=&file_hint_raw },
- { .enable=0, .file_hint=&file_hint_rdc },
- { .enable=0, .file_hint=&file_hint_reg },
- { .enable=0, .file_hint=&file_hint_res },
- { .enable=0, .file_hint=&file_hint_riff },
- { .enable=0, .file_hint=&file_hint_rm },
- { .enable=0, .file_hint=&file_hint_rns },
- { .enable=0, .file_hint=&file_hint_rpm },
- { .enable=0, .file_hint=&file_hint_sib },
- { .enable=0, .file_hint=&file_hint_sit },
- { .enable=0, .file_hint=&file_hint_skp },
- { .enable=0, .file_hint=&file_hint_sp3 },
- { .enable=0, .file_hint=&file_hint_spe },
- { .enable=0, .file_hint=&file_hint_spf },
- { .enable=0, .file_hint=&file_hint_spss },
- { .enable=0, .file_hint=&file_hint_sqlite },
- { .enable=0, .file_hint=&file_hint_sqm },
- { .enable=0, .file_hint=&file_hint_stl },
- { .enable=0, .file_hint=&file_hint_stuffit },
- { .enable=0, .file_hint=&file_hint_swf },
- { .enable=0, .file_hint=&file_hint_tar },
- { .enable=0, .file_hint=&file_hint_tax },
- { .enable=0, .file_hint=&file_hint_tib },
- { .enable=0, .file_hint=&file_hint_tiff },
- { .enable=0, .file_hint=&file_hint_tph },
- { .enable=0, .file_hint=&file_hint_fasttxt },
- { .enable=0, .file_hint=&file_hint_txt },
- { .enable=0, .file_hint=&file_hint_vmdk },
- { .enable=0, .file_hint=&file_hint_veg },
- { .enable=0, .file_hint=&file_hint_wks },
- { .enable=0, .file_hint=&file_hint_wmf },
- { .enable=0, .file_hint=&file_hint_wnk },
- { .enable=0, .file_hint=&file_hint_wpd },
- { .enable=0, .file_hint=&file_hint_wv },
- { .enable=0, .file_hint=&file_hint_x3f },
- { .enable=0, .file_hint=&file_hint_xcf },
- { .enable=0, .file_hint=&file_hint_xm },
- { .enable=0, .file_hint=&file_hint_xsv },
- { .enable=0, .file_hint=&file_hint_zip },
- { .enable=0, .file_hint=NULL }
- };
- /* random (weak is ok) is need fot GPT */
- srand(time(NULL));
-#ifdef HAVE_SIGACTION
- /* set up the signal handler for SIGHUP */
- action.sa_handler = sighup_hdlr;
- action.sa_flags = 0;
- if(sigaction(SIGHUP, &action, &old_action)==-1)
- {
- printf("Error on SIGACTION call\n");
- return -1;
- }
-#endif
- printf("PhotoRec %s, Data Recovery Utility, %s\nChristophe GRENIER <grenier@cgsecurity.org>\nhttp://www.cgsecurity.org\n",VERSION,TESTDISKDATE);
- for(i=1;i<argc;i++)
- {
- if((strcmp(argv[i],"/logname")==0) ||(strcmp(argv[i],"-logname")==0))
- {
- if(i+2>=argc)
- help=1;
- else
- logfile=argv[++i];
- }
- else if((strcmp(argv[i],"/log")==0) ||(strcmp(argv[i],"-log")==0))
- {
- if(create_log==TD_LOG_NONE)
- create_log=log_open(logfile, TD_LOG_APPEND, 0, "PhotoRec", argc, argv);
- }
- else if((strcmp(argv[i],"/debug")==0) || (strcmp(argv[i],"-debug")==0))
- {
- verbose++;
- if(create_log==TD_LOG_NONE)
- create_log=log_open(logfile, TD_LOG_APPEND, 0, "PhotoRec", argc, argv);
- }
- else if(((strcmp(argv[i],"/d")==0)||(strcmp(argv[i],"-d")==0)) &&(i+1<argc))
- {
- int len=strlen(argv[i+1]);
- if(argv[i+1][len-1]=='\\' || argv[i+1][len-1]=='/')
- {
- char *new_recup_dir=(char *)MALLOC(len+strlen(DEFAULT_RECUP_DIR)+1);
- strcpy(new_recup_dir,argv[i+1]);
- strcat(new_recup_dir,DEFAULT_RECUP_DIR);
- recup_dir=new_recup_dir; /* small memory leak */
- }
- else
- recup_dir=argv[i+1];
- i++;
- }
- else if((strcmp(argv[i],"/all")==0) || (strcmp(argv[i],"-all")==0))
- testdisk_mode|=TESTDISK_O_ALL;
- else if((strcmp(argv[i],"/direct")==0) || (strcmp(argv[i],"-direct")==0))
- testdisk_mode|=TESTDISK_O_DIRECT;
- else if((strcmp(argv[i],"/help")==0) || (strcmp(argv[i],"-help")==0) || (strcmp(argv[i],"--help")==0) ||
- (strcmp(argv[i],"/h")==0) || (strcmp(argv[i],"-h")==0))
- help=1;
- else if((strcmp(argv[i],"/version")==0) || (strcmp(argv[i],"-version")==0) || (strcmp(argv[i],"--version")==0) ||
- (strcmp(argv[i],"/v")==0) || (strcmp(argv[i],"-v")==0))
- version=1;
- else if((strcmp(argv[i],"/nosetlocale")==0) || (strcmp(argv[i],"-nosetlocale")==0))
- run_setlocale=0;
- else if(strcmp(argv[i],"/cmd")==0)
- {
- if(i+2>=argc)
- help=1;
- else
- {
- disk_t *disk_car;
- cmd_device=argv[++i];
- cmd_run=argv[++i];
- /* There is no log currently */
- disk_car=file_test_availability(cmd_device,verbose,arch,testdisk_mode);
- if(disk_car==NULL)
- {
- printf("\nUnable to open file or device %s\n",cmd_device);
- help=1;
- }
- else
- list_disk=insert_new_disk(list_disk,disk_car);
- }
- }
- else
- {
- disk_t *disk_car=file_test_availability(argv[i],verbose,arch,testdisk_mode);
- if(disk_car==NULL)
- {
- printf("\nUnable to open file or device %s\n",argv[i]);
- help=1;
- }
- else
- list_disk=insert_new_disk(list_disk,disk_car);
- }
- }
- if(version!=0)
- {
- printf("\n");
- printf("Version: %s\n", VERSION);
- printf("Compiler: %s\n", get_compiler());
- printf("ext2fs lib: %s, ntfs lib: %s, ewf lib: %s, libjpeg: ",
- td_ext2fs_version(), td_ntfs_version(), td_ewf_version());
-#if defined(HAVE_LIBJPEG)
-#if defined(JPEG_LIB_VERSION)
- printf("%u", JPEG_LIB_VERSION);
-#else
- printf("yes");
-#endif
-#else
- printf("none");
-#endif
- printf("\n");
- printf("OS: %s\n" , get_os());
- return 0;
- }
- if(help!=0)
- {
- printf("\nUsage: photorec [/log] [/debug] [/d recup_dir] [file.dd|file.e01|device]\n"\
- " photorec /version\n" \
- "\n" \
- "/log : create a photorec.log file\n" \
- "/debug : add debug information\n" \
- "\n" \
- "PhotoRec searches various file formats (JPEG, Office...), it stores them\n" \
- "in recup_dir directory.\n" \
- "\n" \
- "If you have problems with PhotoRec or bug reports, please contact me.\n");
- return 0;
- }
- screen_buffer_reset();
-#ifdef HAVE_SETLOCALE
- if(run_setlocale>0)
- {
- const char *locale;
- locale = setlocale (LC_ALL, "");
- if (locale==NULL) {
- locale = setlocale (LC_ALL, NULL);
- log_error("Failed to set locale, using default '%s'.\n", locale);
- } else {
- log_info("Using locale '%s'.\n", locale);
- }
- }
-#endif
-#ifdef HAVE_NCURSES
- /* ncurses need locale for correct unicode support */
- if(start_ncurses("PhotoRec", argv[0]))
- return 1;
-#endif
- log_open(logfile, create_log, 1, "PhotoRec", argc, argv);
- log_info("PhotoRec %s, Data Recovery Utility, %s\nChristophe GRENIER <grenier@cgsecurity.org>\nhttp://www.cgsecurity.org\n", VERSION, TESTDISKDATE);
- log_info("OS: %s\n" , get_os());
- log_info("Compiler: %s\n", get_compiler());
- log_info("ext2fs lib: %s, ntfs lib: %s, ewf lib: %s, libjpeg: ",
- td_ext2fs_version(), td_ntfs_version(), td_ewf_version());
-#if defined(HAVE_LIBJPEG)
-#if defined(JPEG_LIB_VERSION)
- log_info("%u", JPEG_LIB_VERSION);
-#else
- log_info("yes");
-#endif
-#else
- log_info("none");
-#endif
- log_info("\n");
-#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(DJGPP)
-#else
-#ifdef HAVE_GETEUID
- if(geteuid()!=0)
- {
- log_warning("User is not root!\n");
- }
-#endif
-#endif
-#ifdef HAVE_NCURSES
- aff_copy(stdscr);
- wmove(stdscr,5,0);
- wprintw(stdscr, "Please wait...\n");
- wrefresh(stdscr);
-#endif
- /* Scan for available device only if no device or image has been supplied in parameter */
- if(list_disk==NULL)
- list_disk=hd_parse(list_disk,verbose,arch,testdisk_mode);
- hd_update_all_geometry(list_disk,0,verbose);
- /* Activate the cache, even if photorec has its own */
- for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
- element_disk->disk=new_diskcache(element_disk->disk,testdisk_mode);
- /* save disk parameters to rapport */
- log_info("Hard disk list\n");
- for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
- {
- disk_t *disk=element_disk->disk;
- if(disk->model==NULL)
- log_info("%s, sector size=%u\n",
- disk->description(disk), disk->sector_size);
- else
- log_info("%s, sector size=%u - %s\n",
- disk->description(disk), disk->sector_size, disk->model);
- }
- log_info("\n");
- file_options_load(list_file_enable);
- use_sudo=do_curses_photorec(verbose, recup_dir, list_disk, list_file_enable, cmd_device, &cmd_run);
-#ifdef HAVE_NCURSES
- end_ncurses();
-#endif
- delete_list_disk(list_disk);
- log_info("PhotoRec exited normally.\n");
- if(log_close()!=0)
- {
- printf("PhotoRec: Log file corrupted!\n");
- }
- else
- {
- printf("PhotoRec exited normally.\n");
- }
-#ifdef SUDO_BIN
- if(use_sudo>0)
- run_sudo(argc, argv);
-#endif
- return 0;
-}
-
-void file_search_footer(file_recovery_t *file_recovery, const unsigned char*footer, const unsigned int footer_length)
-{
- const unsigned int read_size=4096;
- unsigned char*buffer;
- int64_t file_size;
- if(footer_length==0)
- return ;
- buffer=(unsigned char*)MALLOC(read_size+footer_length-1);
- file_size=file_recovery->file_size;
- memset(buffer+read_size,0,footer_length-1);
- do
- {
- int i;
- int taille;
- if(file_size%read_size!=0)
- file_size=file_size-(file_size%read_size);
- else
- file_size-=read_size;
- if(fseek(file_recovery->handle,file_size,SEEK_SET)<0)
- return;
- taille=fread(buffer,1,read_size,file_recovery->handle);
- for(i=taille-1;i>=0;i--)
- {
- if(buffer[i]==footer[0] && memcmp(buffer+i,footer,footer_length)==0)
- {
- file_recovery->file_size=file_size+i+footer_length;
- free(buffer);
- return;
- }
- }
- memcpy(buffer+read_size,buffer,footer_length-1);
- } while(file_size>0);
- file_recovery->file_size=0;
- free(buffer);
-}
-
-void file_search_lc_footer(file_recovery_t *file_recovery, const unsigned char*footer, const unsigned int footer_length)
-{
- const unsigned int read_size=4096;
- unsigned char*buffer;
- int64_t file_size;
- if(footer_length==0)
- return ;
- buffer=(unsigned char*)MALLOC(read_size+footer_length-1);
- file_size=file_recovery->file_size;
- memset(buffer+read_size,0,footer_length-1);
- do
- {
- int i;
- int taille;
- if(file_size%read_size!=0)
- file_size=file_size-(file_size%read_size);
- else
- file_size-=read_size;
- if(fseek(file_recovery->handle,file_size,SEEK_SET)<0)
- return;
- taille=fread(buffer,1,read_size,file_recovery->handle);
- for(i=0;i<taille;i++)
- buffer[i]=tolower(buffer[i]);
- for(i=taille-1;i>=0;i--)
- {
- if(buffer[i]==footer[0] && memcmp(buffer+i,footer,footer_length)==0)
- {
- file_recovery->file_size=file_size+i+footer_length;
- free(buffer);
- return;
- }
- }
- memcpy(buffer+read_size,buffer,footer_length-1);
- } while(file_size>0);
- file_recovery->file_size=0;
- free(buffer);
-}
-
-int data_check_size(const unsigned char *buffer, const unsigned int buffer_size, file_recovery_t *file_recovery)
-{
- if(file_recovery->file_size>=file_recovery->calculated_file_size)
- {
- file_recovery->file_size=file_recovery->calculated_file_size;
- return 2;
- }
- return 1;
-}
-
-void file_check_size(file_recovery_t *file_recovery)
-{
- if(file_recovery->file_size<file_recovery->calculated_file_size)
- file_recovery->file_size=0;
- else
- file_recovery->file_size=file_recovery->calculated_file_size;
-}
-
static void free_list_allocation(alloc_list_t *list_allocation)
{
struct td_list_head *tmp = NULL;
@@ -1522,4 +843,70 @@ void info_list_search_space(const alloc_data_t *list_search_space, const alloc_d
(keep_corrupted_file>0?"but saved":"and rejected"));
}
+static alloc_data_t *file_truncate_aux(alloc_data_t *space, alloc_data_t *file, const uint64_t file_size, const unsigned int sector_size, const unsigned int blocksize)
+{
+ struct td_list_head *tmp;
+ struct td_list_head *next;
+ uint64_t size=0;
+ const uint64_t file_size_on_disk=(file_size+blocksize-1)/blocksize*blocksize;
+ for(tmp=&file->list, next=tmp->next; tmp!=&space->list; tmp=next, next=tmp->next)
+ {
+ alloc_data_t *element=td_list_entry(tmp, alloc_data_t, list);
+ if(size >= file_size)
+ return element;
+ if(element->data>0)
+ {
+ if(size + (element->end-element->start+1) <= file_size_on_disk)
+ {
+ size=size + (element->end-element->start+1);
+ log_info(" %lu-%lu", (unsigned long)(element->start/sector_size), (unsigned long)(element->end/sector_size));
+ td_list_del(tmp);
+ free(element);
+ }
+ else
+ {
+ log_info(" %lu-%lu",
+ (unsigned long)(element->start/sector_size),
+ (unsigned long)((element->start + file_size_on_disk - size - 1)/sector_size));
+ element->start+=file_size_on_disk - size;
+ element->file_stat=NULL;
+ element->data=1;
+ return element;
+ }
+ }
+ else
+ {
+ log_info(" (%lu-%lu)", (unsigned long)(element->start/sector_size), (unsigned long)(element->end/sector_size));
+ td_list_del(tmp);
+ free(element);
+ }
+ }
+ return space;
+}
+alloc_data_t *file_truncate(alloc_data_t *space, file_recovery_t *file, const unsigned int sector_size, const unsigned int blocksize)
+{
+ alloc_data_t *spacenext;
+ alloc_data_t *datanext;
+ if(file->filename!=NULL)
+ log_info("%s\t", file->filename);
+ else
+ log_info("?\t");
+ spacenext=file_truncate_aux(space, file->loc, file->file_size, sector_size, blocksize);
+ log_info("\n");
+ datanext=td_list_entry(&spacenext->list.next, alloc_data_t, list);
+ return datanext;
+}
+
+void free_search_space(alloc_data_t *list_search_space)
+{
+ struct td_list_head *search_walker = NULL;
+ struct td_list_head *search_walker_next = NULL;
+ td_list_for_each_safe(search_walker,search_walker_next,&list_search_space->list)
+ {
+ alloc_data_t *current_search_space;
+ current_search_space=td_list_entry(search_walker, alloc_data_t, list);
+ td_list_del(search_walker);
+ free(current_search_space);
+ }
+}
diff --git a/src/photorec.h b/src/photorec.h
index 4c0567d..81ae276 100644
--- a/src/photorec.h
+++ b/src/photorec.h
@@ -21,6 +21,9 @@
*/
#define MAX_FILES_PER_DIR 500
#define DEFAULT_RECUP_DIR "recup_dir"
+#ifdef __cplusplus
+extern "C" {
+#endif
enum photorec_status { STATUS_FIND_OFFSET, STATUS_EXT2_ON, STATUS_EXT2_ON_BF, STATUS_EXT2_OFF, STATUS_EXT2_OFF_BF, STATUS_EXT2_ON_SAVE_EVERYTHING, STATUS_EXT2_OFF_SAVE_EVERYTHING, STATUS_QUIT };
typedef enum photorec_status photorec_status_t;
@@ -56,3 +59,9 @@ int sorfile_stat_ts(const void *p1, const void *p2);
unsigned int photorec_mkdir(const char *recup_dir, const unsigned int initial_dir_num);
void list_space_used(const file_recovery_t *file_recovery, const unsigned int sector_size);
void info_list_search_space(const alloc_data_t *list_search_space, const alloc_data_t *current_search_space, const unsigned int sector_size, const int keep_corrupted_file, const int verbose);
+alloc_data_t *file_truncate(alloc_data_t *space, file_recovery_t *file, const unsigned int sector_size, const unsigned int blocksize);
+void free_search_space(alloc_data_t *list_search_space);
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
+
diff --git a/src/phrecn.c b/src/phrecn.c
index 7c980e7..12600e6 100644
--- a/src/phrecn.c
+++ b/src/phrecn.c
@@ -60,6 +60,7 @@
#include "phrecn.h"
#include "partauto.h"
#include "log.h"
+#include "log_part.h"
#include "hdaccess.h"
#include "file_tar.h"
#include "phcfg.h"
@@ -67,6 +68,7 @@
#include "pdisksel.h"
#include "pblocksize.h"
#include "pfree_whole.h"
+#include "askloc.h"
/* #define DEBUG */
/* #define DEBUG_GET_NEXT_SECTOR */
@@ -285,18 +287,6 @@ static int photorec_progressbar(WINDOW *window, const unsigned int pass, const p
wrefresh(window);
return check_enter_key_or_s(window);
}
-
-void aff_copy(WINDOW *window)
-{
- wclear(window);
- keypad(window, TRUE); /* Need it to get arrow key */
- wmove(window,0,0);
- wprintw(window, "PhotoRec %s, Data Recovery Utility, %s\n",VERSION,TESTDISKDATE);
- wmove(window,1,0);
- wprintw(window, "Christophe GRENIER <grenier@cgsecurity.org>");
- wmove(window,2,0);
- wprintw(window, "http://www.cgsecurity.org");
-}
#endif
static void set_filename(file_recovery_t *file_recovery, const char *recup_dir, const unsigned int dir_num, const disk_t *disk, const partition_t *partition, const int broken)
@@ -722,61 +712,6 @@ static alloc_data_t *file_add_data(alloc_data_t *data, const uint64_t offset, co
}
}
-static alloc_data_t *file_truncate_aux(alloc_data_t *space, alloc_data_t *file, const uint64_t file_size, const unsigned int sector_size, const unsigned int blocksize)
-{
- struct td_list_head *tmp;
- struct td_list_head *next;
- uint64_t size=0;
- const uint64_t file_size_on_disk=(file_size+blocksize-1)/blocksize*blocksize;
- for(tmp=&file->list, next=tmp->next; tmp!=&space->list; tmp=next, next=tmp->next)
- {
- alloc_data_t *element=td_list_entry(tmp, alloc_data_t, list);
- if(size >= file_size)
- return element;
- if(element->data>0)
- {
- if(size + (element->end-element->start+1) <= file_size_on_disk)
- {
- size=size + (element->end-element->start+1);
- log_info(" %lu-%lu", (unsigned long)(element->start/sector_size), (unsigned long)(element->end/sector_size));
- td_list_del(tmp);
- free(element);
- }
- else
- {
- log_info(" %lu-%lu",
- (unsigned long)(element->start/sector_size),
- (unsigned long)((element->start + file_size_on_disk - size - 1)/sector_size));
- element->start+=file_size_on_disk - size;
- element->file_stat=NULL;
- element->data=1;
- return element;
- }
- }
- else
- {
- log_info(" (%lu-%lu)", (unsigned long)(element->start/sector_size), (unsigned long)(element->end/sector_size));
- td_list_del(tmp);
- free(element);
- }
- }
- return space;
-}
-
-alloc_data_t *file_truncate(alloc_data_t *space, file_recovery_t *file, const unsigned int sector_size, const unsigned int blocksize)
-{
- alloc_data_t *spacenext;
- alloc_data_t *datanext;
- if(file->filename!=NULL)
- log_info("%s\t", file->filename);
- else
- log_info("?\t");
- spacenext=file_truncate_aux(space, file->loc, file->file_size, sector_size, blocksize);
- log_info("\n");
- datanext=td_list_entry(&spacenext->list.next, alloc_data_t, list);
- return datanext;
-}
-
static int photorec_find_blocksize(disk_t *disk_car, partition_t *partition, const int verbose, const int interface, file_stat_t *file_stats, unsigned int *file_nbr, unsigned int *blocksize, alloc_data_t *list_search_space, const time_t real_start_time, const unsigned int expert)
{
uint64_t offset=0;
@@ -1267,20 +1202,6 @@ static void recovery_finished(const unsigned int file_nbr, const char *recup_dir
}
#endif
-
-void free_search_space(alloc_data_t *list_search_space)
-{
- struct td_list_head *search_walker = NULL;
- struct td_list_head *search_walker_next = NULL;
- td_list_for_each_safe(search_walker,search_walker_next,&list_search_space->list)
- {
- alloc_data_t *current_search_space;
- current_search_space=td_list_entry(search_walker, alloc_data_t, list);
- td_list_del(search_walker);
- free(current_search_space);
- }
-}
-
#if defined(HAVE_NCURSES) && (defined(__CYGWIN__) || defined(__MINGW32__))
static int interface_cannot_create_file(void)
{
diff --git a/src/phrecn.h b/src/phrecn.h
index 984c5cc..0f3c3d8 100644
--- a/src/phrecn.h
+++ b/src/phrecn.h
@@ -19,8 +19,14 @@
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
int photorec(disk_t *disk_car, partition_t *partition, const int verbose, const int paranoid, char *recup_dir, const int keep_corrupted_file, const int interface, file_enable_t *file_enable, const unsigned int mode_ext2, char **current_cmd, alloc_data_t *list_search_space, unsigned int blocksize, const unsigned int expert, const unsigned int lowmem, const unsigned int carve_free_space_only);
void interface_file_select(file_enable_t *files_enable, char**current_cmd);
void interface_options_photorec(int *paranoid, int *allow_partial_last_cylinder, int *keep_corrupted_file, unsigned int *mode_ext2, unsigned int *expert, unsigned int *lowmem, char**current_cmd);
-void free_search_space(alloc_data_t *list_search_space);
-alloc_data_t *file_truncate(alloc_data_t *space, file_recovery_t *file, const unsigned int sector_size, const unsigned int blocksize);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/ppartsel.c b/src/ppartsel.c
index f22b9d6..672b0c2 100644
--- a/src/ppartsel.c
+++ b/src/ppartsel.c
@@ -41,16 +41,22 @@
#include "fnctdsk.h"
#include "dir.h"
#include "list.h"
-#include "chgtype.h"
#include "lang.h"
#include "filegen.h"
#include "photorec.h"
#include "phrecn.h"
#include "log.h"
+#include "log_part.h"
#include "hdaccess.h"
#include "ext2grp.h"
#include "pfree_whole.h"
#include "ppartsel.h"
+#include "askloc.h"
+#include "geometry.h"
+#include "addpart.h"
+#include "intrfn.h"
+
+extern const arch_fnct_t arch_none;
enum { INIT_SPACE_WHOLE, INIT_SPACE_PREINIT, INIT_SPACE_EXT2_GROUP, INIT_SPACE_EXT2_INODE };
@@ -149,7 +155,11 @@ void menu_photorec(disk_t *disk_car, const int verbose, const char *recup_dir, f
res=(char *)recup_dir;
else
{
+#ifdef HAVE_NCURSES
res=ask_location("Do you want to save recovered files in %s%s ? [Y/N]\nDo not choose to write the files to the same partition they were stored on.","");
+#else
+ res=get_default_location();
+#endif
if(res!=NULL)
{
char *new_recup_dir=(char *)MALLOC(strlen(res)+1+strlen(DEFAULT_RECUP_DIR)+1);
@@ -167,10 +177,14 @@ void menu_photorec(disk_t *disk_car, const int verbose, const char *recup_dir, f
if(mode_init_space==INIT_SPACE_EXT2_GROUP)
{
blocksize=ext2_fix_group(list_search_space, disk_car, partition);
+ if(blocksize==0)
+ display_message("Not a valid ext2/ext3/ext4 filesystem");
}
else if(mode_init_space==INIT_SPACE_EXT2_INODE)
{
blocksize=ext2_fix_inode(list_search_space, disk_car, partition);
+ if(blocksize==0)
+ display_message("Not a valid ext2/ext3/ext4 filesystem");
}
if(td_list_empty(&list_search_space->list))
{
@@ -416,9 +430,9 @@ void menu_photorec(disk_t *disk_car, const int verbose, const char *recup_dir, f
break;
case 'a':
case 'A':
- if(disk_car->arch->add_partition!=NULL)
+ if(disk_car->arch != &arch_none)
{
- list_part=disk_car->arch->add_partition(disk_car,list_part, verbose, current_cmd);
+ list_part=add_partition(disk_car, list_part, verbose, current_cmd);
current_element=list_part;
current_element_num=0;
}
diff --git a/src/ppartsel.h b/src/ppartsel.h
index 0ece3d2..8ab5410 100644
--- a/src/ppartsel.h
+++ b/src/ppartsel.h
@@ -19,6 +19,12 @@
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-void menu_photorec(disk_t *disk_car, const int verbose, const char *recup_dir, file_enable_t *file_enable, char **current_cmd, alloc_data_t*list_search_space);
+#ifdef __cplusplus
+extern "C" {
+#endif
+void menu_photorec(disk_t *disk_car, const int verbose, const char *recup_dir, file_enable_t *file_enable, char **current_cmd, alloc_data_t*list_search_space);
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/rfs.c b/src/rfs.c
index 9f98c1b..19efd7c 100644
--- a/src/rfs.c
+++ b/src/rfs.c
@@ -24,6 +24,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
diff --git a/src/sun.c b/src/sun.c
index 89fa673..b5400f6 100644
--- a/src/sun.c
+++ b/src/sun.c
@@ -24,6 +24,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -35,6 +36,7 @@
#include "sun.h"
#include "fnctdsk.h"
#include "log.h"
+#include "log_part.h"
#define SUN_LABEL_MAGIC 0xDABE
extern const arch_fnct_t arch_sun;
diff --git a/src/sysv.c b/src/sysv.c
index f6bd56a..000b4d3 100644
--- a/src/sysv.c
+++ b/src/sysv.c
@@ -24,6 +24,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
diff --git a/src/tanalyse.c b/src/tanalyse.c
index 0b0743e..1de4a44 100644
--- a/src/tanalyse.c
+++ b/src/tanalyse.c
@@ -2,7 +2,7 @@
File: tanalyse.c
- Copyright (C) 2008 Christophe GRENIER <grenier@cgsecurity.org>
+ Copyright (C) 2009 Christophe GRENIER <grenier@cgsecurity.org>
This software is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,6 +23,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
@@ -30,15 +31,13 @@
#include "common.h"
#include "lang.h"
#include "intrf.h"
-#ifdef HAVE_NCURSES
#include "intrfn.h"
-#else
-#include <stdio.h>
-#endif
#include "savehdr.h"
#include "log.h"
#include "tanalyse.h"
+extern const arch_fnct_t arch_none;
+
static list_part_t *interface_analyse_ncurses(disk_t *disk_car, const int verbose, const int saveheader, char**current_cmd)
{
list_part_t *list_part;
@@ -91,7 +90,7 @@ static list_part_t *interface_analyse_ncurses(disk_t *disk_car, const int verbos
log_flush();
#ifdef HAVE_NCURSES
command=screen_buffer_display(stdscr,
- (list_part!=NULL && disk_car->arch->add_partition!=NULL?"QB":"Q"),
+ (list_part!=NULL && disk_car->arch != &arch_none?"QB":"Q"),
menuAnalyse);
#endif
}
diff --git a/src/tbanner.c b/src/tbanner.c
new file mode 100644
index 0000000..45fc4ab
--- /dev/null
+++ b/src/tbanner.c
@@ -0,0 +1,44 @@
+/*
+
+ File: tbanner.c
+
+ Copyright (C) 2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef HAVE_NCURSES
+#include "types.h"
+#include "common.h"
+#include "testdisk.h"
+#include "intrf.h"
+#include "intrfn.h"
+
+void aff_copy(WINDOW *window)
+{
+ wclear(window);
+ keypad(window, TRUE); /* Need it to get arrow key */
+ wmove(window,0,0);
+ wprintw(window, "TestDisk %s, Data Recovery Utility, %s",VERSION,TESTDISKDATE);
+ wmove(window,1,0);
+ wprintw(window,"Christophe GRENIER <grenier@cgsecurity.org>");
+ wmove(window,2,0);
+ wprintw(window,"http://www.cgsecurity.org");
+}
+#endif
diff --git a/src/tdiskop.c b/src/tdiskop.c
index e6662b7..c2bfdf1 100644
--- a/src/tdiskop.c
+++ b/src/tdiskop.c
@@ -38,7 +38,6 @@
#include "fnctdsk.h"
#include "testdisk.h"
#include "adv.h"
-#include "chgtype.h"
#include "edit.h"
#include "log.h"
#include "hdaccess.h"
@@ -47,6 +46,7 @@
#include "tmbrcode.h"
#include "tdelete.h"
#include "tdiskop.h"
+#include "geometry.h"
extern const arch_fnct_t arch_i386;
#define INTER_DISK_X 0
diff --git a/src/tdisksel.c b/src/tdisksel.c
index dadf1e1..faf7426 100644
--- a/src/tdisksel.c
+++ b/src/tdisksel.c
@@ -47,6 +47,9 @@
#include "tdiskop.h"
#include "tdisksel.h"
#include "hidden.h"
+#include "hiddenn.h"
+#include "nodisk.h"
+#include "chgtypen.h"
#ifdef HAVE_NCURSES
#define NBR_DISK_MAX (LINES-6-8)
@@ -73,7 +76,8 @@ static int testdisk_disk_selection_ncurses(int verbose,int dump_ind, const list_
};
if(list_disk==NULL)
{
- use_sudo=intrf_no_disk("TestDisk");
+ log_critical("No disk found\n");
+ use_sudo=intrf_no_disk_ncurses("TestDisk");
}
if(list_disk==NULL || use_sudo>0)
return use_sudo;
@@ -179,7 +183,7 @@ static int testdisk_disk_selection_ncurses(int verbose,int dump_ind, const list_
autoset_unit(disk);
if(interface_check_disk_capacity(disk)==0 &&
interface_check_disk_access(disk, current_cmd)==0 &&
- interface_check_hidden(disk, current_cmd)==0 &&
+ (!is_hpa_or_dco(disk) || interface_check_hidden_ncurses(disk)==0) &&
interface_partition_type(disk, verbose, current_cmd)==0)
{
if(menu_disk(disk, verbose, dump_ind, saveheader, current_cmd))
@@ -215,7 +219,8 @@ static int testdisk_disk_selection_cli(int verbose,int dump_ind, const list_disk
current_disk=list_disk;
if(current_disk==NULL)
{
- return intrf_no_disk("TestDisk");
+ log_critical("No disk found\n");
+ return 0;
}
if(*current_cmd!=NULL)
{
diff --git a/src/testdisk.c b/src/testdisk.c
index 7cfb055..2edd249 100644
--- a/src/testdisk.c
+++ b/src/testdisk.c
@@ -79,20 +79,6 @@ void sighup_hdlr(int shup)
}
#endif
-#ifdef HAVE_NCURSES
-void aff_copy(WINDOW *window)
-{
- wclear(window);
- keypad(window, TRUE); /* Need it to get arrow key */
- wmove(window,0,0);
- wprintw(window, "TestDisk %s, Data Recovery Utility, %s",VERSION,TESTDISKDATE);
- wmove(window,1,0);
- wprintw(window,"Christophe GRENIER <grenier@cgsecurity.org>");
- wmove(window,2,0);
- wprintw(window,"http://www.cgsecurity.org");
-}
-#endif
-
int main( int argc, char **argv )
{
int i;
@@ -123,7 +109,8 @@ int main( int argc, char **argv )
#ifdef HAVE_SIGACTION
struct sigaction action;
#endif
- /* random (weak is ok) is need fot GPT */
+ FILE *log_handle=NULL;
+ /* srand needed for GPT creation (weak is ok) */
srand(time(NULL));
#ifdef HAVE_SIGACTION
/* set up the signal handler for SIGHUP */
@@ -150,13 +137,13 @@ int main( int argc, char **argv )
else if((strcmp(argv[i],"/log")==0) ||(strcmp(argv[i],"-log")==0))
{
if(create_log==TD_LOG_NONE)
- create_log=log_open(logfile, TD_LOG_APPEND, 0, "TestDisk", argc, argv);
+ create_log=TD_LOG_APPEND;
}
else if((strcmp(argv[i],"/debug")==0) || (strcmp(argv[i],"-debug")==0))
{
verbose++;
if(create_log==TD_LOG_NONE)
- create_log=log_open(logfile, TD_LOG_APPEND, 0, "TestDisk", argc, argv);
+ create_log=TD_LOG_APPEND;
}
else if((strcmp(argv[i],"/all")==0) || (strcmp(argv[i],"-all")==0))
testdisk_mode|=TESTDISK_O_ALL;
@@ -287,6 +274,8 @@ int main( int argc, char **argv )
delete_list_disk(list_disk);
return 0;
}
+ if(create_log!=TD_LOG_NONE)
+ log_handle=log_open(logfile, create_log);
#ifdef HAVE_SETLOCALE
if(run_setlocale>0)
{
@@ -300,17 +289,45 @@ int main( int argc, char **argv )
}
}
#endif
+ if(create_log!=TD_LOG_NONE && log_handle==NULL)
+ log_handle=log_open_default(logfile, create_log);
#ifdef HAVE_NCURSES
/* ncurses need locale for correct unicode support */
if(start_ncurses("TestDisk",argv[0]))
return 1;
-#endif
if(argc==1 && create_log==TD_LOG_NONE)
{
verbose=1;
create_log=ask_testdisk_log_creation();
+ if(create_log==TD_LOG_CREATE || create_log==TD_LOG_APPEND)
+ log_handle=log_open(logfile, create_log);
+ }
+ {
+ const char*filename=logfile;
+ while(create_log!=TD_LOG_NONE && log_handle==NULL)
+ {
+ filename=ask_log_location(filename);
+ if(filename!=NULL)
+ log_handle=log_open(filename, create_log);
+ else
+ create_log=TD_LOG_NONE;
+ }
+ }
+#endif
+ if(log_handle!=NULL)
+ {
+ time_t my_time;
+#ifdef HAVE_DUP2
+ dup2(fileno(log_handle),2);
+#endif
+ my_time=time(NULL);
+ log_info("\n\n%s",ctime(&my_time));
+ log_info("Command line: PhotoRec");
+ for(i=1;i<argc;i++)
+ log_info(" %s", argv[i]);
+ log_info("\n\n");
+ log_flush();
}
- create_log=log_open(logfile, create_log, 1, "TestDisk", argc, argv);
log_info("TestDisk %s, Data Recovery Utility, %s\nChristophe GRENIER <grenier@cgsecurity.org>\nhttp://www.cgsecurity.org\n", VERSION, TESTDISKDATE);
log_info("OS: %s\n" , get_os());
log_info("Compiler: %s\n", get_compiler());
diff --git a/src/thfs.c b/src/thfs.c
index 4d0485e..f5f047a 100644
--- a/src/thfs.c
+++ b/src/thfs.c
@@ -22,7 +22,8 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-
+
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -38,6 +39,7 @@
#include "hfs.h"
#include "hfsp.h"
#include "log.h"
+#include "log_part.h"
#include "thfs.h"
#ifdef HAVE_NCURSES
@@ -214,6 +216,7 @@ int HFS_HFSP_boot_sector(disk_t *disk_car, partition_t *partition, const int ver
free(buffer_backup_bs);
return 0;
case 'O': /* O : copy original superblock over backup boot */
+#ifdef HAVE_NCURSES
if(ask_confirmation("Copy original HFS/HFS+ volume header over backup, confirm ? (Y/N)")!=0)
{
log_info("copy original superblock over backup boot\n");
@@ -224,8 +227,10 @@ int HFS_HFSP_boot_sector(disk_t *disk_car, partition_t *partition, const int ver
disk_car->sync(disk_car);
rescan=1;
}
+#endif
break;
case 'B': /* B : copy backup superblock over main superblock */
+#ifdef HAVE_NCURSES
if(ask_confirmation("Copy backup HFS/HFS+ volume header over main volume header, confirm ? (Y/N)")!=0)
{
log_info("copy backup superblock over main superblock\n");
@@ -236,6 +241,7 @@ int HFS_HFSP_boot_sector(disk_t *disk_car, partition_t *partition, const int ver
disk_car->sync(disk_car);
rescan=1;
}
+#endif
break;
case 'D':
hfs_dump(disk_car, partition, buffer_bs, buffer_backup_bs);
diff --git a/src/tload.c b/src/tload.c
index 29b4480..2538e4e 100644
--- a/src/tload.c
+++ b/src/tload.c
@@ -46,6 +46,7 @@
#include "fnctdsk.h"
#include "savehdr.h"
#include "log.h"
+#include "log_part.h"
#include "tload.h"
#ifdef HAVE_NCURSES
diff --git a/src/tntfs.c b/src/tntfs.c
index 88095a0..34ecafa 100644
--- a/src/tntfs.c
+++ b/src/tntfs.c
@@ -23,6 +23,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -38,6 +39,7 @@
#include "ntfs.h"
#include "io_redir.h"
#include "log.h"
+#include "log_part.h"
#include "tntfs.h"
#ifdef HAVE_NCURSES
@@ -239,6 +241,7 @@ int ntfs_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose
free(buffer_backup_bs);
return 0;
case 'O': /* O : copy original boot sector over backup boot */
+#ifdef HAVE_NCURSES
if(ask_confirmation("Copy original NTFS boot sector over backup boot, confirm ? (Y/N)")!=0)
{
log_info("copy original boot sector over backup boot\n");
@@ -249,8 +252,10 @@ int ntfs_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose
disk_car->sync(disk_car);
rescan=1;
}
+#endif
break;
case 'B': /* B : copy backup boot sector over boot sector */
+#ifdef HAVE_NCURSES
if(ask_confirmation("Copy backup NTFS boot sector over boot sector, confirm ? (Y/N)")!=0)
{
log_info("copy backup boot sector over boot sector\n");
@@ -261,6 +266,7 @@ int ntfs_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose
disk_car->sync(disk_car);
rescan=1;
}
+#endif
break;
case 'L':
if(strchr(options,'O')==NULL && strchr(options,'B')!=NULL)
diff --git a/src/ufs.c b/src/ufs.c
index 0f3cad0..84d1a01 100644
--- a/src/ufs.c
+++ b/src/ufs.c
@@ -24,6 +24,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
diff --git a/src/xfs.c b/src/xfs.c
index e7149e2..c461ad6 100644
--- a/src/xfs.c
+++ b/src/xfs.c
@@ -24,6 +24,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif