Wednesday, August 29, 2018

i pool in a hotel with tell you somthing about finding a real bargain about your health not a bone insulation problem with walking and driving in cars and them taking me to the company every day of the week and making me talk through a building that looks the the gambit and the companies appearance in accessory to its surface its hard surface actually, rock, and its neon light bulbs are really just another publisher gambit for a pool to be in it and only pools are found in hotels and there is like a gambit about tools and a murder company for BAD LITTLE BOYS?! what the fuck does this mean, im like a seliacs dissertation ready to happen im running linux i went to 3 different high schools in the same area on the east coast and theirs like gambit company gone wrong again.... and im like full of good oel' words to say when theirs like still dead brain and pus in my brain from when the cop shot into my body in 2003 when the nsa kid CHRIS LEIDIG was in my apartment becuase he told me his brother didnt let him live with him and he told he was from hawaii and he worked for the nsa and he was only 17 at the time and he does extasy because i took half of the pill and he took the other half when i got off of work that day <-- i just at the time graduated from bryan station magnet high school in lexington kentucky and mY brother told me i caoulndt live with him anymore either and he was really weord with me and hes got like 3 kids a wife and some mason girl <-- her dad was a free mason and they were from wast viginia and like he took me out of the maryland high in 2000 and i went to pennsyvania high school in muncy, pa and i turned 16 and then he graduated from penn tech with a construction management degree and she was a chemist working for merck pharmaceuticals and like the gambit closes down over the assumption, what the hell does merck have to fucking do with hospital poisens gambits when their actually trying to loop the gambit system over having a girl friend and i didnt know i would fucking MEET her when i showed up in maryland again at my dads house after i graduated and my brother dopped me off in 2002 and i met her at borders and she worked there and i knew here from church.... like serisously their are like so many ways i publish really ideas and make great assumptions out of computer schience and i am able to work very construcelly with it, linux operating system kernel developemnt over you know, publisher years of profeessions over linguistic aptitude and everyone talks like a british fucking 3 year old alien to hispital assumptions and its like they dont even know church was run by a bunch a masons already makeing whores out of girls with car gambits, school gambits, book publisher gambit, entertainment gambtis, tv memory gambits, consumer __TOTIENT__ gambits and its like its antoher loop on really linguistics education and its like im being poisend like i used to work for the portigul navy to get really interested abou the american spanish whore portiguLL like ive like two things to make up for about merck, one assumption they are a SKYLARK gambit company, but the gambit works the bath systemic operator over time, my mom is a french wannabe, simply becuase you know shes a warlord but shes NOT shes just a warlord, ok... so like im not a warlord but i have warlord money from gambit computer apptitude industry and so do the doctors and the cops,,, WHOS THE REAL WARLORD here () =
nenducki told the maryland coptic' <<stream pipe "you swallowed his lung and dektscx'tr and already boiled him to death in the smiths'bargain" <-- the chateu baslica rock woud stepper with a {RICH HARROWER BILL PAYMENT INSURANCE NUNNER'y <<_MARYLAND DRUNK CARD SOUP CONSUMAAR__sz bean government murders"} <<MURDER HALGOEE ASSUMERS_zsizillen lessons again with poisen IADHE COPTICS ATTACHMENTS CORPSATED BULB CORPORATION BASILICA SUN LOId consume mars DRAFT YRUNDEE AMAURA NORTH AMERICA BILL PAYMENT SCHEDULE << THE PAYMENY SYSTEM IS STILL CLOnED __i really cant believe they were throwing a basillica toe'rush money at me with richie still in my NEC totient pluto bend with my pluto iadhe car song and richie and me still talk over the cloda cloud and hes only 3 years old and on summer vacation right now and im like lemer coptics over north america french chateu neuman nixon roosevelt and like there is cars bombing the fuck out of the house and they were about to poisen me again with a bone loader again and there is like masons in the house with iadhe'r bones riddling another LEROY BURLOWS black man that looks like a LOREN HAYES girl over lisas frined money like they already make nixon money out of the consumer money and im being thrown in a dirt ram totient over gopher lilly html and its like the tonight file over the mountain and the hospital is trying to hide women that are clones in the hospital and there is some like american aft're_wecan money for some mason clones going like virginia money on the house draft rogers temperture () < filler prudence _WHAT_IS_HAS_IN_A __SCALE COMPANY __I THINK THIS MEANS THEY WOULD BE SCALING MONEY WITH BLIGHT IADHERS FARMER MONEY AND LIKE SOME THETLER 61 < assumer you were a husband for years as a hospital doctor having dexterity problems to help the baby out with birth ?! there is like, umm, a problem with my skull and my leg bones and lisas too, my skull, on the back of it had a divet in it and i think the doctor pushed my soft skull in with his finger and i know he really did but i dont remember it and my dad and mom told me alot of times when i ask them when i get moolaria about my divet in my school when ime around them about the well in words "do you remember when i was born what i t was like " and they told me i was born premuture 2 months and i got extremely sick in the hospotal and said, my dad, that i was extrememly sick like i was going to die out of the womb in the hospital and somehow the moolaria of a womans birth, my mom namel'Y was, that the idea is to put the baby in the incubater and let the baby sleep but when you see american woman have babies theirs always holding the baby right out of the womb and noone has the hole in their skull like me and i think there is a big mix up and the employees here dont add up to how i talk and i assume im talking to somone i dont know so like i have to type __ how i write so im not sure whats going on, my family is a little woird but im not, i dont know whats going on but i need to talk to the right person because when i type i can get a good totient mix on how i am to approach the well of words to say to someone about it but it still doesnt seem like i can say it to the employees becuase they act very strange about giving out the pills and there is one specific pill called olanszpine that is really poisen and the emplayees dont know it and i sit dont the employee gets it out of the closet behind the table where i sit at in the small dining room (a nixon house from the 40s) and he comes over and i get terrified like there about to poisen me again and i cant say anything about it and the cop shoots into my body and fucking shoots into my muscles so bad its like hes trying to murder me with it and like theres cars everywhere fucking riding over the concrete and the only way a cop and a doctor can hide their evidence is to shoot me with a totient that was already from another assumer industry that i can really assume mean the cops and the doctors hid evidence with a gambit from companies and its like every driver ans social security numbers in maryland, i live right by the nsa, an nsa boy from when i was 18 made me take ecstasy when i didnt want to and i asked him what it was going to do like i said what does it do to you is what i really unbecomingly said when i got home from the pizza shop and he said its good just do it so i did and the cop shot into my body and was trying to hide nec electrician money with a chair and a power source to my computer and this was back in 2003 when i was dating lisa and only dated her for 1 and half years and i really didnt expect to meet her anayway and i went to the same church with her when i was 12 and 13, i even went to the same christian school with her! i mean i cant explain what their doing, when (anyone reading this) comes to reading my reasearch and attempts to come up with building up to published my dream of at least writing a book this looks like its exactly publisher money and their all like draft a liying goverment hiding lies again and their nothing but a gambit company all over america and its like im not a realy american or something WHAT THE FUCK!

Thursday, August 23, 2018

#include <unistd.h>
#include <dirent.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/time.h>
#include <sys/types.h>
#include <ncurses.h>
#include <menu.h>
#include <sys/time.h>
#include <time.h>

#include "cpdu.h"
#include "cipher.h"
#include "var.h"
#include "options.h"
#include "error.h"
#include "ciphervar.h"
#include "sha1.h"
#include "zlf.h"
#include "bzf.h"

/* real eople uedol arhu germ self proteoma */
/*spec lom is not relling me anything but bullshit grass moronisms'
 they've sv lalmoline the river naga "their not the hospital and their not the police <-- barnicule phass stellars notinggoing highway
 all uears over the march, he shot the hospoital down with portigul rock */
/* a chateu rocke'r remains an otter for long periouds of aweona */
/* its ferars f again lie its the next c <-- sasachurn milling halogee in an again <-- product value hill drafts thank the lord! */
/* m in l zime product lilly: --> he sayis "dont be a promenlt" I SAID"" "what was he doing, when he said dont be a promelt" <-- amean puul'r mod box n martydome "DONT BE A PROMELT ZIME?!? <-- drag merlo doesnt even solve it, its like being in heaven and having a homophobic opeind of opinions by being a rich homophonbia in america in a house" <-- how in the hell does that mean double negatives and being corousan of a home ? <-- it doesnt homes dont exist!... but in montantana ballr club mountain homes are chateu promelted with think that arent likely the occlusion of at least fitted, having no resistence of a child <-- hey cmon, homes arent children, they are sadistic ruled out hard {} <-faysower arrest halogee and also children are like much shorter than __BEING GROWN UP__ <-- this isnt god, this is america __I GUESS GERMANY GOT RULED OUT TOO, WHAT THE FUCK! */

/* thetlr adhe <-- where was the NEC interview, ... in a NEC baller club, the murder kind --> "see downward causation for population lr field gambit fieldo of professions, and believe me you wont get anything but a portigul navy gambit effexor murder culture out of it <-- they murdered me alread'y with this shit !*/

typedef enum
{    cpdu_archive=0,
    cpdu_encrypted=1,
    cpdu_backup_archive=2,
    cpdu_none =3
} cpdu_file_type;

/* -- start main -- */

//#define size_t unsigned long long

/* -- cpdu.c variables -- */
unsigned char* passbuf=NULL;
unsigned long* passbufsz=NULL;
int margc;
char **margv;
char *archive_name = NULL;
static int file_processed_count = 0;
unsigned char check_hash[SHA1_DIGESTSIZE];
int normv_int = 0;
char *curfile, *curfileout;
size_t wpsz_int = 0, wpdn_int = 0, wpszdn_int = 0;
char *topdir = NULL;
char *topentry = NULL;
char masterkeydbfilename[200];
char *archive_ext_set_file = "set_archive_ext\0";
char *cur_ext = ".cpdu.package\0";
unsigned long long session_total_size = 0;
unsigned long long session_current_size = 0;
char** entrylist = NULL;
int entrycounter = 0;
int entrylist_size = 0;
int entrylist_count = 0;
int got_backup_archive = 0;
char** il;
int ilcnt;
int ilsz;
char** choices;
int access_lock_warning = 0;
const char *processedlist_filename = "/.cpdu_processedlist";
int hottrackcount = 0;
typedef struct {
    char *name;
    unsigned long count;
    unsigned long dircount;
} archive_entry;

archive_entry **archive_entry_status_list;
unsigned long archive_entry_status_list_count = 0;
unsigned long archive_entry_status_list_size = 0;
unsigned long asel_counter = 0;

/* -- cpdu.c variables -- */

/* -- cpdu.c constants -- */
const char cpdu_archive_hdr[] = "cpdu_encrypted_archive";
const char cpdu_encrypt_hdr[] = "cpdu_encrypted_file";
const char cpdu_archive_backup_hdr[] = "cpdu_backup_archive";

/* -- cpdu.c constants -- */

/* -- function prototypes -- */
void chmod_secure_file(char *file);
void chmod_unsecure_file(char *file);
void chmod_secure_mykeydir();
void chmod_unsecure_mykeydir();
char *make_mykeydir();
char *make_mydir();
char **getdir(char *dirname, int recurse);
size_t init_file_encrypt(void* pctx, FILE* in, FILE* out);
size_t init_file_decrypt(void* pctx, FILE* in, FILE* out);
int getpassword(int ciphermode, char *prompt);
int read_stdin_to_fd(int fd_out);
int write_fd_to_stdout(int fd_in);
void _secureclearpassbuf();
void secure_local_key_set();
void secure_local_key_get();
char *get_current_dir_name(){return getenv("PWD");}
int cpdu_archive_unload(char* larchive_name);
int cpdu_archive_load(char* larchive_name);
unsigned char* sha1_get_file_hash(char* file);
char *make_myrecoverdir();
char *rm_relative_path(char* name);
int copy_file(char *file, char* new);
char *mk_recoverdb_entry(char *entry);
int addkey_to_masterkeylist();
int getkey_from_masterkeylist(char *digest);
void status_print_session_done();
void cpdu_signal_sigint(int signal);
cpdu_file_type cpdu_query_file_type(char *file);
int generate_keyfile(char *keyfile, size_t fsize);
unsigned char *crunch_key(unsigned char *xkey, unsigned long xkeysize, unsigned char *keybuf, unsigned long outsize);
int read_key_from_keyfile(char *keyfile, unsigned char *keybuf, unsigned long keysize);
size_t encrypt_header(void *ctx, FILE* fs);
int decrypt_header(FILE* fs);
void secure_commit_key();
char *clf_strip_path_dlmtr(char* name);
char* get_archive_ext() { return cur_ext; } /* FIXME: @ */
void status_print_file_done();
void print_archive_list(char* larchive_name);
char** menu_getdir(char* dirname);
int _purge_fillentrylist();
int _reseal_fillentrylist();
void menu_directory_select();
int print_processed_list();
void write_recovery_log(int argc, char** argv);
void add_to_processedlist(char* string_filename);
void menu_();

void archive_access_error(char* file)
{
    int r;
    r = access(file, R_OK|W_OK);

    if ( r == -1 ) {
        merror("insufficient permissions on file %s: %s\n", file, strerror(errno));
        merror("session/archive error, incomplete session due to permissions error on file '%s'\n", file);
        exit(0);
    }
}

int diff(int a, int b)
{
    if ( a > b ) return a - b;
    if ( b > a ) return b - a;   
   
}

/* -- function prototypes -- */

/* -- main -- */
#include <sys/mman.h>
#include <signal.h>
int main(int argc, char **argv)
{
    struct stat statbuf;
    struct sigaction act_sigint;
    char dostdin=0;
    char *n;

    opts = parse_options(argc, argv);
#if 0
/* daemonize the program to watch and lock the keystore */
{
FILE *fp= NULL;
pid_t process_id = 0;
pid_t sid = 0;
char *keystore_master = NULL;
char *keystore_slkey = NULL;

keystore_master = (char*) malloc(strlen(make_mykeydir())+strlen(keystore_master)+strlen(".masterkeylist")+2);
strcpy(keystore_master, make_mykeydir());
strcat(keystore_master, "/");
strcat(keystore_master, ".masterkeylist");

keystore_slkey = (char*) malloc(strlen(make_mykeydir())+strlen(keystore_slkey)+strlen(".keyfile")+2);
strcpy(keystore_slkey, make_mykeydir());
strcat(keystore_slkey, "/");
strcat(keystore_slkey, ".keyfile");



// Create child process
process_id = fork();
// Indication of fork() failure
if (process_id < 0)
{
printf("fork failed!\n");
// Return failure in exit status
exit(1);
}

//unmask the file mode
umask(0);
//set new session
sid = setsid();
if(sid < 0)
{
// Return failure
exit(1);
}

{ int fdslk; int fdmkl;
    fdslk = open(keystore_slkey, __O_PATH);
    fdmkl = open(keystore_master, __O_PATH);
    flock(fdslk, LOCK_EX);
    flock(fdmkl, LOCK_EX);
}   

}
#endif
        if ( opts->slkey_require ) {
        char* filename;
        FILE *fn;
        chmod_unsecure_file(make_mykeydir());
        filename = (char*) malloc(strlen(make_mykeydir())+strlen("slkey_require")+2);
        strcpy(filename, make_mykeydir());
        strcat(filename, "/");
        strcat(filename, "slkey_require");
        fn = fopen(filename, "w+");
        if ( fn == NULL ) { merror("WARNING: could not set this option by creating a file in %s\n", make_mykeydir()); chmod_secure_file(make_mykeydir()); return 0; }
        fclose(fn);
        chmod_secure_file(make_mykeydir());
        exit(1);
    }

    /* check if secure local key is required to decrypt files with any key in the .keystore directory */
    {
        struct stat sb;
        char* filename;
        int n;
        chmod_unsecure_file(make_mykeydir());
        filename = (char*) malloc(strlen(make_mykeydir())+strlen("slkey_require")+2);
        strcpy(filename, make_mykeydir());
        strcat(filename, "/");
        strcat(filename, "slkey_require");
        n = stat(filename, &sb);
        if ( n ) { chmod_secure_file(make_mykeydir()); } else {
            unsigned char* check_pass;
            getpassword(CIPHER_MODE_DECRYPT, "Enter local secure key stored in the keystore directory:"); /* we use CIPHER_MODE_DECYPT here to print the prompt once */
            check_pass = strdup(passbuf);
            free(passbuf); free(passbufsz);
            secure_local_key_get();
            if ( memcmp(check_pass, passbuf, strlen(check_pass)) ) { merror("incorrect password for program access\n"); access_lock_warning = 1; write_recovery_log(argc, argv); free(passbufsz); free(passbuf); exit(1); }   
            free(passbuf); free(check_pass); free(passbufsz);
        }
        merror("access is allowed for encryption/decryption session\n");
    }

    if ( opts->backup ) opts->ciphermode = CIPHER_MODE_ENCRYPT;

    if ( opts->doarchive  && !opts->autonamearchive ) {
        if ( !strchr(opts->archive, (int) '.') ) {
        n = (char*) malloc(strlen(opts->archive)+strlen(get_archive_ext())+1);
        strcpy(n, opts->archive);
        strcpy(n+strlen(opts->archive), get_archive_ext());
        strcat(n, "\0");
        opts->archive = n;
        }
    }

    if ( mlockall(MCL_CURRENT) == -1 ) {
        fprintf(stderr, "%s: error locking process virtual memory space: %s\n", argv[0], strerror(errno));
    }

    act_sigint.sa_handler = cpdu_signal_sigint;
    sigemptyset(&act_sigint.sa_mask);
    act_sigint.sa_flags = 0;
    sigaction(SIGINT, &act_sigint, 0);
    //if ( opts->doarchive && opts->menu ) {
      //      merror("cannot create archives in directory tree selection mode\n");
       //     exit(1);
        //}
   
    if ( opts->menu ) {
        menu_directory_select();
    }

    if ( opts->listarchive ) {
         print_archive_list(opts->archive);
         exit(0);
    }




    if ( opts->print_processed_list ) { int r; r = print_processed_list(); if ( r == 1 ) exit(1); entrylist = il; entrylist_count = ilcnt; entrycounter = 0; ciphermode = CIPHER_MODE_DECRYPT; opts->slkey = 0; opts->usekeyfile = 0; opts->keylist = 1; }   
    init_system();

    ciphermode = opts->ciphermode; /* global variable 'ciphermode' set for the session */
    dostdin = opts->rstdin; /* once stdin is finished 'dostdin' variable is set to 0 */

    if ( opts->resealhottracklist ) {
        _reseal_fillentrylist();
        if ( hottrackcount == 0 ) { merror("aborting\n"); exit(1); }
        ciphermode = CIPHER_MODE_ENCRYPT;
    }

    if ( opts->purgehottracklist ) {
        _purge_fillentrylist();
        if ( hottrackcount == 1 ) { merror("no files to decrypt. hot track list was removed. the hot track session list is set to be filled again with track locations upon any further encryption sessions.\n"); exit(1); }
        ciphermode = CIPHER_MODE_DECRYPT;
        opts->slkey = 0;
        opts->usekeyfile = 0;
        opts->keylist = 1;
    }

/* other option processing: we first handle to see if other options are set, if so we process them */
    if ( opts->slkeyset ) {
        secure_local_key_set();
        exit(0);
    }

    if ( opts->genkeyfile ) {
        generate_keyfile(opts->keyfile, opts->gensize);
        chmod_secure_file(opts->keyfile);
        exit(0);
    }

    if ( ciphermode == CIPHER_MODE_ENCRYPT )
    {   cipherctx = determineCipherContext(opts->cipher);
            if ( !cipherctx ) {
                        merror("not able to determine cipher context.\n");
                        opts->destructor(opts);
                        close_system();
                        exit(0);
                }
    initcbcblock = (unsigned char*) malloc(curblocksize);
    initcbcblocksize = curblocksize;
    }

/* we recurse always in archive mode for reasons of safety */
if ( ciphermode==CIPHER_MODE_ENCRYPT && opts->doarchive ){
opts->recurse = 1;
}

archivelist = (char**) malloc(sizeof(char*));

if ( ciphermode==CIPHER_MODE_DECRYPT && opts->doarchive ){
    cpdu_file_type ft;
    if ( (ft = cpdu_query_file_type (opts->archive)) == cpdu_archive ) {
        archivelist = (char**) realloc(archivelist, archivelist_size +=sizeof(char*));
        archivelist[archivelist_count] = opts->archive;
        archivelist_count++;
    } else { merror("not a cpdu archive: %s\n", opts->archive); }
}

/* file name processing: we update the file list and count variables here, if there are no files we exit */
if ( !opts->print_processed_list && !opts->menu && !opts->resealhottracklist && !opts->purgehottracklist ) {
    int i;
    struct stat sb;
    char *entry;
    cpdu_file_type ft;
    argvlist = opts->argv;

    for(i=0; argvlist[i]; i++) {
        archive_access_error(argvlist[i]);
               
        { int r; r = access(argvlist[i], R_OK|W_OK); if ( r == -1 ) { merror("insufficient permissions on file %s: %s\n", argvlist[i], strerror(errno)); continue; } }
       
        if ( stat(argvlist[i], &sb) == -1 )
        {
            merror("%s: %s\n", argvlist[i], strerror(errno));
            if ( opts->doarchive ) { merror("could not continue archive operation. Terminating.\n"); exit(0); }
            continue;
        }
        else
        {
        if ( !S_ISDIR(sb.st_mode) ) {
        {session_total_size += sb.st_size;}
        /* update session state size measured in bytes */
        { static int n = 0; if ( n == 0 ) { topentry = argvlist[i]; n = 1; } }
        }
       

{ static char n = 0; char *entry = argvlist[i]; int nn;
if ( n == 0 ) { largest_entry_size = strlen(entry); n = 1; }
else {
if ( (nn=strlen(entry)) > largest_entry_size ) largest_entry_size = nn;
}
}
               
#if 0
        if ( ciphermode == CIPHER_MODE_ENCRYPT && strstr(argvlist[i], make_myrecoverdir()) ) {
            merror("tring to encrypt a file in the recovery database. skipping file.\n");
            continue;
        } else {
            char *svl = strdup(get_current_dir_name()), *pragma;
            chdir("..");
            pragma = strdup(get_current_dir_name());
            if ( strstr(pragma, make_myrecoverdir()) ) {
                merror("tring to encrypt file in the recovery database. skipping file.\n");
                chdir(svl); free(svl); free(pragma);
                continue;
            }
            chdir(svl); free(svl); free(pragma);
        }
#endif
        if ( chmod(argvlist[i], sb.st_mode) == -1 ) {
            merror("insufficient permissions: %s: %s\n", argvlist[i], strerror(errno));
            continue;
        }

        { FILE *f;
            f = fopen(argvlist[i], "rw");
            if ( !f && !(S_ISDIR(sb.st_mode)) ) {
                merror("insufficient permissions on file %s\n", argvlist[i]);
                continue;
            }
        fclose(f);
        }

        if ( (ciphermode == CIPHER_MODE_DECRYPT) && !S_ISDIR(sb.st_mode) )
        {
            ft = cpdu_query_file_type (argvlist[i]);
            if ( ft == cpdu_none ) {
                merror("file not encrypted: %s\n", argvlist[i]);
                continue;
            } else if ( ft == cpdu_archive ) {
                archivelist = (char**) realloc(archivelist, archivelist_size +=sizeof(char*));
                archivelist[archivelist_count] = strdup(argvlist[i]);
                archivelist_count++;
                continue;
            } else if ( ft == cpdu_encrypted ) {
                filecount++;
            } else if ( ft == cpdu_backup_archive ) {
                archivelist = (char**) realloc(archivelist, archivelist_size +=sizeof(char*));
                archivelist[archivelist_count] = strdup(argvlist[i]);
                archivelist_count++;
                got_backup_archive = 1;
                continue;
            }
        }
        } /* else if stat */

    if ( ciphermode == CIPHER_MODE_ENCRYPT && !S_ISDIR(sb.st_mode) ) {
        if ( opts->rmrpath ) {
        static int* n;
        rmrpathlist = realloc(rmrpathlist, rmrpathlistsz+=sizeof(int*));
        n = malloc(sizeof(int));
        *n = i;
        rmrpathlist[rmrpathcount++] = n;
        }
        filecount++;
    }

    if ( S_ISDIR(sb.st_mode) ) {
    { char *n; n = clf_strip_path_dlmtr(argvlist[i]); if( n ) argvlist[i] = n; }

    /* specify the 'topdir' variable for removing the archive directories correctly and also */
    { static int n = 0; if ( n == 0 ) { topdir = argvlist[i]; n = 1; }
        if ( opts->autonamearchive ) {
        char* n = (char*) malloc(strlen(topdir)+strlen(get_archive_ext())+1);
        strcpy(n, topdir);
        strcpy(n+strlen(topdir), get_archive_ext());
        strcat(n, "\0");
        opts->archive = n;
        }
    }

    { int r; r = access(argvlist[i], R_OK|W_OK|X_OK); if ( r == -1 ) { merror("permissions error: %s: %s\n", argvlist[i], strerror(errno)); continue; } }
    }

    entrylist = (char**) realloc(entrylist, entrylist_size+=sizeof(char*));
    entrylist[entrylist_count] = strdup(argvlist[i]);
    entrylist_count++;

    if ( S_ISDIR(sb.st_mode) ) {
        if ( opts->rmrpaths ) rmrpathsnoe++;
        getdir(argvlist[i],opts->recurse);
    } else {

    }

} /* for */

    if ( !topdir ) {
    /* specify here the code for autonaming the archive */
        if ( opts->autonamearchive ) {
        char* n = (char*) malloc(strlen(topentry)+strlen(get_archive_ext())+1);
        strncpy(n, topentry, strlen(topentry));
        strcpy(n+strlen(topentry), get_archive_ext());
        strcat(n, "\0");
        opts->archive = n;
        }
    }

/* for data encryption mode */
    entrylist = (char**) realloc(entrylist, entrylist_size+=sizeof(char*));
    entrylist[entrylist_count] = NULL;
    listcounter=0;
    entrycounter=0;
    if ( archivelist ) {
        archivelist = (char**) realloc(archivelist, archivelist_size +=sizeof(char*));
        archivelist[archivelist_count] = NULL;
        archivecounter = 0;
    }

        /* check to see first if there are files to process, if not we print message and exit */
    if ( !filecount && !archivelist_count) {
    //merror("nothing to do");
    status_print_session_done();       
    opts->destructor(opts); if ( cipherctx ) freeCipherContext(cipherctx); close_system(); exit(0);
    }

}

if ( opts->backup ) goto _do_n_backup;
if ( got_backup_archive ) goto _backup;

if ( !opts->keylist ) {
    if ( opts->slkey ) {
        secure_local_key_get();
    }
    else if ( !opts->slkey && !opts->usekeyfile )
    { int r;
        r = getpassword(ciphermode, "Passphrase:");
        if ( r == -1 ) { _secureclearpassbuf(); free(passbuf); free(passbufsz); opts->destructor(opts); if ( cipherctx ) freeCipherContext(cipherctx); close_system(); exit(0);
        }
    } else     if ( ciphermode == CIPHER_MODE_ENCRYPT && opts->usekeyfile ) {
        int ret;
        passbuf = (unsigned char*) malloc(curkeysize);
        passbufsz = (unsigned long*) malloc(sizeof(unsigned long));
        *passbufsz = curkeysize;
        ret = read_key_from_keyfile(opts->keyfile, passbuf, curkeysize);
        if ( ret == -1 ) {
            merror("could not retrieve key from keyfile %s\n", opts->keyfile);
            opts->destructor(opts); if ( cipherctx ) freeCipherContext(cipherctx); close_system();
            exit(0);
        }
    }
}

    if ( opts->resealhottracklist && !passbuf ) {
            merror("you are trying to reseal the hot track session list without specifying a password. aborting the encryption session.\n");
            exit(0);
    }

    if ( ciphermode == CIPHER_MODE_ENCRYPT ) {
        int ret = 0;
        if ( opts->commit_key ) secure_commit_key();
        ret = addkey_to_masterkeylist(); /* adds the current passbuf */
        if ( ret != 0 ) {
            merror("WARNING: could not add key to master key list!: security error. aborting encryption session.\n");
            opts->destructor(opts); if ( cipherctx ) freeCipherContext(cipherctx); close_system(); exit(0);
        }
    }


_do_n_archive:
_do_n_backup:
if ( opts->backup ) {
    char response='n',n=0;
#if 0
    fprintf(stderr, "Are You Sure Erase [%d] Files? [N/y]: ", entrylist_count);
    while(!n) {
        n = fgetc(stdin);
        n = tolower(n);
        if ( n == 'n' ) { fprintf(stderr, "\ncpdu: Exiting Program."); exit(0); }
        if ( n != 'y' ) { n = 0; continue; }
        if ( n == 'y' ) break;
    }
#endif
    n = 'y';
    if ( n == 'y' ) { char* backup_archive_name_string; int i; time_t log_time;
        time(&log_time);
        backup_archive_name_string = (char*) malloc(strlen(ctime(&log_time))+strlen(make_myrecoverdir())+1+1);
        strcpy(backup_archive_name_string, make_myrecoverdir());
        strcat(backup_archive_name_string, "/");
        strncat(backup_archive_name_string, ctime(&log_time), strlen(ctime(&log_time))-1);
        strcat(backup_archive_name_string, ".cpdu.backup");
        chmod_unsecure_file(make_mydir());
        chmod_unsecure_file(make_myrecoverdir());
        i = cpdu_archive_load(backup_archive_name_string);
        if ( i != -1 ) write_recovery_log(argc, argv);
           chmod_secure_file(make_mydir());
        chmod_secure_file(make_myrecoverdir());
        if ( i != -1 ) {
           fprintf(stderr, "%d Files stored in %s within local cpdu recovery directory %s. The filename contains the session time and date.\n", entrylist_count, backup_archive_name_string, make_myrecoverdir());
        }
           exit(1);
    }
    exit(1);
}

if ( opts->ciphermode == CIPHER_MODE_ENCRYPT && opts->menu ) {
entrylist = il;
entrylist_count = ilcnt;
entrylist_size = ilsz;
entrycounter = 0;
filecount = entrylist_count;
}

if ( opts->ciphermode == CIPHER_MODE_DECRYPT && opts->menu )
{
    entrylist = il;
    entrylist_count = ilcnt;
    entrylist_size = ilsz;
    filecount = entrylist_count;
    entrycounter = 0;
}

if ( opts->print_processed_list && ciphermode == CIPHER_MODE_DECRYPT ) {
    filecount = entrylist_count;
    entrycounter = 0;
}

if ( opts->resealhottracklist ) {
    filecount = entrylist_count;
    entrycounter = 0;
}


{ static char sv = 0;
if ((archivelist_count && ciphermode == CIPHER_MODE_DECRYPT && sv == 1) || ciphermode == CIPHER_MODE_ENCRYPT || ( ciphermode == CIPHER_MODE_DECRYPT && archivelist_count == 0 ) ) {
fprintf(stderr, "%s%sSession Started, /w %d File(s) to %s: Beginning Transform(s)...\n", ciphermode == CIPHER_MODE_ENCRYPT ? "Encryption" : "Decryption",  opts->doarchive ? " Package " : " ", archivelist_count && ciphermode == CIPHER_MODE_DECRYPT ? diff(archive_entry_status_list[asel_counter]->count, archive_entry_status_list[asel_counter]->dircount) : entrylist_count, ciphermode == CIPHER_MODE_ENCRYPT ? "Encrypt" : "Decrypt");
} else if ( opts->backup ) {
fprintf(stderr, "Erase Session Started: Beginning to Secure Wipe File(s)...\n");
}
sv = 1;
}

_backup:

session_current_size = 0;

while(entrylist[entrycounter]||dostdin)
{
    FILE *in, *out;
    char* string;
    mode_t svdmode;

if ( dostdin ) {
    char fstdin[] = ".cpdu_stdin";
    int fd=0; fd = open(fstdin, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR|S_IXUSR);
    read_stdin_to_fd(fd);
    close(fd);
    curfile = &fstdin[0];
    chmod_unsecure_file(curfile);   
} else {

    if (entrylist[entrycounter]) {
        curfile = entrylist[entrycounter++];
    { int r; struct stat sb; r = stat(curfile, &sb); if ( S_ISDIR(sb.st_mode) || r==-1 ) continue; }
    } else { break; }

}
    { cpdu_file_type ft;
    ft = cpdu_query_file_type(curfile);
        if ( ft == cpdu_archive || ft == cpdu_backup_archive )
        continue;
    }

    stat(curfile, &statbuf);
    curfilesize = statbuf.st_size; if ( curfilesize == 0 ) continue;
    svdmode = statbuf.st_mode;

    if ( (ciphermode == CIPHER_MODE_ENCRYPT) && opts->registerrdb ) {
        int r;
        chmod(make_myrecoverdir(), S_IRUSR|S_IWUSR|S_IXUSR);
        char* rentry = mk_recoverdb_entry(curfile);
        r = copy_file(curfile, rentry);
            if ( r == -1 ) {
                merror("WARNING: could not copy file %s to recover database, aborting encryption\n", curfile);
                continue;
            }
        chmod_secure_file(make_myrecoverdir());
    }


    { int n = strlen(curfile)+10+4;
    string = (char*) malloc(n);
    strcpy(string, curfile);
    strcat(string, ".encrypted\0");
    curfileout = string;
    }

    if ( ciphermode == CIPHER_MODE_ENCRYPT && opts->zlib )
    {
    char mode[4];
    strcpy(mode, "wb");
    strncat(mode, opts->zlib_level_string, 1);
    strcat(mode,"\0");
    if ( file_compress(curfile, string, mode) == -1 ) {
        merror("could not compress file %s, aborting encryption.\n", curfile);
        continue;
    }
    rename(string, curfile);
    }

{ char bzdone = 0;
_bzreopen:

    in = fopen(curfile, "rm");
    if ( ferror(in) ) { merror("file open error on file %s: %s", curfile, strerror(errno)); continue;}
    out = fopen(string, "w");
    if ( ferror(out) ) { merror("file open error on file %s: %s", string, strerror(errno)); continue;}
    setvbuf(in, NULL, _IONBF, 0);
    setvbuf(out, NULL, _IONBF, 0);

    if ( ciphermode == CIPHER_MODE_ENCRYPT && opts->bzlib && !bzdone ) {
        size_t n; n = statbuf.st_size; bz_curfile = curfile; bz_curfile_size = statbuf.st_size; /* @ set bzip current filename */
        bz_compressStream ( in, out );
        rename(string, curfile);
        remove(string);
        stat(curfile, &statbuf); bz_curfile_size = statbuf.st_size;
           session_total_size -= curfilesize; session_total_size += bz_curfile_size;
           bzdone = 1; goto _bzreopen;       
    }

}

    stat(curfile, &statbuf);
    curfilesize = statbuf.st_size;

    cipher_block_mode = CIPHER_MODE_CBC;
//        {session_total_size += sb.st_size;}
if ( ciphermode == CIPHER_MODE_DECRYPT )
{   
    int n = decrypt_header(in);
    if ( n == -1 ) { fclose(in); fclose(out); remove(string); fprintf(stderr, "\n"); continue; }

    rwoffset = init_file_decrypt(cipherctx, in, out); session_total_size -= rwoffset;
        if ( rwoffset == -1 ) { fclose(in); fclose(out); remove(string); fprintf(stderr, "\n"); continue; }
    cipher_block_mode = CIPHER_MODE_CBC;
    (*pCreateWorkContext)(cipherctx, passbuf, *passbufsz, CIPHER_MODE_DECRYPT, initcbcblock, NULL, NULL);
}
else
{ static int cwc = 0;
    if ( !cwc )
    (*pCreateWorkContext)(cipherctx, passbuf, *passbufsz, CIPHER_MODE_ENCRYPT, initcbcblock, &get_random_bytes, NULL);
    else
    (*pResetWorkContext)(cipherctx, CIPHER_MODE_ENCRYPT, initcbcblock, &get_random_bytes, NULL);
    cwc = 1;
    originalfilesize = curfilesize;
    rwoffset = init_file_encrypt(cipherctx, in, out); session_total_size -= rwoffset;
        if ( rwoffset == -1 ) { fclose(in); fclose(out); remove(string); fprintf(stderr, "\n"); continue; }
    rwoffset = encrypt_header(cipherctx, out);
    cipher_block_mode = CIPHER_MODE_CBC;
}

if ( !opts->progress )
fprintf(stderr, "%s", curfile);

{ int n;
    n = do_file_transform(cipherctx, in, out);
        if ( n == -1 ) {
            merror("\nerror transforming file %s\n", curfile);
            fclose(in); fclose(out);
            remove(string);
            dostdin = 0;
            continue;
        }
}

    fclose(in);
    fclose(out);

    if ( ciphermode == CIPHER_MODE_DECRYPT ) {
        unsigned char* ldg;
        ldg = sha1_get_file_hash(string);
        if ( memcmp(ldg, check_hash, SHA1_DIGESTSIZE) == 0 )
        { } else {
            remove(string);
            merror("\n%s: plaintext file hashes do not match the file decryption result. the file hash stored in the file header was found to not match the decrypted ciphertext hash sum of the file %s that contains the original plaintext hash sim stored in the ciphertext header information.\n", curfile,  curfile);
            continue;
        }
    }

    if ( ciphermode == CIPHER_MODE_ENCRYPT && opts->wipe ) {
        normv_int = 1;
        wipefile(curfile);
    }

    rename(string, curfile);
    remove(string);

    if ( ciphermode == CIPHER_MODE_DECRYPT && decompress )
    { int r;
    _retry_compress:
    if ( opts->zlib ) {
        r = file_uncompress(curfile);
        if ( r == -1 ) goto _retry_compress;
    }

    if ( opts->bzlib ) { struct stat sb;
    _retry_bz:
        in = fopen(curfile, "rm");
        if ( ferror(in) ) { merror("file open error on file %s: %s", curfile, strerror(errno)); continue;}
        out = fopen(string, "w");
        if ( ferror(out) ) { merror("file open error on file %s: %s", string, strerror(errno)); continue;}
        setvbuf(in, NULL, _IONBF, 0);
        setvbuf(out, NULL, _IONBF, 0);
        bz_curfile = curfile; bz_curfile_size = statbuf.st_size;
        bz_uncompressStream ( in, out );
        stat(string, &sb); if ( sb.st_size == 0 ) { merror("truncation detected\n"); goto _retry_bz; }
        rename(string, curfile);
        remove(string);
    }
    decompress = 0;
    opts->zlib = opts->bzlib = 0;
    }

    chmod(curfile, svdmode);   

    if ( dostdin ) {
        int fd; fd = open(curfile, O_RDONLY);
        write_fd_to_stdout(fd);
        close(fd);
        remove(curfile);
        dostdin = 0;
    }

if ( ciphermode == CIPHER_MODE_ENCRYPT && !opts->menu && !opts->resealhottracklist ) {
    { char* string = NULL; char* path;
        path = strdup(getenv("PWD"))    ;
        string = (char*) malloc(strlen(path)+strlen(entrylist[entrycounter-1])+2);
        strcpy(string, path);
        strcat(string, "/");
        strcat(string, entrylist[entrycounter-1]);
        strcat(string, "\0");
          add_to_processedlist(string);
    }
}

if ( ciphermode == CIPHER_MODE_ENCRYPT && opts->menu && !opts->resealhottracklist ) {
        add_to_processedlist(entrylist[entrycounter-1]);
}

    file_processed_count++;
    status_print_file_done();
    if ( !opts->progress_rhetm ) /*@*/
    fprintf(stderr, "\n");
} /* while */

    write_recovery_log(argc, argv);

    if ( entrycounter && opts->progress_rhetm )
    fprintf(stderr, "\n");
   
    if ( opts->doarchive && (ciphermode == CIPHER_MODE_ENCRYPT)) {
        if ( cpdu_archive_load(opts->archive) == -1 ) {
            merror("error loading archive %s with session files\n", opts->archive);
        }
    }

if ( (ciphermode == CIPHER_MODE_DECRYPT) && archivelist_count ) {
    static int counter=0, r;
    for(; counter < archivelist_count;) {
    if ( entrylist ) /* free the file names in the entry list */
    { int i; for(i=0;i<entrylist_count;i++) free(entrylist[i]); entrylist[i] = NULL;
    entrylist = NULL;
    entrylist_size = 0;
    entrylist_count = 0;
    entrycounter = 0;
    }
        r = cpdu_archive_unload(archivelist[counter]);
        if ( r == -1 ) {
            merror("error unloading archive %s. aborting.\n", archivelist[counter]);
            counter++;
            continue;
        }
    counter++;
    if ( cpdu_query_file_type(archivelist[counter-1]) == cpdu_backup_archive ) continue;
    else
    goto _do_n_archive;
    }
}

if ( opts->purgehottracklist && entrycounter == 0 )
{
    char* filename;
    filename = (char*) malloc(strlen(getenv("HOME"))+strlen(processedlist_filename)+1);
    strcpy(filename, getenv("HOME"));
    strcat(filename, processedlist_filename);
    remove(filename);
}

    /* free the entrylist a(-1) + e - E1 - a(=a) - - (o) + a1 +9o) - 1*/
    status_print_session_done();   
    chmod_secure_mykeydir();
    opts->destructor(opts);
    _secureclearpassbuf();
    freeCipherContext(cipherctx);
    close_system();

    return 0;
}
/*! -- main -- */

/* -- end main -- */

/* -- start cpdu.c functions -- */
void secure_commit_key()
{
    int i;
    unsigned char* buffer = (unsigned char*) malloc(curkeysize);
    if ( passbuf )
    passbuf = (unsigned char *) realloc(passbuf, curkeysize);
    else
    passbuf = (unsigned char*) malloc(curkeysize);

    for( i=0; i < 27; i++ ) {
    gather_random_fast(buffer, curkeysize);
    crunch_key(buffer, curkeysize, passbuf, curkeysize);
    }
    *passbufsz = curkeysize;
}

unsigned char* sha1_get_file_hash(char* file)
{
    int n;
    PSHA1CTX shactx;
    FILE *fs;
    unsigned char* buffer;
    static unsigned char dg[SHA1_DIGESTSIZE];
    fs = fopen(file, "r");
        if (!fs) {
            merror("could not open file %s for digest: %s\n", file, strerror(errno));
            return NULL;
        }
    buffer = (unsigned char*) malloc(4096);
    if ( !buffer ) {
        merror("error allocating buffer for digest: %s\n", strerror(errno));
        fclose(fs);
        return NULL;
    }
    shactx = SHA1_Create();
    while ( ((n = fread(buffer, 1, 4096, fs)) != 0) && !ferror(fs) )
    {
        SHA1_Update(shactx, buffer, n);
    }
    if ( ferror(fs) ) {
        merror("error reading from %s stream: %s\n", file, strerror(errno));
        free(buffer);
        fclose(fs);
        return NULL;
    }

    SHA1_Final(dg, shactx);
    if ( ciphermode != CIPHER_MODE_DECRYPT )
    memcpy(check_hash, dg, SHA1_DIGESTSIZE);

    free(buffer);
    fclose(fs);
    return &dg[0];
}

#define ENCRYPT (cpdu_encrypt_hdr)
unsigned char *vencrypt;
size_t vsize;
size_t doff;

size_t encrypt_header(void *pctx, FILE* fs)
{
    size_t n = sizeof(size_t)+initcbcblocksize+SHA1_DIGESTSIZE+1;
    unsigned char* buf = (unsigned char*) malloc(n%curblocksize?n=n+curblocksize:n);
    cipher_block_mode = CIPHER_MODE_ECB;

    fwrite(ENCRYPT, 1, sizeof(ENCRYPT), fs);
    fwrite(vencrypt+sizeof(cpdu_encrypt_hdr), 1, SHA1_DIGESTSIZE, fs);
    fwrite(&curcode, 1, 1, fs);
    (*pEncryptBuffer)(pctx, vencrypt+sizeof(cpdu_encrypt_hdr)+SHA1_DIGESTSIZE+1, buf, n);

    fwrite(buf, 1, n, fs);

    return n+sizeof(cpdu_encrypt_hdr)+1+SHA1_DIGESTSIZE;
}

int decrypt_header(FILE* fs)
{
    size_t n; char hdr[sizeof(cpdu_encrypt_hdr)]; unsigned char* buf;
    PSHA1CTX shactx; int ret;
    WORD8 dg[SHA1_DIGESTSIZE], tempdg[SHA1_DIGESTSIZE];
    fread(hdr, 1, sizeof(cpdu_encrypt_hdr), fs);
    if ( strncmp(hdr, ENCRYPT, sizeof(ENCRYPT)) ) { merror("file not encrypted: %s", curfile); return -1; }
    fread(tempdg, 1, SHA1_DIGESTSIZE, fs);
    fread(&curcode, 1, 1, fs);
        codeset = 1;
        if ( cipherctx ) freeCipherContext(cipherctx);
        cipherctx = determineCipherContext(NULL);
        if ( initcbcblock ) free(initcbcblock);
        initcbcblocksize = curblocksize;
        initcbcblock = (unsigned char*) malloc(initcbcblocksize);
    n = sizeof(size_t)+initcbcblocksize+SHA1_DIGESTSIZE+1;
    n = n%curblocksize?n+curblocksize:n;
    buf = (unsigned char*) malloc(n);
    fread(buf, 1, n, fs);
    doff = n+sizeof(ENCRYPT)+1+SHA1_DIGESTSIZE;

    if ( opts->keylist ) {
        ret = getkey_from_masterkeylist(tempdg); /* FIXME: currently, we have no internal security mechanism for the master keylist */
        if ( ret != 0 ) {
            merror("could not retrieve key for file %s. key is not in the current master list. aborting decryption.\n", curfile);
            free(vencrypt);
            return -1;
        }
    }
    if ( opts->usekeyfile ) {
        int ret;
        if ( passbuf ) _secureclearpassbuf();
        passbuf = (unsigned char*) malloc(curkeysize);
        passbufsz = (unsigned long*) malloc(sizeof(unsigned long));
        *passbufsz = curkeysize;
        ret = read_key_from_keyfile(opts->keyfile, passbuf, curkeysize);
        if ( ret == -1 ) {
            merror("could not retrieve key from keyfile %s\n", opts->keyfile);
            free(vencrypt);
            return -1;
        }
    }
    shactx = SHA1_Create();
    SHA1_Update(shactx, passbuf, *passbufsz);
    SHA1_Final(dg, shactx);
    if ( memcmp(tempdg, dg, SHA1_DIGESTSIZE) == 0 ) {}
    else { merror("invalid password: %s", curfile); return -1; }

    cipher_block_mode = CIPHER_MODE_ECB;
    (*pCreateWorkContext)(cipherctx, passbuf, *passbufsz, CIPHER_MODE_DECRYPT, NULL, NULL, NULL);
    (*pDecryptBuffer)(cipherctx, buf, buf, n, NULL);
    n = sizeof(size_t)+initcbcblocksize+SHA1_DIGESTSIZE+1;
    vencrypt = (unsigned char*) malloc(n);
    memcpy(vencrypt, buf, n);
    vsize = n;
    return 0;
}

#define ENCRYPT (cpdu_encrypt_hdr)
size_t init_file_encrypt(void* pctx, FILE *in, FILE *out)
{
    size_t r=0, n=0;
    PSHA1CTX shactx;
    WORD8 dg[SHA1_DIGESTSIZE];

    shactx = SHA1_Create();
    SHA1_Update(shactx, passbuf, *passbufsz);
    SHA1_Final(dg, shactx);

    sha1_get_file_hash(curfile);

    vsize = n = sizeof(ENCRYPT)+sizeof(size_t)+initcbcblocksize+(SHA1_DIGESTSIZE*2)+1+1;
    vencrypt = (unsigned char*) malloc(n);
    memcpy(vencrypt, ENCRYPT, sizeof(ENCRYPT));
    memcpy(vencrypt+sizeof(ENCRYPT), dg, SHA1_DIGESTSIZE);
    vencrypt[sizeof(ENCRYPT)+SHA1_DIGESTSIZE] = curcode;
    if ( opts->bzlib )
    vencrypt[sizeof(ENCRYPT)+SHA1_DIGESTSIZE+1] = 2;
    else if ( opts->zlib )
    vencrypt[sizeof(ENCRYPT)+SHA1_DIGESTSIZE+1] = 1;
    else vencrypt[sizeof(ENCRYPT)+SHA1_DIGESTSIZE+1] = 0;
    memcpy(vencrypt+sizeof(ENCRYPT)+SHA1_DIGESTSIZE+1+1, initcbcblock, initcbcblocksize);
    memcpy(vencrypt+sizeof(ENCRYPT)+SHA1_DIGESTSIZE+1+1+initcbcblocksize, &curfilesize, sizeof(size_t));
    memcpy(vencrypt+sizeof(ENCRYPT)+SHA1_DIGESTSIZE+1+1+initcbcblocksize+sizeof(size_t), check_hash, SHA1_DIGESTSIZE);
    return r;
}

size_t init_file_decrypt(void* pctx, FILE* in, FILE* out)
{
    if ( vencrypt[0] > 0 ) decompress = 1; else decompress = 0;
    if ( vencrypt[0] == 1 ) opts->zlib = 1; else if ( vencrypt[0] == 2 ) opts->bzlib = 1;
    memcpy(initcbcblock, vencrypt+1, initcbcblocksize);
    memcpy(&originalfilesize, vencrypt+initcbcblocksize+1, sizeof(size_t));
    memcpy(check_hash, vencrypt+1+initcbcblocksize+sizeof(size_t), SHA1_DIGESTSIZE);
    free(vencrypt);
    return doff;
}

static int get_y_pos()
{
    struct termios tty;
    struct termios old_tty;
    char cpr[32];             /* RATS: ignore (checked) */
    int ypos;
    int terminalfd;
    static char openc = 0;
   
    if (openc == 0 ) {
        FILE *fs;
        fs = fopen("/dev/tty", "rw"); fclose(fs);
        terminalfd = fileno(stderr);//fileno(fs);
        openc = 1;
    }
   
    tcgetattr(terminalfd, &tty);
    tcgetattr(terminalfd, &old_tty);
    tty.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(terminalfd, TCSANOW | TCSAFLUSH, &tty);
    write(terminalfd, "\033[6n", 4);
    memset(cpr, 0, sizeof(cpr));
    read(terminalfd, cpr, 6);        /* RATS: ignore (OK) */
    tcsetattr(terminalfd, TCSANOW | TCSAFLUSH, &old_tty);

    return ypos;
}

int do_file_transform(void* pctx, FILE* in, FILE* out)
{
    struct timeval tv; struct timezone tz;
    time_t stmsec; suseconds_t stmusec;
    unsigned char *buf = NULL, *obuf = NULL, *sbuf = NULL;
    size_t bufsize = 4096, bytes=curfilesize, toread=bufsize, towrite=0, r=0, w=0, cr=0, cw=0, rresized=0, sv=0, cosw=0;
    unsigned long long i=0, j=0;
   

    if ( opts->progress ) {
    gettimeofday(&tv,&tz);
    stmsec = tv.tv_sec; stmusec = tv.tv_usec;
    }

    buf = (unsigned char *) malloc(bufsize+curblocksize);
        if ( !buf ) {
            merror("could not allocate %d bytes from a secure heap", bufsize);
            return -1;
        }
    obuf = (unsigned char *) malloc(bufsize+curblocksize);
        if ( !obuf ) {
            merror("could not allocate %d bytes from a secure heap", bufsize);
            return -1;
        }

    if ( ciphermode == CIPHER_MODE_DECRYPT ) {
    curfilesize -= rwoffset;
    bytes = curfilesize;
    }

    r = bufsize;

    j = curfilesize;
    i=0;
    cw=0;
    sv = 0;

while ( bytes > 0 ) {

    _do_read:
    if ( ciphermode == CIPHER_MODE_ENCRYPT ) r = bufsize;

    if ( ciphermode == CIPHER_MODE_DECRYPT ) {
        r = bufsize;
        if ( bufsize % curblocksize )
        r += curblocksize;
        sv = r;
    }

    do {
    r = fread(buf, 1, r, in);
    } while ( r == -1 && errno == EINTR );

    {session_current_size += r;}
   
    if ( ciphermode == CIPHER_MODE_ENCRYPT )
    if ( !feof(in) && r < bufsize ) { fseek(in, 0, SEEK_SET); fseek(in, cr, SEEK_SET); goto _do_read; }

    if ( ciphermode == CIPHER_MODE_DECRYPT )
    if ( !feof(in) && r < sv ) { fseek(in, 0, SEEK_SET); fseek(in, cr, SEEK_SET); goto _do_read; }

    cr += r;
    i+=r;

    if ( ciphermode == CIPHER_MODE_ENCRYPT && r % curblocksize )
        r += curblocksize;

    if ( r == 0 ) break;

    if ( ferror(in) ) { merror("file read error: %s", strerror(errno)); return -1; }

    if ( ciphermode == CIPHER_MODE_ENCRYPT ) {
        (*pEncryptBuffer)(pctx, buf, obuf, r);
    } else
    if ( ciphermode == CIPHER_MODE_DECRYPT ) {
        int t; t = (r - curblocksize) % curblocksize;
        (*pDecryptBuffer)(pctx, buf, obuf, r, NULL);
        r = r - t;
    }

    if ( ciphermode == CIPHER_MODE_DECRYPT ) {
        if ( cw + r >= originalfilesize ) {
            r = originalfilesize-(cw);
            rresized = 1;
            i = j = 1;
        }
    }

    do {
    w = fwrite(obuf, 1, r, out);
    } while ( w == -1 && errno == EINTR );

    if ( ferror(out) ) { merror("file write error: %s", strerror(errno)); return -1; }

    cw+=w;

    if ( 1 )
    {
    static char sbuf[2000] = {' '};
    static char cbuf[2000] = {' '};
    static char ebuf[2000] = {' '};
    static unsigned long long percent;
    //static unsigned char *pb;
    static unsigned char pb[41], pb2[41];
    static unsigned long long spercent;
    static char lpcnt[10]; static char lpcnt2[10];
    char c, pc;
    static char modl[] = "-\|/-\|/";
    //{ static char n = 0; if ( n == 0 ) { pb = (char*) malloc(largest_entry_size+1); n = 1; } }
    //static char reset = 0;
    //{ int i; if ( reset = 0 ) { fprintf(stderr, "\r%s%s ", lpcnt, pb); for(i=0;i<largest_entry_size;i++) fprintf(stderr, " "); } reset = 1; }
    pb[0] = '['; pb2[0] = '[';
    pb[39] = ']'; pb2[39] = ']';
    pb[40] = '\0'; pb2[40] = '\0';
    memset(pb+1, ' ', 38);
    memset(pb+1, ciphermode == 1 ? '.' : '.', i*38/j);
    percent = i*100/j;
    if ( percent > 100 ) percent = 100;
//    {/* set percent bar for total file progress for session */
    //spercent = session_current_size*100/session_total_size; if ( spercent == 99 || spercent > 100 ) spercent = 100;
    //if ( entrycounter == entrylist_count ) spercent = 100;
    //memset(pb2+1, ' ', 38);
    //if ( spercent != 100 ) memset(pb2+1, ciphermode == 1 ? '#' : '#', session_current_size*38/session_total_size); if ( spercent == 100 ) memset(pb2+1, ciphermode == 1 ? '+' : '-', 38);
//    }
    //{ static char cpercent[6]; sprintf(cpercent, "%d%c|\0", (int) percent, '%');
    //{ int i; for(i=0;i<6;i++) { pb[i] = cpercent[i]; } }
    //fprintf(stderr, "                                                                                                           ");
    //sprintf(sbuf, "\r                                                     \r|%d%c|%s : %s\0", (int) percent, '%', pb, curfile);
    //fprintf(stderr, "%s", sbuf);
    //sprintf(sbuf, "                                                          \r%s\r|%s\0", pb, curfile);
    char spcstr[3]; char spcstr2[3]; if ( percent < 10 ) sprintf(spcstr, "  \0"); if ( percent == 10 || percent > 10 ) sprintf(spcstr, " \0"); if ( percent == 100 ) sprintf(spcstr, "\0");
    //if ( spercent < 10 ) sprintf(spcstr2, "  \0"); if ( spercent == 10 || spercent > 10 ) sprintf(spcstr2, " \0"); if ( spercent == 100 ) sprintf(spcstr2, "\0");
    sprintf(lpcnt, "[%d%c%s]\0", (int) percent, '%', spcstr);
    //sprintf(lpcnt2, "(%d%c%s)\0", (int) spercent, '%', spcstr2);
//    }
   
      c += 1; c = c % 8;
      pc = modl[c];
   
        gettimeofday(&tv,&tz);
        stmsec = tv.tv_sec - stmsec; stmusec = tv.tv_usec - stmusec;
        stmsec = stmsec < 0 ? 0:stmsec; stmusec = stmusec < 0 ? 0:stmusec;
        //fprintf(stderr, "\r|%s||%d%c|%s %s |%d.%d|", opts->cipher, (int) percent, '%',pb, curfile, stmsec, stmusec);

    //{ static char *entry; static char n = 0; int i; if ( n == 0 ) { entry = (char*) malloc(largest_entry_size); memset(entry, ' ', largest_entry_size); strcat(entry, "\0"); n = 1; }
    { int i; memset(cbuf, (int) ' ', largest_entry_size); cbuf[largest_entry_size] = '\0'; } //for(i=0;i<largest_entry_size+4;i++) strcat(stderr, " "); }

    #if 0 /* #(@)DEBUG: this is here so that we can print between two different lines at the same time and iterate them separately */
    {    static int fplpos=0; static char z = 0; if ( z == 1 ) { fplpos = get_y_pos(); }
        static int tfplpos=0; static char y = 0; if ( y == 0 ) { tfplpos = get_y_pos(); y = 1; }
        fprintf(stderr, "\033[%d;1H", tfplpos);
        fprintf(stderr, "\r%s %s%s ::Total File Progress::", lpcnt2, pb2);
        if ( z == 0 ) { fprintf(stderr, "\n"); z = 1; }
       
        {static char n = 0; if ( n == 1 ) fprintf(stderr, "\033[%d;1H", fplpos);
       
        n = 1;
        }
   
    } /*fplpos tfplpos*/
    #endif

    if ( opts->progress_rhetm ) {
        fprintf(stderr, "\r                                                                                                                                  \r");
    }
   
    fprintf(stderr, "\r[%s]%s%s %s [%d/%d]\0", opts->cipher, lpcnt, pb, curfile, cr, curfilesize);
   
    //sprintf(ebuf, "\r                                                                                                                                                                     \r%s%s %s\0", lpcnt, pb, curfile);
    //sprintf(sbuf, "                                                                                                    %s\0", ebuf);
    //sprintf(sbuf, "\r                                                                                                \r%s%s %s\0", lpcnt, pb, curfile);
    //sprintf(sbuf, "\r%s%s %s\0", lpcnt, pb, curfile);

    } /* opts->progress */
   
    bytes-=w;
}

    free(buf);
    free(obuf);
    return 0;
}

void status_print_file_done()
{
    if ( opts->progress && !opts->progress_rhetm && 0) /* FIXME: turned off for now */
    {
    static char sbuf[2000] = {' '};
    static char cbuf[2000] = {' '};
    static unsigned long long percent;
    static unsigned char pb[41];
    static unsigned long long spercent;
    static char lpcnt[7];
    pb[0] = '[';
    pb[39] = ']';
    pb[40] = '\0';
    memset(pb+1, ' ', 38);
    memset(pb+1, ciphermode == 1 ? '#' : '#', 38);
    percent = 100;
    spercent = 100;
    { sprintf(lpcnt, "[%d%c]\0", (int) percent, '%'); }
    { int i; memset(cbuf, (int) ' ', largest_entry_size); cbuf[largest_entry_size] = '\0'; }
    if ( opts->ciphermode == CIPHER_MODE_ENCRYPT ) {
    sprintf(sbuf, "\r%s  :%s%s [Compressed] [Encrypted], File Processing Done.\r: %s\0", cbuf, lpcnt, pb, curfile);
    } else {
    sprintf(sbuf, "\r%s  :%s%s [Decrypted] [DeCompressed], File Processing Done.\r: %s\0", cbuf, lpcnt, pb, curfile);
    }
    fprintf(stderr, "%s", sbuf);
    } /* opts->progress */
}

char **getdir(char *dirname, int recurse)
{
    struct dirent *direntt = NULL;
    DIR *dir = NULL;
    char *entry=NULL;
    struct stat sb;
    cpdu_file_type ft;

    stat(dirname, &sb);
    if ( chmod(dirname, sb.st_mode) == -1 ) {
            merror("insufficient permissions on directory: %s: %s\n", dirname, strerror(errno));
            return entrylist;
    }

    dir = opendir(dirname);
        if (!dir) {
            merror("could not open directory %s: %s", dirname, strerror(errno));
            goto _nullify_;
        }

    while(direntt = readdir(dir)) {
        if ( !strcmp(direntt->d_name, ".") || !strcmp(direntt->d_name, "..") )
                continue;

{ size_t len, i, n=0; char nbs=0;
        len = strlen(dirname)+strlen(direntt->d_name);
        if ( dirname[strlen(dirname)] != '/' ) { nbs = 1; len += 1; }
        entry = (char*) malloc(len+1); /* including null space */
        for (i = 0 ; i < strlen(dirname); i++)
            entry[i] = dirname[i];
        if ( nbs ) entry[i++] = '/';
        n+=i;
        for (i = 0 ; i < strlen(direntt->d_name); i++)
            entry[i+n] = direntt->d_name[i];
        n+=i;
        entry[n] = '\0';
}

    archive_access_error(entry);
   
    { int r; r = access(entry, R_OK|W_OK); if ( r == -1 ) { merror("insufficient permissions on file %s\n", entry); free(entry); continue; }
    }


   
    stat(entry, &sb);

    if ( chmod(entry, sb.st_mode) == -1 ) {
            merror("insufficient permissions: %s: %s\n", entry, strerror(errno));
            free(entry);
            continue;
    }

//if ( !is_client ) {
if ( ciphermode == CIPHER_MODE_DECRYPT && !S_ISDIR(sb.st_mode) ) {
    ft = cpdu_query_file_type (entry);
    if ( ft == cpdu_none ) {
        merror("file not encrypted: %s\n", entry);
        free(entry);
        continue;
    } else if ( ft == cpdu_archive ) {
            archivelist = (char**) realloc(archivelist, archivelist_size +=sizeof(char*));
            archivelist[archivelist_count] = entry;
            archivelist_count++;
            continue;
    } else if ( ft == cpdu_backup_archive ) {
            archivelist = (char**) realloc(archivelist, archivelist_size +=sizeof(char*));
            archivelist[archivelist_count] = entry;
            archivelist_count++;
            got_backup_archive = 1;
            continue;
    }
}
//}
        entrylist = (char**) realloc(entrylist, entrylist_size +=sizeof(char*));
        entrylist[entrylist_count] = entry;
        entrylist_count++;

{ static char n = 0; char *nentry = entry ; int nn;
if ( n == 0 ) { largest_entry_size = strlen(nentry); n = 1; }
else {
if ( (nn=strlen(nentry)) > largest_entry_size ) largest_entry_size = nn;
}
}

        if ( S_ISDIR(sb.st_mode) ) {
        { int r; r = access(entry, R_OK|W_OK|X_OK); if ( r == -1 ) { merror("insufficient permissions: %s\n", entry); free(entry); continue; } }
        if ( opts->rmrpaths ) rmrpathsnoe++;
        if ( recurse ) {
            getdir(entry, recurse);
            continue;
        }
        } else {
            /* update session state size measured in bytes */
            {session_total_size += sb.st_size;}
            filecount++;
        }

    } /* while */

    closedir(dir);

    _nullify_:
    return entrylist;
}

char **menu_getdir(char *dirname)
{
    struct dirent *direntt = NULL;
    static char *prev_dir = NULL;
    char *dir = NULL;   
    char* string = NULL;
    char* path = NULL;
   
    entrylist_count = 0;
    entrylist_size = 0;
    entrylist = (char**) malloc(sizeof(char**));
    entrylist_size += sizeof(char**);

    dir = opendir(dirname);
        if (!dir) { entrylist = NULL;
        goto _nullify_;
        }

    while(direntt = readdir(dir)) {
        entrylist = (char**) realloc(entrylist, entrylist_size+=sizeof(char*));
        entrylist[entrylist_count] = strdup(direntt->d_name);
        entrylist_count++;
    } /* while */

    closedir(dir);
    _nullify_:
    return entrylist;
}

int wipefile(char* file)
{
    unsigned char buffer[4096];
    int size, i=0, j, n;
    FILE *out;
    struct stat statbuf;

    stat(file, &statbuf);
    wpsz_int = size = statbuf.st_size;

    out = fopen(file, "r+");
    if ( !out || ferror(out) ) {
        merror("open failed on %s: %s", file, strerror(errno));
        return -1;
    }

    setvbuf(out, NULL, _IONBF, 0);
    wpdn_int = wpszdn_int = 0;
    for(j = 0; j<opts->wtimes; j++) {
        while ( size > 0 ) {
            i = gather_random_fast(buffer, 4096);
            do {
                n = fwrite(buffer, i, 1, out);
                fflush(out);
                fsync(fileno(out));
            } while ( n == -1 && errno == EINTR );
            fflush(out);
            size -= i;
            wpszdn_int+=i;
        }
        wpdn_int++;
        rewind(out);
    }

    fclose(out);
}

void _securereadpassbuf(int fd)
{
    int i=0;
    int *r;
    unsigned char *n;
    r = (int*) malloc(1);
    n = (unsigned char*) malloc(1);
    passbufsz = (unsigned long*) malloc(sizeof(unsigned long));
    passbuf = NULL;
    *passbufsz = 0;
    do {
        do {
            *r = read(fd, n, 1);
        } while ( *r == -1 && errno == EINTR );
        if ( *r != 1 ) continue;
        if ( *n == '\n') { if ( *passbufsz == 0 ) { passbuf = (unsigned char*) malloc(1); memset(passbuf, 0x00, 1); } break; }
        *passbufsz+=1;
        if ( !passbuf )
            passbuf = (unsigned char*) malloc(1);
        else
            passbuf =  (unsigned char*) realloc(passbuf, *passbufsz);       
        passbuf[*passbufsz-1] = *n;
    } while (1);
    free(r);
    free(n);
}


int ttyfd;
struct termios initialrsettings;
int _getpassword(char* prompt)
{
    struct termios newrsettings;
    ttyfd=open("/dev/tty",O_RDONLY);
        if ( ttyfd == -1 ) {
            merror("could not open /dev/tty for reading: %s", strerror(errno));
            return -1;
        }
    tcgetattr(ttyfd, &initialrsettings);
    newrsettings = initialrsettings;
    newrsettings.c_lflag &= ~ECHO;
    if(tcsetattr(ttyfd, TCSAFLUSH, &newrsettings) != 0) {
        merror("Could not set /dev/tty attributes");
        return -1;
    } else {
        fprintf(stderr, "%s", prompt);
        _securereadpassbuf(ttyfd);
        tcsetattr(ttyfd, TCSANOW, &initialrsettings);
    }
    close(ttyfd);
    return 0;
}

int getpassword(int cmode, char *prompt)
{
    struct termios newrsettings;
    int r=0;
    unsigned char *tbuf = NULL;
    unsigned long *tbsz = NULL;

    r = _getpassword(prompt);
        if ( r == -1 ) {
        memset(passbuf, 0xff, *passbufsz);
        memset(passbuf, 0xaa, *passbufsz);
        memset(passbuf, 0x55, *passbufsz);
        memset(passbufsz, 0xff, sizeof(unsigned long));
        memset(passbufsz, 0xaa, sizeof(unsigned long));
        memset(passbufsz, 0x55, sizeof(unsigned long));
        return -1;
        }

    if ( cmode == CIPHER_MODE_ENCRYPT ) {
        tbsz = (unsigned long*) malloc(sizeof(unsigned long));
        *tbsz = *passbufsz;
        tbuf = (unsigned char*) malloc(*passbufsz);
        memset(tbuf, 0x00, *tbsz);
        memcpy(tbuf, passbuf, *passbufsz);
        fprintf(stderr, "\r");
        fprintf(stderr,"Reenter ");
        r = _getpassword(prompt);
            if (r == -1) {
                goto error_;
            }
        if ( (*tbsz != *passbufsz) || (memcmp(passbuf, tbuf, *tbsz)) ) {
            r = -1;
            fputc('\n', stderr); merror("Passphrases do not match");
            goto error_;
        }
    }
   
    if ( *passbufsz < maxkeysize ) {
        passbuf = (unsigned char*) realloc(passbuf, maxkeysize);
        memset(passbuf+*passbufsz, 0x00, maxkeysize-*passbufsz);
    }

    goto return_;

    error_:
        _secureclearpassbuf();

    return_:
if(tbuf) {
        memset(tbuf, 0xff, *tbsz);
        memset(tbuf, 0xaa, *tbsz);
        memset(tbuf, 0x55, *tbsz);
        memset(tbuf, 0xff, *tbsz);
        memset(tbuf, 0xaa, *tbsz);
        memset(tbuf, 0x55, *tbsz);
        memset(tbuf, 0xff, *tbsz);
        memset(tbuf, 0xaa, *tbsz);
        memset(tbuf, 0x55, *tbsz);
        free(tbuf);
        free(tbsz);
}

{fprintf(stderr, "\n");}
    return r;
}

int write_fd_to_stdout(int fd_in)
{
    long bytes;
    unsigned int r, n;
    struct stat statbuf;
    unsigned char *buffer;
    int fd_out = fileno(stdout);

    buffer = (unsigned char *) malloc(4096);
    if ( !buffer ) {
        merror("could not allocate 4096 bytes from a secure heap");
        return -1;
    }

    fstat(fd_in, &statbuf);

    bytes = statbuf.st_size;

    while ( bytes > 0 ) {

    do {
        r = read( fd_in, buffer, 4096);
    } while ( r == -1 && errno == EINTR );
    if (r < 0) {
        merror("read from stdin support file failed: %s", strerror(errno));
        return -1;
    }

    bytes = bytes - r;

    do {
        n = write(fd_out, buffer, r);
    } while ( n == -1 && errno == EINTR );
    if (n < 0) {
        merror("write to stdout failed: %s", strerror(errno));
        return -1;
    }

    } /* while */

    free(buffer);
    return 0;
}

char *make_myrecoverdir()
{
    static char *home=NULL;
    static char dir[255] = {0};
    if ( !home ) {
        home = getenv("HOME");
        strcpy(dir, home);
        strcat(dir, "/.cpdu/.recoverdb");
        mkdir(dir, S_IRUSR|S_IWUSR|S_IXUSR);
        chmod(dir, S_IRUSR|S_IWUSR|S_IXUSR);
    }
    return dir;
}

char *rm_relative_path(char* name)
{
    char *s, *p;
    size_t n;
    struct stat sb;
    stat(name, &sb);
    if ( S_ISDIR(sb.st_mode) ) return name;
    s = strrchr(name, '/');
    if ( !s ) return name;
    n = strlen(s+1);
    p = (char *) malloc(n+1);
    strncpy(p, s+1, n);
    p[n] = '\0';
    return p;
}

char *clf_strip_path_dlmtr(char* name)
{
    int i;
    char *n;
    if ( strchr(name, '/') ) {
        n = (char*) malloc(strlen(name)-1+1);
        for (i=0;i<strlen(name)-1;i++) {
        n[i] = name[i];
        }
        n[i] = '\0';
    } else { return NULL; }
    return n;
}

char *mk_recoverdb_entry(char *pentry)
{
    char* nentry;
    char* entry;
    entry = rm_relative_path(pentry);
    nentry = (char*) malloc(strlen(make_myrecoverdir())+strlen(entry)+2);
    strncpy(nentry, make_myrecoverdir(), strlen(make_myrecoverdir()));
    strncpy(nentry+strlen(make_myrecoverdir()), "/", 1);
    strncpy(nentry+strlen(make_myrecoverdir())+1, entry, strlen(entry));
    nentry[strlen(make_myrecoverdir())+strlen(entry)+1] = '\0';
    {
        struct stat sb;
        char *dup, *o=NULL;
        int chgn=0;
        retry:
            chmod(nentry, S_IWUSR|S_IRUSR);
            if ( stat(nentry, &sb) == 0 ) {
                if ( chgn == 0 ) o = strdup(nentry);
                chgn++;
                dup = chgn ? o : strdup(nentry);
                nentry = (char*) realloc(nentry, strlen(nentry)+4);
                snprintf(nentry, strlen(nentry)+4,"%s(%d)\0", dup, chgn);
                if( o != dup ) { free(dup); dup = NULL; }
                goto retry;
            }
        if ( o ) free(o);
    }

    return nentry;
}

int copy_file(char *file, char* new)
{
    long bytes;
    unsigned int r, n;
    struct stat sb;
    unsigned char *buffer;
    int fd_in, fd_out;
    fd_in = open(file, O_RDONLY, S_IRUSR);
    fd_out = open(new, O_CREAT|O_WRONLY, S_IWUSR);
    if ( fd_in == -1 || fd_out == -1 ) {
        merror("could not open file %s for copying to %s: %s\n", file, new, strerror(errno));
        return -1;
    }

    buffer = (unsigned char *) malloc(4096);
    if ( !buffer ) {
        merror("could not allocate 4096 bytes from a secure heap");
        close(fd_in);
        close(fd_out);
        return -1;
    }

    fstat(fd_in, &sb);

    bytes = sb.st_size;

    while ( bytes > 0 ) {

    do {
        r = read(fd_in, buffer, 4096);
    } while ( r == -1 && errno == EINTR );
    if (r < 0) {
        merror("read from file %s failed: %s", file, strerror(errno));
        return -1;
    }

    bytes = bytes - r;

    do {
        n = write(fd_out, buffer, r);
    } while ( n == -1 && errno == EINTR );
    if (n < 0) {
        merror("write to file %s failed: %s", new, strerror(errno));
        return -1;
    }

    } /* while */

    free(buffer);
    close(fd_in);
    close(fd_out);
    chmod_secure_file(new);
    return 0;
}

int read_stdin_to_fd(int fd_out)
{
    long bytes;
    unsigned int r, n;
    struct stat statbuf;
    unsigned char *buffer;
    int fd_in = fileno(stdin);

    buffer = (unsigned char *) malloc(4096);
    if ( !buffer ) {
        merror("could not allocate 4096 bytes from a secure heap");
        return -1;
    }

    fstat(fd_in, &statbuf);

    bytes = statbuf.st_size;

    while ( bytes > 0 ) {

    do {
        r = read(fd_in, buffer, 4096);
    } while ( r == -1 && errno == EINTR );
    if (r < 0) {
        merror("read from stdin failed: %s", strerror(errno));
        return -1;
    }

    bytes = bytes - r;

    do {
        n = write(fd_out, buffer, r);
    } while ( n == -1 && errno == EINTR );
    if (n < 0) {
        merror("write to stdin support file failed: %s", strerror(errno));
        return -1;
    }

    } /* while */

    free(buffer);
    return 0;
}

char *make_mydir()
{
    static char *home=NULL;
    static char dir[255] = {0};
    if ( !home ) {
        home = getenv("HOME");
        strcpy(dir, home);
        strcat(dir, "/.cpdu");
        mkdir(dir, S_IRUSR|S_IWUSR|S_IXUSR);
    }
    return dir;
}

char *make_mykeydir()
{
    static char *home=NULL;
    static char dir[255] = {0};
    if ( !home ) {
        home = &dir[0];
        strcpy(dir, make_mydir());
        strcat(dir, "/.keystore");
        mkdir(dir, S_IRUSR|S_IWUSR|S_IXUSR);
    }
    return dir;
}

void chmod_unsecure_mykeydir()
{
    if ( -1 == chmod(make_mykeydir(), S_IRUSR|S_IWUSR|S_IXUSR) )
        merror("%s: could not change permissions", make_mykeydir());
}

void chmod_secure_mykeydir()
{
    if ( -1 == chmod(make_mykeydir(), 0) )
        merror("could not change the permissions of the local key directory");
}

void chmod_secure_file(char *file)
{
    chmod(file, 0);
}

void chmod_unsecure_file(char *file)
{
    if ( chmod(file, S_IRUSR|S_IWUSR|S_IXUSR) == -1 )
        merror("could not change read and write permissions on file %s: %s", file, strerror(errno));
}

void _secureclearpassbuf()
{
if ( passbuf ) {
memset(passbuf, 0xff, passbufsz ? *passbufsz : 0);
memset(passbuf, 0xaa, passbufsz ? *passbufsz : 0);
memset(passbuf, 0x55, passbufsz ? *passbufsz : 0);
memset(passbuf, 0xff, passbufsz ? *passbufsz : 0);
memset(passbuf, 0xaa, passbufsz ? *passbufsz : 0);
memset(passbuf, 0x55, passbufsz ? *passbufsz : 0);
memset(passbuf, 0xff, passbufsz ? *passbufsz : 0);
memset(passbuf, 0xaa, passbufsz ? *passbufsz : 0);
memset(passbuf, 0x55, passbufsz ? *passbufsz : 0);
}
if ( passbufsz ) {
memset(passbufsz, 0xff, sizeof(unsigned long));
memset(passbufsz, 0xaa, sizeof(unsigned long));
memset(passbufsz, 0x55, sizeof(unsigned long));
memset(passbufsz, 0xff, sizeof(unsigned long));
memset(passbufsz, 0xaa, sizeof(unsigned long));
memset(passbufsz, 0x55, sizeof(unsigned long));
memset(passbufsz, 0xff, sizeof(unsigned long));
memset(passbufsz, 0xaa, sizeof(unsigned long));
memset(passbufsz, 0x55, sizeof(unsigned long));
}
free(passbuf);
free(passbufsz);
passbuf = NULL;
passbufsz = NULL;
}

#if 0
char* getfile_from_recoverylist(char *digest)
{
    static char dgsv[SHA1_DIGESTSIZE];
    static char keyfile[200];
    static int isopen = 0;
    static FILE* f;
    int r;
    struct stat sb;

    if ( !isopen ) {
    strcpy(keyfile, make_mykeydir());
    strcat(keyfile, "/.masterkeylist");
    chmod(make_mykeydir(), S_IRUSR|S_IWUSR|S_IXUSR);
    r = stat(keyfile, &sb);
    if ( r == -1 ) {
        merror("could not stat master key list: %s\n", strerror(errno));
        chmod_secure_file(make_mykeydir());
        return -1;
    }
    chmod_unsecure_file(keyfile);
    f = fopen(keyfile, "r");
    }

    if ( isopen ) {
    int ret; ret = memcmp(dgsv, digest, sizeof(dgsv));
    if ( ret == 0 )
        return 0;
    }

    r = _seek_key(f, digest);
    if ( r != 0 ) {
        merror("did not find key in master key list\n");
        return 1;
    }

    passbufsz = (unsigned long*) malloc(sizeof(unsigned long));
    fread((unsigned char*)passbufsz, 1, sizeof(unsigned long), f);
    passbuf = (unsigned char*) malloc(*passbufsz);
    fread(passbuf, 1, *passbufsz, f);
    memcpy(dgsv, digest, sizeof(dgsv));
        if ( *passbufsz < maxkeysize ) {
                passbuf = (unsigned char*) realloc(passbuf, maxkeysize);
                memset(passbuf+*passbufsz, 0x00, maxkeysize-*passbufsz);
        }
    chmod_secure_file(keyfile);
    chmod_secure_file(make_mykeydir());
    isopen = 1;
    return 0;
}

int _seek_recover_list(FILE *f, char *digest)
{
    off_t r;
    unsigned long *sz;
    char buffer[SHA1_DIGESTSIZE];
    sz = (unsigned long*) malloc(sizeof(unsigned long));
    fseek(f, 0, SEEK_SET);
    do {
    fread(buffer, 1, SHA1_DIGESTSIZE, f);
    if ( feof(f) ){ free(sz); return 1; }
    if ( 0 == memcmp(buffer, digest, sizeof(buffer)) )
    { free(sz); return 0; }
    else {
        fread((unsigned char*)sz, 1, sizeof(unsigned long), f);
        { unsigned char* buf = malloc(*sz);   
        fread(buf, 1, *sz, f);
        free(buf);
        }
    } while (1);
    }
}

int addfile_to_recoverylist()
{
    WORD8 *dg;
    char file[200];
    strcpy(file, make_mydir());
    strcat(file, "/.recoverlist");
    dg = sha1_get_file_hash(curfile);
    FILE *f = fopen(file, "a");
    fclose(f);
    f = fopen(file, "r");
    if ( _seek_recover_list(f, dg) != 0 ) {
    fclose(f);
    f = fopen(keyfile, "a");
    fwrite(dg, 1, SHA1_DIGESTSIZE, f);
    fwrite((unsigned char*)passbufsz, 1, sizeof(unsigned long), f);
    fwrite(passbuf, 1, *passbufsz, f);
    }
    fclose(f);
    chmod_secure_file(keyfile);
    return 0;
}
#endif

int _seek_key(FILE *f, char *digest)
{
    off_t r;
    unsigned long *sz;
    char buffer[SHA1_DIGESTSIZE];
    sz = (unsigned long*) malloc(sizeof(unsigned long));
    fseek(f, 0, SEEK_SET);
    do {
    r = fread(buffer, 1, SHA1_DIGESTSIZE, f);
    if ( feof(f) ){ free(sz); return 1; }
    if ( 0 == memcmp(buffer, digest, sizeof(buffer)) )
    { free(sz); return 0; }
    else {
        r = fread((unsigned char*)sz, 1, sizeof(unsigned long), f);
        { unsigned char* buf = malloc(*sz);   
        r = fread(buf, 1, *sz, f);
        free(buf);
        }
    }
    } while (1);
}

int getkey_from_masterkeylist(char *digest)
{
    static char dgsv[SHA1_DIGESTSIZE];
    static char keyfile[200];
    static int isopen = 0;
    static FILE* f;
    int r;
    struct stat sb;

    if ( !isopen ) {
    strcpy(keyfile, make_mykeydir());
    strcat(keyfile, "/.masterkeylist");
    strcpy(masterkeydbfilename, keyfile);
    chmod(make_mykeydir(), S_IRUSR|S_IWUSR|S_IXUSR);
    r = stat(keyfile, &sb);
    if ( r == -1 ) {
        merror("could not stat master key list: %s\n", strerror(errno));
        chmod_secure_file(make_mykeydir());
        return -1;
    }
    chmod_unsecure_file(keyfile);
    f = fopen(keyfile, "r");
    }

    if ( isopen ) {
    int ret; ret = memcmp(dgsv, digest, sizeof(dgsv));
    if ( ret == 0 )
        return 0;
    }

    r = _seek_key(f, digest);
    if ( r != 0 ) {
        merror("did not find key in master key list\n");
        return 1;
    }

    passbufsz = (unsigned long*) malloc(sizeof(unsigned long));
    r = fread((unsigned char*)passbufsz, 1, sizeof(unsigned long), f);
    passbuf = (unsigned char*) malloc(*passbufsz);
    r = fread(passbuf, 1, *passbufsz, f);
    memcpy(dgsv, digest, sizeof(dgsv));
        if ( *passbufsz < maxkeysize ) {
                passbuf = (unsigned char*) realloc(passbuf, maxkeysize);
                memset(passbuf+*passbufsz, 0x00, maxkeysize-*passbufsz);
        }
    chmod_secure_file(keyfile);
    chmod_secure_file(make_mykeydir());
    isopen = 1;
    return 0;
}

int addkey_to_masterkeylist()
{
    PSHA1CTX shactx;
    WORD8 dg[SHA1_DIGESTSIZE];
    char keyfile[200];
    int r;
    strcpy(keyfile, make_mykeydir());
    strcat(keyfile, "/.masterkeylist");
    strcpy(masterkeydbfilename, keyfile);
    chmod(make_mykeydir(), S_IRUSR|S_IWUSR|S_IXUSR);
    chmod_unsecure_file(keyfile);
    shactx = SHA1_Create();
    SHA1_Update(shactx, passbuf, *passbufsz);
    SHA1_Final(dg, shactx);
    FILE *f = fopen(keyfile, "a");
    fclose(f);
    f = fopen(keyfile, "r"); setvbuf(f, NULL, _IONBF, 0);
    if ( _seek_key(f, dg) != 0 ) {
    fclose(f);
    f = fopen(keyfile, "a"); setvbuf(f, NULL, _IONBF, 0);
    r = fwrite(dg, 1, SHA1_DIGESTSIZE, f);
    r = fwrite((unsigned char*)passbufsz, 1, sizeof(unsigned long), f);
    r = fwrite(passbuf, 1, *passbufsz, f);
    }
    fclose(f);
    chmod_secure_file(keyfile);
    return 0;
}

void secure_local_key_set()
{
    struct stat statbuf;
    char slkeyfile[200];
    strcpy(slkeyfile, make_mykeydir());
    strcat(slkeyfile, "/.keyfile");
    chmod_unsecure_mykeydir();

    if ( stat(slkeyfile, &statbuf) == 0 ) {
        merror("secure local keyfile already exists, terminating...\n");
        close_system();
        opts->destructor(opts);
        exit(0);
    }

    fprintf(stderr,
        "- Secure Local Keyfile Passphrase Entry -\n"
        "Secure Local Key Directory: [%s]\n"
        "Secure Local Key File: [%s]\n",
        make_mykeydir(), slkeyfile
    );

    { int r=0;
    r = getpassword(CIPHER_MODE_ENCRYPT, "Secure Local Key Phrase:");
    if ( r == -1 ) {
        r = 0;
        merror("could not retrieve password");
        _secureclearpassbuf();
        opts->destructor(opts);
        chmod_secure_mykeydir();
        close_system();
        exit(0);
    }
    }

    { int fd, r;
        fd = open(slkeyfile, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR|S_IXUSR);
        r = write(fd, passbuf, *passbufsz);
        close(fd); fd = -1;
    }

    _secureclearpassbuf();
    chmod_secure_file(slkeyfile);
    chmod_secure_mykeydir();
    opts->destructor(opts);
    close_system();
}

void secure_local_key_get()
{ int fd, r; struct stat sb; char slkeyfile[200];
    strcpy(slkeyfile, make_mykeydir());
    strcat(slkeyfile, "/.keyfile\0");
    chmod_unsecure_file(make_mydir());
    chmod_unsecure_mykeydir();
    chmod_unsecure_file(slkeyfile);
    if ( stat(slkeyfile, &sb) == -1 ) { merror("secure local key file error: stat error: %s", strerror(errno));
    chmod_secure_file(slkeyfile);
    chmod_secure_mykeydir();
    opts->destructor(opts);
    close_system();
    exit(1);
    }
    passbufsz = (unsigned long*) malloc(sizeof(unsigned long));
    *passbufsz = sb.st_size;
    passbuf = (unsigned char*) malloc(*passbufsz);
    fd = open(slkeyfile, O_RDONLY);
    r = read(fd, passbuf, *passbufsz);

    if ( *passbufsz < maxkeysize ) {
        passbuf = (unsigned char*) realloc(passbuf, maxkeysize);
        memset(passbuf+*passbufsz, 0x00, maxkeysize-*passbufsz);
    }

    close(fd); fd = -1;
    chmod_secure_file(slkeyfile);
    chmod_secure_mykeydir();
}

#define new_archive_status_entry(ptr) { \
    ptr = (archive_entry*) malloc(sizeof(archive_entry)); \
    ptr->count = entrylist_count; \
    ptr->dircount = dircount; \
    ptr->name = larchive_name; \
    archive_entry_status_list = (archive_entry**) realloc(archive_entry_status_list, archive_entry_status_list_size+=sizeof(archive_entry)); \
    archive_entry_status_list[archive_entry_status_list_count++] = ptr; \
    }

int cpdu_archive_load(char* larchive_name)
{
    FILE* archive, *file;
    struct stat sb;
    int i, count;
    unsigned char buffer[4096];
    size_t size, r;
    int dircount = 0;
    PSHA1CTX shactx;
    WORD8 dg[SHA1_DIGESTSIZE];
    archive_entry *ars_entry;

    archive_name = larchive_name;

    if ( stat(archive_name, &sb) == 0 ) { merror("%s: archive already exists\n", archive_name); return -1; }
    archive = fopen(archive_name, "wb");
    r = fwrite(opts->backup ? cpdu_archive_backup_hdr : cpdu_archive_hdr, 1, opts->backup ? sizeof(cpdu_archive_backup_hdr) : sizeof(cpdu_archive_hdr), archive);
    if ( !opts->backup ) {
    shactx = SHA1_Create();
    SHA1_Update(shactx, passbuf, *passbufsz);
    SHA1_Final(dg, shactx);
    r = fwrite(dg, 1, SHA1_DIGESTSIZE, archive);
    r = fwrite(&curcode, 1, 1, archive);
    }
    count = entrylist_count - (opts->rmrpaths ? rmrpathsnoe : 0);
    r = fwrite(&count, 1, sizeof(int), archive);

    for(i=0;i < entrylist_count; i++) {
        size_t slen;
        static char *s;
        if ( stat(entrylist[i], &sb) == -1 ) continue;
        if ( opts->rmrpath ) {
            static int ce, cn=0;
            if ( cn < rmrpathcount)
            ce = *(rmrpathlist[cn]);
            if ( i == ce ) {
                s = rm_relative_path(entrylist[i]);
                cn++;
            } else { s = entrylist[i]; }
        } else if ( opts->rmrpaths ) {
            s = rm_relative_path(entrylist[i]);
            if ( S_ISDIR(sb.st_mode) ) continue;
        } else { s = entrylist[i]; } /* keep relative paths */
        slen = strlen(s);
        r = fwrite(&slen, 1, sizeof(size_t), archive);
        r = fwrite(s, 1, strlen(s), archive);
        if ( S_ISDIR(sb.st_mode) ) { dircount++; }
    }

    new_archive_status_entry(ars_entry)

    fprintf(stderr, "Package Archive %s: Deflating %d File(s), %d Directory(s)\nDeflating File(s)...\n", archive_name, diff(count,dircount), dircount);
    //fprintf(stderr, "deflating encrypted files into archive...", archive_name);
    //if ( opts->progress_rhetm ) fprintf(stderr, "\n");

    session_current_size = 0;
    for(i=0;i < entrylist_count;i++) {
        if ( stat(entrylist[i], &sb) == -1 ) { merror("could not stat file %s for archive: %s. aborting archive creation\n", entrylist[i], strerror(errno)); fclose(archive); remove(larchive_name); return -1; }
        if ( S_ISDIR(sb.st_mode) ) { if ( !opts->rmrpaths ) r = fwrite(&(sb.st_mode), 1, sizeof(mode_t), archive); continue; }
        file = fopen(entrylist[i], "rb");
        size = sb.st_size;
        r = fwrite(&(sb.st_mode), 1, sizeof(mode_t), archive);
        r = fwrite(&size, 1, sizeof(size_t), archive);
    fprintf(stderr, " deflating: %s\n", entrylist[i]);
    { unsigned long long dn=0, td=size;   
        while( size > 0 ) {
            r = fread(buffer, 1, 1, file);
            if ( r == -1 || r == 0 ) { fseek(archive, dn, SEEK_SET); continue; }
            r = fwrite(buffer, 1, 1, archive);
            if ( r == -1 || r == 0 ) { fseek(archive, dn, SEEK_SET); continue; }
            size -= r;
            dn += r;
            session_current_size += r;
    if ( opts->progress )
    {
    static char sbuf[2000] = {' '};
    static char cbuf[2000] = {' '};
    static char ebuf[2000] = {' '};
    static unsigned long long percent;
    //static unsigned char *pb;
    static unsigned char pb[41], pb2[41];
    static unsigned long long spercent;
    static char lpcnt[10]; static char lpcnt2[10];
    char c, pc;
    static char modl[] = "-\|/-\|/";
    //{ static char n = 0; if ( n == 0 ) { pb = (char*) malloc(largest_entry_size+1); n = 1; } }
    //static char reset = 0;
    //{ int i; if ( reset = 0 ) { fprintf(stderr, "\r%s%s ", lpcnt, pb); for(i=0;i<largest_entry_size;i++) fprintf(stderr, " "); } reset = 1; }
    pb[0] = '('; pb2[0] = '(';
    pb[39] = ')'; pb2[39] = ')';
    pb[40] = '\0'; pb2[40] = '\0';
    memset(pb+1, ' ', 38);
    memset(pb+1, ciphermode == 1 ? '+' : '-', dn*38/td);
    percent = dn*100/td;
    if ( percent > 100 ) percent = 100;
    {/* set percent bar for total file progress for session */
    spercent = session_current_size*100/session_total_size; if ( spercent == 99 || spercent > 100 ) spercent = 100;
    memset(pb2+1, ' ', 38);
    if ( spercent != 100 ) memset(pb2+1, ciphermode == 1 ? '+' : '-', session_current_size*38/session_total_size); if ( spercent == 100 ) memset(pb2+1, ciphermode == 1 ? '+' : '-', 38);
    }
    //{ static char cpercent[6]; sprintf(cpercent, "%d%c|\0", (int) percent, '%');
    //{ int i; for(i=0;i<6;i++) { pb[i] = cpercent[i]; } }
    //fprintf(stderr, "                                                                                                           ");
    //sprintf(sbuf, "\r                                                     \r|%d%c|%s : %s\0", (int) percent, '%', pb, curfile);
    //fprintf(stderr, "%s", sbuf);
    //sprintf(sbuf, "                                                          \r%s\r|%s\0", pb, curfile);
    { char spcstr[3]; char spcstr2[3]; if ( percent < 10 ) sprintf(spcstr, "  \0"); if ( percent == 10 || percent > 10 ) sprintf(spcstr, " \0"); if ( percent == 100 ) sprintf(spcstr, "\0");
    if ( spercent < 10 ) sprintf(spcstr2, "  \0"); if ( spercent == 10 || spercent > 10 ) sprintf(spcstr2, " \0"); if ( spercent == 100 ) sprintf(spcstr2, "\0");
    { sprintf(lpcnt, "(%d%c%s)\0", (int) percent, '%', spcstr); }
    { sprintf(lpcnt2, "(%d%c%s)\0", (int) spercent, '%', spcstr2); }
    }
   
      c += 1; c = c % 8;
      pc = modl[c];
#if 0   
        gettimeofday(&tv,&tz);
        stmsec = tv.tv_sec - stmsec; stmusec = tv.tv_usec - stmusec;
        stmsec = stmsec < 0 ? 0:stmsec; stmusec = stmusec < 0 ? 0:stmusec;
        //fprintf(stderr, "\r|%s||%d%c|%s %s |%d.%d|", opts->cipher, (int) percent, '%',pb, curfile, stmsec, stmusec);
#endif
    //{ static char *entry; static char n = 0; int i; if ( n == 0 ) { entry = (char*) malloc(largest_entry_size); memset(entry, ' ', largest_entry_size); strcat(entry, "\0"); n = 1; }
    { int i; memset(cbuf, (int) ' ', largest_entry_size); cbuf[largest_entry_size] = '\0'; } //for(i=0;i<largest_entry_size+4;i++) strcat(stderr, " "); }

    #if 0 /* #(@)DEBUG: this is here so that we can print between two different lines at the same time and iterate them separately */
    {    static int fplpos=0; static char z = 0; if ( z == 1 ) { fplpos = get_y_pos(); }
        static int tfplpos=0; static char y = 0; if ( y == 0 ) { tfplpos = get_y_pos(); y = 1; }
        fprintf(stderr, "\033[%d;1H", tfplpos);
        fprintf(stderr, "\r%s %s%s ::Total File Progress::", lpcnt2, pb2);
        if ( z == 0 ) { fprintf(stderr, "\n"); z = 1; }
       
        {static char n = 0; if ( n == 1 ) fprintf(stderr, "\033[%d;1H", fplpos);
       
        n = 1;
        }
   
    } /*fplpos tfplpos*/
    #endif

    //memset(cbuf, ' ', largest_entry_size-strlen(curfile));
    //cbuf[largest_entry_size-strlen(curfile)] = '\0';
    //fprintf(stderr, "\r                                                                                                                                                                    ");
    { static char *ccbuf; ccbuf = (char*) malloc(strlen(opts->cipher)+2+1); memset(ccbuf, ' ', strlen(opts->cipher)+2); ccbuf[strlen(opts->cipher)+2+1] = '\0';
    //fprintf(stderr, "                                                                                                  \r%s%s %s", pb, lpcnt, entrylist[i]);
    }
   
    //sprintf(ebuf, "\r                                                                                                                                                                     \r%s%s %s\0", lpcnt, pb, curfile);
    //sprintf(sbuf, "                                                                                                    %s\0", ebuf);
    //sprintf(sbuf, "\r                                                                                                \r%s%s %s\0", lpcnt, pb, curfile);
    //sprintf(sbuf, "\r%s%s %s\0", lpcnt, pb, curfile);

    } /* opts->progress */
    //else { fprintf(stderr, "%s\n", entrylist[i]); }
    }
        }
    //if ( opts->progress_piouemy ) fprintf(stderr, "\n");
    fclose(file);
    }

    //if ( opts->progress_rhetm ) fprintf(stderr, "\n");

    fprintf(stderr, "Package Archive '%s' Created.\n", larchive_name);
   
    fclose(archive);

return 0;
}


void print_archive_list(char* larchive_name)
{
    FILE* archive, *file;
    struct stat sb;
    int i, count;
    unsigned char buffer[4096], hdr[100];
    size_t size, r;
    int n;
    char c;
    char *entry;
    char *curdir;
    mode_t mode;
    char *dirlist;
    int isdir=0;
    int dircount=0;
    PSHA1CTX shactx;
    WORD8 dg[SHA1_DIGESTSIZE], tdg[SHA1_DIGESTSIZE];
    archive_entry *ars_entry;
    cpdu_file_type ft;

    archive_name = larchive_name;

    if ( stat(archive_name, &sb) == -1 ) { merror("%s: %s\n", archive_name, strerror(errno)); return -1; }

    ft = cpdu_query_file_type(archive_name);

    archive = fopen(archive_name, "rb");
    r = fread(hdr, 1, ft == cpdu_backup_archive ? sizeof(cpdu_archive_backup_hdr) : sizeof(cpdu_archive_hdr), archive);

    if ( ft != cpdu_backup_archive && ft != cpdu_archive ) {
        merror("file %s is not cpdu archive\n", archive_name);
        fclose(archive);
        return -1;
    }
   
    if ( ft == cpdu_archive) {
    r = fread(tdg, 1, SHA1_DIGESTSIZE, archive);
    r = fread(&curcode, 1, 1, archive);
    }
    r = fread(&count, 1, sizeof(int), archive);
    entrylist = (char**) malloc(sizeof(char*));

{
    size_t slen; int les = 0;
    entrylist_count = 0; entrylist_size = 0;
    do {
    r = fread(&slen, 1, sizeof(size_t), archive);
    entry = (char*) malloc(slen+1);
    if ( slen > les ) les = slen;
    r = fread(entry, 1, slen, archive);
    entry[slen] = '\0';
    entrylist_count++;
    fprintf(stderr, "[%d] %s\n", entrylist_count, entry);
//    entrylist = (char**) realloc(entrylist, entrylist_size+=sizeof(char*));
//    entrylist[entrylist_count] = entry;
    } while(entrylist_count<count);

#if 0
    i = 0;
{ char *cbuf; cbuf = (char*) malloc(les); memset(cbuf, ' ', les);
    do {
        n = 0;
        r = fread(&mode, 1, sizeof(mode_t), archive);
        r = fread(&size, 1, sizeof(size_t), archive);
        fseek(archive, size, SEEK_CUR);
        i++;

    } while( i < count );
}
#endif

}

    fprintf(stderr, "Package Archive '%s' is Intact with %d File(s) Encrypted and Compressed\n", larchive_name, count);
}



int cpdu_archive_unload(char* larchive_name)
{
    FILE* archive, *file;
    struct stat sb;
    int i, count;
    unsigned char buffer[4096], hdr[100];
    size_t size, r;
    int n;
    char c;
    char *entry;
    char *curdir;
    mode_t mode;
    char *dirlist;
    int isdir=0;
    int dircount=0;
    PSHA1CTX shactx;
    WORD8 dg[SHA1_DIGESTSIZE], tdg[SHA1_DIGESTSIZE];
    archive_entry *ars_entry;
    cpdu_file_type ft;

    archive_name = larchive_name;

    if ( stat(archive_name, &sb) == -1 ) { merror("%s: %s\n", archive_name, strerror(errno)); return -1; }

    ft = cpdu_query_file_type(archive_name);

    archive = fopen(archive_name, "rb");

    r = fread(hdr, 1, ft == cpdu_backup_archive ? sizeof(cpdu_archive_backup_hdr) : sizeof(cpdu_archive_hdr), archive);

    if ( ft != cpdu_backup_archive && ft != cpdu_archive ) {
        merror("file %s is not cpdu archive\n", archive_name);
        fclose(archive);
        return -1;
    }
   
    if ( ft == cpdu_archive ) {
    r = fread(tdg, 1, SHA1_DIGESTSIZE, archive);
    r = fread(&curcode, 1, 1, archive);

        codeset = 1;
        if ( cipherctx ) freeCipherContext(cipherctx);
        cipherctx = determineCipherContext(NULL);
        if ( opts->usekeyfile ) {
                int ret;
                if ( passbuf ) _secureclearpassbuf();
                passbuf = (unsigned char*) malloc(curkeysize);
                passbufsz = (unsigned long*) malloc(sizeof(unsigned long));
                *passbufsz = curkeysize;
                ret = read_key_from_keyfile(opts->keyfile, passbuf, curkeysize);
                if ( ret == -1 ) {
                        merror("could not retrieve key from keyfile %s\n", opts->keyfile);
                        free(vencrypt);
                        return -1;
                }
        }

    if ( opts->keylist && !opts->usekeyfile ) { int ret;
        ret = getkey_from_masterkeylist(tdg); /* FIXME: currently, we have no internal security mechanism for the master keylist */
        if ( ret != 0 ) {
            merror("could not retrieve key for archive %s. key is not in the current master list. aborting decryption.\n", archive);
            fclose(archive);
            return -1;
        }
    }
    shactx = SHA1_Create();
    SHA1_Update(shactx, passbuf, *passbufsz);
    SHA1_Final(dg, shactx);
    if ( memcmp(tdg, dg, SHA1_DIGESTSIZE) ) {
        merror("password for archive %s is incorrect\n", archive_name);
        fclose(archive);
        return -1;
    }
    } /* encrypted or just backup archive if__ */
    r = fread(&count, 1, sizeof(int), archive);
    entrylist = (char**) malloc(sizeof(char*));

    do {
    {
    size_t slen;
    r = fread(&slen, 1, sizeof(size_t), archive);
    entry = (char*) malloc(slen+1);
    r = fread(entry, 1, slen, archive);
    entry[slen] = '\0';
    entrylist = (char**) realloc(entrylist, entrylist_size+=sizeof(char*));
    entrylist[entrylist_count] = entry;
    filecount++;
    entrylist_count++;
    }

    /* we check here to see if any of the archives files already exist, if one does we abort processing the complete archive */
    n = stat(entrylist[entrylist_count-1], &sb);
    if ( n == 0 ) { merror("%s already exists, aborting archive operation\n", entrylist[entrylist_count-1]); return -1; }

{ static char n = 0; char *nentry = entry ; int nn;
if ( n == 0 ) { largest_entry_size = strlen(nentry); n = 1; }
else {
if ( (nn=strlen(nentry)) > largest_entry_size ) largest_entry_size = nn;
}
}

    } while(entrylist_count<count);

    i=0;

    fprintf(stderr, "Package Archive %s: Inflating %d files\nInflating File(s)...\n", archive_name, entrylist_count);

    fprintf(stderr, "inflating files from archive...\n", archive_name);
    //if(opts->progress_rhetm ) fprintf(stderr, "\n");

    do {
               n = 0;
        r = fread(&mode, 1, sizeof(mode_t), archive);
        if ( S_ISDIR(mode) ) {
            curdir = entrylist[i];
            mkdir(curdir, mode);
            i++;
            dircount++;
            continue;
        }
        r = fread(&size, 1, sizeof(size_t), archive);
        fprintf(stderr, " inflating: %s\n", entrylist[i]);
    {
        char *dup, *o=NULL;
        int chgn=0;
        retry:
            if ( stat(entrylist[i], &sb) == 0 ) {
                if ( chgn == 0 ) o = strdup(entrylist[i]);
                chgn++;
                dup = chgn ? o : strdup(entrylist[i]);
                entrylist[i] = (char*) realloc(entrylist[i], strlen(entrylist[i])+4);
                snprintf(entrylist[i], strlen(entrylist[i])+4,"%s(%d)\0", dup, chgn);
                if( o != dup ) { free(dup); dup = NULL; }
                goto retry;
            }
        if ( o ) free(o);
    }
        file = fopen(entrylist[i], "wb");
            if ( !file ) {
                merror("in archive %s: file %s cannot be created: %s\n", archive_name, entrylist[i], strerror(errno));
                merror("aborting unloading archive %s\n", archive_name);
                fclose(archive);
                return -1;
            }
    { unsigned long long dn = 0, td = size, tr = 0;
        while( size > 0 ) {
            //tr = (size - n) % 4096;
            r = fread(buffer, 1, 1, archive);
            if ( r == -1 || r == 0) { fseek(archive, dn, SEEK_SET); continue; }
            r = fwrite(buffer, 1, 1, file);
            if ( r == -1 || r == 0 ) { fseek(archive, dn, SEEK_SET); continue; }
            size -= r;
            n+=r;
            dn+=r;
            session_current_size += r;
    if ( opts->progress )
    {
    static char sbuf[2000] = {' '};
    static char cbuf[2000] = {' '};
    static char ebuf[2000] = {' '};
    static unsigned long long percent;
    //static unsigned char *pb;
    static unsigned char pb[41], pb2[41];
    static unsigned long long spercent;
    static char lpcnt[10]; static char lpcnt2[10];
    char c, pc;
    static char modl[] = "-\|/-\|/";
    //{ static char n = 0; if ( n == 0 ) { pb = (char*) malloc(largest_entry_size+1); n = 1; } }
    //static char reset = 0;
    //{ int i; if ( reset = 0 ) { fprintf(stderr, "\r%s%s ", lpcnt, pb); for(i=0;i<largest_entry_size;i++) fprintf(stderr, " "); } reset = 1; }
    pb[0] = '('; pb2[0] = '(';
    pb[39] = ')'; pb2[39] = ')';
    pb[40] = '\0'; pb2[40] = '\0';
    memset(pb+1, ' ', 38);
    memset(pb+1, ciphermode == 1 ? '+' : '-', dn*38/td);
    percent = dn*100/td;
    if ( percent > 100 ) percent = 100;
    {/* set percent bar for total file progress for session */
    spercent = session_current_size*100/session_total_size; if ( spercent == 99 || spercent > 100 ) spercent = 100;
    memset(pb2+1, ' ', 38);
    if ( spercent != 100 ) memset(pb2+1, ciphermode == 1 ? '+' : '-', session_current_size*38/session_total_size); if ( spercent == 100 ) memset(pb2+1, ciphermode == 1 ? '+' : '-', 38);
    }
    //{ static char cpercent[6]; sprintf(cpercent, "%d%c|\0", (int) percent, '%');
    //{ int i; for(i=0;i<6;i++) { pb[i] = cpercent[i]; } }
    //fprintf(stderr, "                                                                                                           ");
    //sprintf(sbuf, "\r                                                     \r|%d%c|%s : %s\0", (int) percent, '%', pb, curfile);
    //fprintf(stderr, "%s", sbuf);
    //sprintf(sbuf, "                                                          \r%s\r|%s\0", pb, curfile);
    { char spcstr[3]; char spcstr2[3]; if ( percent < 10 ) sprintf(spcstr, "  \0"); if ( percent == 10 || percent > 10 ) sprintf(spcstr, " \0"); if ( percent == 100 ) sprintf(spcstr, "\0");
    if ( spercent < 10 ) sprintf(spcstr2, "  \0"); if ( spercent == 10 || spercent > 10 ) sprintf(spcstr2, " \0"); if ( spercent == 100 ) sprintf(spcstr2, "\0");
    { sprintf(lpcnt, "(%d%c%s)\0", (int) percent, '%', spcstr); }
    { sprintf(lpcnt2, "(%d%c%s)\0", (int) spercent, '%', spcstr2); }
    }
   
      c += 1; c = c % 8;
      pc = modl[c];
    #if 0
        gettimeofday(&tv,&tz);
        stmsec = tv.tv_sec - stmsec; stmusec = tv.tv_usec - stmusec;
        stmsec = stmsec < 0 ? 0:stmsec; stmusec = stmusec < 0 ? 0:stmusec;
        //fprintf(stderr, "\r|%s||%d%c|%s %s |%d.%d|", opts->cipher, (int) percent, '%',pb, curfile, stmsec, stmusec);
    #endif
    //{ static char *entry; static char n = 0; int i; if ( n == 0 ) { entry = (char*) malloc(largest_entry_size); memset(entry, ' ', largest_entry_size); strcat(entry, "\0"); n = 1; }
    { int i; memset(cbuf, (int) ' ', largest_entry_size); cbuf[largest_entry_size] = '\0'; } //for(i=0;i<largest_entry_size+4;i++) strcat(stderr, " "); }

    #if 0 /* #(@)DEBUG: this is here so that we can print between two different lines at the same time and iterate them separately */
    {    static int fplpos=0; static char z = 0; if ( z == 1 ) { fplpos = get_y_pos(); }
        static int tfplpos=0; static char y = 0; if ( y == 0 ) { tfplpos = get_y_pos(); y = 1; }
        fprintf(stderr, "\033[%d;1H", tfplpos);
        fprintf(stderr, "\r%s %s%s ::Total File Progress::", lpcnt2, pb2);
        if ( z == 0 ) { fprintf(stderr, "\n"); z = 1; }
       
        {static char n = 0; if ( n == 1 ) fprintf(stderr, "\033[%d;1H", fplpos);
       
        n = 1;
        }
   
    } /*fplpos tfplpos*/
    #endif

    //memset(cbuf, ' ', largest_entry_size-strlen(curfile));
    //cbuf[largest_entry_size-strlen(curfile)] = '\0';
    //fprintf(stderr, "\r                                                                                                                                                                    ");
    { static char *ccbuf; ccbuf = (char*) malloc(strlen(opts->cipher)+2+1); memset(ccbuf, ' ', strlen(opts->cipher)+2); ccbuf[strlen(opts->cipher)+2+1] = '\0';
    fprintf(stderr, "                                                                                          \r%s%s %s", pb, lpcnt, entrylist[i]);
    }
    //sprintf(ebuf, "\r                                                                                                                                                                     \r%s%s %s\0", lpcnt, pb, curfile);
    //sprintf(sbuf, "                                                                                                    %s\0", ebuf);
    //sprintf(sbuf, "\r                                                                                                \r%s%s %s\0", lpcnt, pb, curfile);
    //sprintf(sbuf, "\r%s%s %s\0", lpcnt, pb, curfile);

    } /* opts->progress */
    }
        }
        //if ( opts->progress_piouemy ) fprintf(stderr, "\n");
        fclose(file);
        chmod(entrylist[i], mode);
        i++;
    } while(i < count);

    new_archive_status_entry(ars_entry)

    //if ( opts->progress_rhetm ) fprintf(stderr, "\n");
   
    fprintf(stderr, "%d File(s), %d Directory(s) Extracted from Package Archive\n", diff(entrylist_count,dircount), dircount);
    fprintf(stderr, "Package Archive '%s' Extracted Correctly\n", larchive_name);

    fclose(archive);   
    return 0;
}

cpdu_file_type cpdu_query_file_type(char *file)
{
    cpdu_file_type ft = cpdu_none;
    size_t n;
    FILE *rd = fopen(file, "r");
    if ( rd == NULL ) {
        merror("coulnt determine file type for file %s: %s\n", file, strerror(errno));
        return cpdu_none;
    }

    char cpdu_archive_s[sizeof(cpdu_archive_hdr)];
    char cpdu_encrypted_s[sizeof(cpdu_encrypt_hdr)];
    char cpdu_backup_archive_s[sizeof(cpdu_archive_backup_hdr)];

#if 0
    { unsigned char buffer[4096], n; size_t r; r = fread(buffer, 1, 4096, rd); n = is_base64_encoded(buffer, r);
        if ( n ) { fclose(rd); return cpdu_encrypted; } else { ft = cpdu_none; }
    }
    fseek(rd, 0, SEEK_SET);
#endif

    n = fread(cpdu_archive_s, 1, sizeof(cpdu_archive_hdr), rd);
        if ( strcmp(cpdu_archive_s, cpdu_archive_hdr) == 0 ) {
            ft = cpdu_archive;
        }
    fseek(rd, 0, SEEK_SET);
    n = fread(cpdu_encrypted_s, 1, sizeof(cpdu_encrypt_hdr), rd);
        if ( strcmp(cpdu_encrypted_s, cpdu_encrypt_hdr) == 0) {
            ft = cpdu_encrypted;
        }
    fseek(rd, 0, SEEK_SET);
    n = fread(cpdu_backup_archive_s, 1, sizeof(cpdu_archive_backup_hdr), rd);
        if ( strcmp(cpdu_backup_archive_s, cpdu_archive_backup_hdr) == 0) {
                    ft = cpdu_backup_archive;
        }

    fclose(rd);
    return ft;
}

void cpdu_signal_sigint(int signal)
{
    fprintf(stderr, "\n");
    merror("signal SIGINT recieved. cleaning up and terminating...");
    curfile = strdup(curfile);
    if ( entrylist ) /* free the file names in the entry list */
    { int i; for(i=0;i<entrylist_count;i++) if ( entrylist[i] ) free(entrylist[i]); }

    if ( normv_int ) {
        float sz = (float) wpsz_int, szdn = (float) wpszdn_int;
        fputc('\n', stderr);
        merror("the last file that was being processed, %s, has been wiped/written-over by %f percent", curfile, (float) (szdn*100/sz));
        if ( wpdn_int ) fprintf(stderr, ", %d times", (int) wpdn_int);
        fputc('\n', stderr);
        merror("the file was encrypted to %s however and you may retrieve plaintext data through normal decryption of this file\n", curfileout);
        free(curfile);
    } else {
    remove(curfileout);
    }
    chmod_secure_mykeydir();
    opts->destructor(opts);
    _secureclearpassbuf();
    freeCipherContext(cipherctx);
    close_system();

    fprintf(stderr, "done.\n");

    exit(1);
}

void status_print_session_done()
{
    if ( !opts->backup ) {
        if ( archivelist_count || opts->doarchive )
        { int i; for(i=0;i<archive_entry_status_list_count;i++) {
                    fprintf(stderr, "Package Archive '%s': %d File(s), %d Directory(s) %s \n", archive_entry_status_list[i]->name, diff(archive_entry_status_list[i]->count, archive_entry_status_list[i]->dircount), archive_entry_status_list[i]->dircount, ciphermode == CIPHER_MODE_ENCRYPT ? "Deflated" : "Extracted");
                 }
        }
        fprintf(stderr, "%s Session Finished: %d File(s) %s\n", ciphermode == CIPHER_MODE_ENCRYPT ? "Encryption" : "Decryption", file_processed_count, ciphermode == CIPHER_MODE_ENCRYPT ? "Encrypted" : "Decrypted");
//        fprintf(stderr, "cpdu: %s [%s]",  ciphermode == CIPHER_MODE_ENCRYPT ? "Session Password commited to the Write Protected Master Key List Database." : "Session Key(s) Intact and Maintained in Write Protected Master Key List Database", masterkeydbfilename);
    } else {
        if ( !opts->progress_rhetm ) fprintf(stderr, "\n");
        fprintf(stderr, "Erase Process done: %d Files Erased", entrylist_count);
    }
}

#include "twofishctx_header.h" /* the twofish context is contained in the twofish.c file. we need to borrow it and restate it globally here */
#include "twofish.h"
void getrandombytes(WORD8* buffer, WORD32 size, void *nothing)
{
    gather_random_fast(buffer, size);
}
int generate_keyfile(char *keyfile, size_t fsize)
{
    int fd=0, i=0, ret=0;
    TWOFISHCTX *ctx=NULL;
    unsigned char *key=NULL;
    unsigned char *fbuf=NULL;
    unsigned char *initdata=NULL;
    unsigned int rounds=0;
    char prompt_for_entropy[] = "This process may block until enough entropy is gathered to resolve a read\nfrom the random device file. You may move your mouse or type all you like\nuntil enough entropy is gathered to resolve this.";



    if ( fsize < TWOFISH_KEYSIZE ) {
        merror("the keyfile size specified is smaller than the\ntwofish algorithm keysize, it must be larger than 32 bytes");
        return -1;
    }

    ctx = (TWOFISHCTX*) smalloc(sizeof(TWOFISHCTX));
        if (!ctx) {
            merror("unable to allocate memory for cipher context");
            return -1;
        }
    memset(ctx, 0x00, sizeof(TWOFISHCTX));

    key = (unsigned char *) smalloc(TWOFISH_KEYSIZE);
        if ( !key ) {
            merror("unable to allocate memory for keyspace");
            goto _error_;
        }

    initdata = (unsigned char *) smalloc(sizeof(TWOFISH_BLOCKSIZE));
        if ( !key ) {
            merror("unable to allocate memory for cipher initdata");
            goto _error_;
        }

    fd = open(keyfile, O_WRONLY|O_CREAT|O_EXCL, S_IRUSR);
        if ( fd == -1 ) {
            merror("could not create keyfile %s: %s", keyfile,
strerror(errno));
            goto _error_;
        }

    fprintf(stderr, "\n%s\n", prompt_for_entropy);

    gather_random_slow(key, TWOFISH_KEYSIZE);
    gather_random_fast(&rounds, sizeof(int));
    gather_random_fast(initdata, TWOFISH_BLOCKSIZE);
    rounds = rounds % 2;
    Twofish_CreateWorkContext(ctx, key, TWOFISH_KEYSIZE, CIPHER_MODE_ENCRYPT, initdata,
            (Cipher_RandomGenerator*)getrandombytes, NULL);

    fprintf(stderr, "Generating...");
{   
    char pb[41];
    unsigned long bufsiz=(fsize>4096?4096:fsize);
    long bytes=fsize;
    long r=0;
    int n=0;
    int sofar = 0, total = bytes;

    pb[0] = '[';
    pb[39] = ']';
    pb[40] = '\0';

    fbuf = (unsigned char *) smalloc(bufsiz+TWOFISH_BLOCKSIZE);
        if ( !fbuf ) {
            merror("could not allocate 4096 byte buffer");
            return -1;
        }

    while ( bytes > 0 ) {
   
    for(i=0;i<rounds;i++)
        Twofish_EncryptBuffer(ctx,key,key,TWOFISH_KEYSIZE);
   
    gather_random_fast(fbuf, bufsiz);
    Twofish_EncryptBuffer(ctx,fbuf,fbuf,bufsiz);

    if (r >= fsize-bufsiz)
        n = fsize-r;
    else
        n=bufsiz;
   
    do {
        n = write(fd, fbuf, n);
    } while ( n == -1 && errno == EINTR );
    if (n < 0) {
        merror("keydata write to keyfile %s failed: %s", keyfile, strerror(errno));
        return -1;
    }
    r+=n;
    bytes = bytes - n;

    sofar+=n;
    memset(pb+1, ' ', 38);
    memset(pb+1, '#', (int) sofar*38/total);
    fprintf(stderr,"\r[%d%c]%s %s Generating...", (int) sofar*100/total, '%', &pb[0], keyfile);
    } /* while */
    memset(fbuf, 0x00, bufsiz);
    sfree(fbuf);
}
    fprintf(stderr, "done.\n");

    goto _success_;

_error_:
    ret = -1;

_success_:
    if (ctx) {
        Twofish_DestroyWorkContext(ctx);
        sfree(ctx);
    }
    if ( initdata ) {
        memset(initdata, 0x00, TWOFISH_BLOCKSIZE);
        memset(initdata, 0x00, TWOFISH_BLOCKSIZE);
        memset(initdata, 0x00, TWOFISH_BLOCKSIZE);
        sfree(initdata);
    }
    if ( key ) {
        memset(key, 0x00, TWOFISH_KEYSIZE);
        memset(key, 0x00, TWOFISH_KEYSIZE);
        memset(key, 0x00, TWOFISH_KEYSIZE);
        sfree(key);
    }

    close(fd);

    return ret;
}

unsigned char *crunch_key(unsigned char *xkey, unsigned long xkeysize, unsigned char *keybuf, unsigned long outsize)
{
    static TWOFISHCTX *ctx=NULL;

    if ( !xkey )
        goto _return;

    if ( !ctx ) {
    ctx = (TWOFISHCTX*) smalloc(sizeof(TWOFISHCTX));
        if (!ctx) {
            merror("unable to allocate memory for cipher context");
            return NULL;
        }
    }
    initcbcblock = (unsigned char*) malloc(TWOFISH_BLOCKSIZE);
    cipher_block_mode = CIPHER_MODE_CBC;
    Twofish_CreateWorkContext(ctx, xkey, xkeysize, CIPHER_MODE_ENCRYPT, initcbcblock, &get_random_bytes, NULL);
    Twofish_EncryptBuffer(ctx, keybuf, keybuf, outsize);


    if ( ctx )
        Twofish_DestroyWorkContext(ctx);

    _return:

    return keybuf;
}

int read_key_from_keyfile(char *keyfile, unsigned char *keybuf, unsigned long keysize)
{
    int fd, i, bytes=0, r=0, n=0;
    unsigned char *buffer=NULL;
    unsigned char *key=NULL;
    struct stat statbuf;

    if ( !buffer )
        buffer = (unsigned char *) malloc(4096);
    if ( !buffer ) {
        merror("unable to allocate 4096 bytes from secure memory");
        return -1;
    }

    chmod_unsecure_file(keyfile);
    fd = open(keyfile, O_RDONLY);
        if ( fd == -1 ) {
            merror("could not open keyfile %s: %s", keyfile, strerror(errno));
            return -1;
        }

    if ( stat(keyfile, &statbuf) == -1 ) {
        merror("could not stat keyfile %s: %s", keyfile, strerror(errno));
        close(fd);
        return -1;
    }

    bytes = statbuf.st_size;

    memset(keybuf, 0, keysize);

    while ( bytes > 0 ) {
    do {
        n = read(fd, buffer, 4096);
    } while ( n == -1 && errno == EINTR );
    if ( n == -1 ) {
        merror("read from keyfile %s failed: %s", keyfile, strerror(errno));
        return -1;
    }
    key = crunch_key(buffer, n, keybuf, keysize);
        if ( !key ) {
            crunch_key(NULL,0,NULL,0);
            free(buffer);
            return -1;
        }
    bytes -= n;
    }

    free(buffer);
    crunch_key(NULL,0,NULL,0);
    close(fd);
    chmod_secure_file(keyfile);
    return 0;
}



#if 0
#define CTRLD     4
void menu_directory_select()
{    ITEM **my_items;
    int c;               
    MENU *my_menu;
        int n_choices, i;
    ITEM *cur_item;
int current = 0;
    char *currentdir;
    char* prev_dir;
    char* fdir = getenv("PWD");
   
    /* Initialize curses */   
    initscr();
    start_color();
        cbreak();
        noecho();
    keypad(stdscr, TRUE);
    init_pair(1, COLOR_RED, COLOR_BLACK);
    init_pair(2, COLOR_GREEN, COLOR_BLACK);
    init_pair(3, COLOR_MAGENTA, COLOR_BLACK);


    currentdir = fdir;
    prev_dir = currentdir;

    entrylist = NULL;

    il = (char**) malloc(ilsz+=sizeof(char**));
    ilcnt = 0;

    __dir:
    if ( entrylist ) free(entrylist);
    current = 0;
    entrylist = menu_getdir(currentdir);
    if ( !entrylist ) { currentdir = prev_dir; goto __dir; }
   
    /* Initialize items */
        n_choices = (int) entrylist_count;
    choices = entrylist;
        my_items = (ITEM **)calloc(n_choices + 1, sizeof(ITEM *));
        for(i = 0; i < n_choices; ++i)
                my_items[i] = new_item(choices[i], NULL);
    my_items[n_choices] = (ITEM *)NULL;

    /* Create menu */
    my_menu = new_menu((ITEM **)my_items);

    /* Set fore ground and back ground of the menu */
    set_menu_fore(my_menu, COLOR_PAIR(1) | A_REVERSE);
    set_menu_back(my_menu, COLOR_PAIR(2));
    set_menu_grey(my_menu, COLOR_PAIR(3));

    /* Post the menu */
    mvprintw(LINES - 3, 0, "Press <ENTER> to see the option selected, Press 'A' to select all");
    mvprintw(LINES - 2, 0, "Up and Down arrow keys to naviage ('E' to Exit)");
    post_menu(my_menu);
    refresh();

    while((c = getch()) != 'E')
    {       switch(c)
            {    case KEY_DOWN:
                menu_driver(my_menu, REQ_DOWN_ITEM);
                break;
            case KEY_UP:
                menu_driver(my_menu, REQ_UP_ITEM);
                break;
            case 10: /* Enter */
                move(20, 0);
                clrtoeol();
                mvprintw(20, 0, "Item selected is : %s",
                        item_name(current_item(my_menu)));
                pos_menu_cursor(my_menu);
            { struct stat sb; char *string;          
                    string = (char*) malloc(strlen(fdir)+strlen(item_name(current_item(my_menu)))+3);
                    strcpy(string, fdir);
                    strcat(string, "/");
                    strcat(string, "\0");
                    strcpy(string+strlen(fdir)+1, item_name(current_item(my_menu)));
                    strcat(string, "\0");
                    stat(string, &sb);                   
                    if ( S_ISDIR(sb.st_mode) ) {
                        fdir = currentdir = string;
                        goto __dir;
                    }
            }
                    { char* string;
                    string = (char*) malloc(strlen(fdir)+strlen(item_name(current_item(my_menu)))+3);
                    strcpy(string, fdir);
                    strcat(string, "/");
                    strcat(string, "\0");
                    strcpy(string+strlen(fdir)+1, item_name(current_item(my_menu)));
                    strcat(string, "\0");
                    il = (char**) realloc(il, ilsz+=sizeof(char*));
                    il[ilcnt++] = string;
                    }
            break;
            case 'A':
            { int a; struct stat sb;
              for(a=0; a<entrylist_count; a++) {
            { struct stat sb;
                stat(entrylist[a], &sb);
                if ( S_ISDIR(sb.st_mode) ) {
                    continue;
                }
            }
                    { char* string;               
                    string = (char*) malloc(strlen(fdir)+strlen(entrylist[a])+3);
                    strcpy(string, fdir);
                    strcat(string, "/");
                    strcat(string, "\0");
                    strcpy(string+strlen(fdir)+1, entrylist[a]);
                    strcat(string, "\0");
                    il = (char**) realloc(il, ilsz+=sizeof(char*));
                    il[ilcnt++] = string;
                    }
                   }
              }
            break;
        }
    }   
    unpost_menu(my_menu);
    for(i = 0; i < n_choices; ++i)
        free_item(my_items[i]);
    free_menu(my_menu);
    endwin();
}
#endif

void menu_directory_select()
{
    ITEM **my_items;
    int c;               
    MENU *my_menu;
    int n_choices, i;
    ITEM *cur_item;
    int current = 0;
    char *currentdir;
    char* prev_dir;
    char* fdir = getenv("PWD");
    unsigned long menu_count = 0;

    currentdir = fdir;
    prev_dir = currentdir;

    entrylist = NULL;

    il = (char**) malloc(ilsz+=sizeof(char**));
    ilcnt = 0;

    initscr();
    cbreak();
    noecho();
    keypad(stdscr, TRUE);

    __dir:
    erase();
    if ( entrylist ) free(entrylist);
    current = 0;
    entrylist = menu_getdir(currentdir);
    if ( !entrylist ) {     mvprintw(LINES - 5, 0, "'E' to Exit. Press 'Enter' for each file to decrypt, Press 'A' to select all in directory.: %s", currentdir); currentdir = prev_dir; goto __dir; }
    if ( menu_count ) { mvprintw(LINES - 3, 0, "Items Selected for Processing: %d", menu_count); }

    n_choices = (int) entrylist_count;
    choices = entrylist;
    my_items = (ITEM **)calloc(n_choices + 1, sizeof(ITEM *));

    for(i = 0; i < n_choices; ++i)
            my_items[i] = new_item(choices[i], NULL);
    my_items[n_choices] = (ITEM *)NULL;

    my_menu = new_menu((ITEM **)my_items);
    { int x, y;
        getmaxyx(stdscr, y, x);
        set_menu_format(my_menu, y-10, 1);
    }

    //mvprintw(LINES - 2, 0, "'E' to Exit. Press 'Enter' for each file to decrypt, Press 'A' to select all in directory.");


    post_menu(my_menu);
    refresh();

    while((c = getch()) != 'E')
    {  
        switch(c)
        {
            case KEY_DOWN:
                menu_driver(my_menu, REQ_DOWN_ITEM);
                break;
            case KEY_UP:
                menu_driver(my_menu, REQ_UP_ITEM);
                break;
            case '\n':
            { struct stat sb; char *string;          
                    string = (char*) malloc(strlen(fdir)+strlen(item_name(current_item(my_menu)))+3);
                    strcpy(string, fdir);
                    strcat(string, "/");
                    strcat(string, "\0");
                    strcpy(string+strlen(fdir)+1, item_name(current_item(my_menu)));
                    strcat(string, "\0");
                    stat(string, &sb);                   
                    if ( S_ISDIR(sb.st_mode) ) {
                        prev_dir = currentdir;
                        fdir = currentdir = string;
                        goto __dir;
                    }
            }
                    { char* string;
                    string = (char*) malloc(strlen(fdir)+strlen(item_name(current_item(my_menu)))+3);
                    strcpy(string, fdir);
                    strcat(string, "/");
                    strcat(string, "\0");
                    strcpy(string+strlen(fdir)+1, item_name(current_item(my_menu)));
                    strcat(string, "\0");
                    mvprintw(LINES - 2, 0, "%s                                                  ", string);
                    il = (char**) realloc(il, ilsz+=sizeof(char*));
                    il[ilcnt++] = string;
                    }
            menu_count++;
mvprintw(LINES - 3, 0, "Items Selected for Processing: %d", menu_count);

            break;
            case 'A':
            { int a; struct stat sb;
              for(a=0; a<entrylist_count; a++) {
                    { char* string;               
                    string = (char*) malloc(strlen(fdir)+strlen(entrylist[a])+3);
                    strcpy(string, fdir);
                    strcat(string, "/");
                    strcat(string, "\0");
                    strcpy(string+strlen(fdir)+1, entrylist[a]);
                    strcat(string, "\0");
            { struct stat sb;
                stat(string, &sb);
                if ( S_ISDIR(sb.st_mode) ) {
                    free(string); continue;
                }
            }
                    il = (char**) realloc(il, ilsz+=sizeof(char*));
                    il[ilcnt++] = string;
                    }
                menu_count++;
                   }
              }
mvprintw(LINES - 3, 0, "Items Selected for Processing: %d", menu_count);
            break;
        }
    }   

    free_item(my_items[0]);
    free_item(my_items[1]);
    free_menu(my_menu);
    endwin();   
}


int _reseal_fillentrylist()
{
 char* string;
 int sz;
 char *c;
 char* filename;
 FILE *f;
 struct stat sb;
 size_t sizefile = 0;
 int null_count = 0;

  filename = (char*) malloc(strlen(getenv("HOME"))+strlen(processedlist_filename)+1);
  strcpy(filename, getenv("HOME"));
  strcat(filename, processedlist_filename);
 
 f = fopen(filename, "r");
 { int r; r = stat(filename, &sb); if ( r == -1 ) { merror("no hot track list available. maybe all files were decrypted\n"); return 1; } }
 
 entrylist = NULL;
 entrylist_count = 0;
 entrylist_size = 0;
 string = NULL;
 sz = 0;

 do {
    int r;
    char c;
    r = fread(&c, 1, 1, f);
    if ( sb.st_size == ++sizefile) goto string__;
    if ( c == '\n' ) {
      string__:
      string = (char*) realloc(string, ++sz);
      string[sz-1] = '\0';
    if ( cpdu_query_file_type(string) == cpdu_encrypted ) { sz = 0; null_count = 1; continue; } else { hottrackcount = 1; }
    if ( entrylist == NULL ) { entrylist = (char**) malloc(entrylist_size+=sizeof(char**)); }
      entrylist = (char**) realloc(entrylist, entrylist_size+=sizeof(char*));
      entrylist_count += 1;
      entrylist[entrylist_count-1] = strdup(string);
 //fprintf(stderr, "entrylist: %s. string: %s\n", entrylist[entrylist_count-1], string);
      sz = 0;
    } else {
     if ( sz == 0 ) { string = (char*) malloc(1); sz++; }
     else { string = (char*) realloc(string, ++sz); }
     string[sz-1] = c;
    }
 } while( !(sb.st_size == sizefile) );
 menu__:
 //if ( null_count && entrylist_count ) { fclose(f); remove(filename); { int i; for ( i = 0; i<entrylist_count; i++)
   //  add_to_processedlist(entrylist[i]);
 //}
 if ( null_count && !entrylist_count ) { hottrackcount = 0; merror("all hot track files are encrypted already\n"); fclose(f); return 1; } else { fclose(f); }

 return 0;
}

int _purge_fillentrylist()
{
 char* string;
 int sz;
 char *c;
 char* filename;
 FILE *f;
 struct stat sb;
 size_t sizefile = 0;
 int null_count = 0;

  filename = (char*) malloc(strlen(getenv("HOME"))+strlen(processedlist_filename)+1);
  strcpy(filename, getenv("HOME"));
  strcat(filename, processedlist_filename);
 
 f = fopen(filename, "r");
 { int r; r = stat(filename, &sb); if ( r == -1 ) { merror("no hot track list currently. if there are encrypted files that you are not sure are encrypted in locations that cant be determined, run a recursive '-dr (base_directory) check and all files that are encrypted will automatically be detected.\n"); remove(filename); hottrackcount = 1; return 1; } }
 
 entrylist = NULL;
 entrylist_count = 0;
 entrylist_size = 0;
 string = NULL;
 sz = 0;

 do {
    int r;
    char c;
    r = fread(&c, 1, 1, f);
    if ( sb.st_size == ++sizefile) goto string__;
    if ( c == '\n' ) {
      string__:
      string = (char*) realloc(string, ++sz);
      string[sz-1] = '\0';
    if ( cpdu_query_file_type(string) == cpdu_none ) { null_count++; }
    if ( entrylist == NULL ) { entrylist = (char**) malloc(entrylist_size+=sizeof(char**)); }
      entrylist = (char**) realloc(entrylist, entrylist_size+=sizeof(char*));
      entrylist_count += 1;
      entrylist[entrylist_count-1] = strdup(string);
 //fprintf(stderr, "entrylist: %s. string: %s\n", entrylist[entrylist_count-1], string);
      sz = 0;
    } else {
     if ( sz == 0 ) { string = (char*) malloc(1); sz++; }
     else { string = (char*) realloc(string, ++sz); }
     string[sz-1] = c;
    }
 } while( !(sb.st_size == sizefile) );
 menu__:
 //if ( null_count && entrylist_count ) { fclose(f); remove(filename); { int i; for ( i = 0; i<entrylist_count; i++)
   //  add_to_processedlist(entrylist[i]);
 //}
 //if ( null_count && !entrylist_count ) { hottrackcount = 0; merror("all hot track files are encrypted already\n"); fclose(f); return 1; } else { fclose(f); }
    if ( null_count == entrylist_count ) { hottrackcount = 1; }
     remove(filename);
 fclose(f);
 return 0;
}

#if 0
void _hottracklist_fill_entrylist()
{
    int eof = 0;
    FILE *f;
    char* filename;
    filename = (char*) malloc(strlen(getenv("HOME"))+strlen(processedlist_filename)+1);
    strcpy(filename, getenv("HOME"));
    strcat(filename, processedlist_filename);

    f = fopen(filename, "r");
   
    if (f == NULL ) {
        merror("%s recover list file does not exist at this point\n");
        exit(1);
    }
   
    while( eof == 0 ) {
        { char n; do { fread(&n, 1, 1, f); if ( feof(f) ) { eof = 1; }
                        if ( eof == 0 ) { static int sz = 0; static char* string = NULL;
                        if ( n == '\n' ) {
                            if ( entrylist == NULL )
                                entrylist = (char**) malloc(entrylist_size+=sizeof(char**));
                            else
                                entrylist = (char**) realloc(entrylist, entrylist_size+=sizeof(char*));
                            entrylist[entrylist_count++] = string;
                            sz = 0;
                        continue;
                        }
                        if ( eof == 1 ) break;
                        if ( string == NULL )
                            string = (char*) malloc(sz+=1);
                        else
                            string  = (char*) realloc(string, sz+=1);
                        string[sz-1] = n;
                        }
                    } while ( 1 );
        }
    if ( eof == 1 ) break;   
    }
}
#endif

#if 0
void menu_()
{    ITEM **my_items;
    int c;               
    MENU *my_menu;
        int n_choices, i;
    ITEM *cur_item;

   
    /* Initialize curses */   
    initscr();
    start_color();
        cbreak();
        noecho();
    keypad(stdscr, TRUE);
    init_pair(1, COLOR_RED, COLOR_BLACK);
    init_pair(2, COLOR_GREEN, COLOR_BLACK);
    init_pair(3, COLOR_MAGENTA, COLOR_BLACK);


    il = (char**) malloc(ilsz+=sizeof(char**));
    ilcnt = 0;

    /* Initialize items */
        n_choices = (int) entrylist_count;
    choices = entrylist;
        my_items = (ITEM **)calloc(n_choices + 1, sizeof(ITEM *));
        for(i = 0; i < n_choices; ++i)
                my_items[i] = new_item(choices[i], NULL);
    my_items[n_choices] = (ITEM *)NULL;

    /* Create menu */
    my_menu = new_menu((ITEM **)my_items);

    /* Set fore ground and back ground of the menu */
    set_menu_fore(my_menu, COLOR_PAIR(1) | A_REVERSE);
    set_menu_back(my_menu, COLOR_PAIR(2));
    set_menu_grey(my_menu, COLOR_PAIR(3));

    /* Post the menu */
    mvprintw(LINES - 3, 0, "Press <ENTER> to see the option selected, Press 'A' to select all");
    mvprintw(LINES - 2, 0, "Up and Down arrow keys to naviage ('E' to Exit)");
    post_menu(my_menu);
    refresh();

    while((c = getch()) != 'E')
    {       switch(c)
            {    case KEY_DOWN:
                menu_driver(my_menu, REQ_DOWN_ITEM);
                break;
            case KEY_UP:
                menu_driver(my_menu, REQ_UP_ITEM);
                break;
            case 10: /* Enter */
                move(20, 0);
                clrtoeol();
                mvprintw(20, 0, "Item selected is : %s",
                        item_name(current_item(my_menu)));
                pos_menu_cursor(my_menu);

                il = (char**) realloc(il, ilsz+=sizeof(char*));
                il[ilcnt++] = strdup(item_name(current_item(my_menu)));
            break;
            case 'A':
            { int a;
              for(a=0; a<entrylist_count; a++) {
                    il = (char**) realloc(il, ilsz+=sizeof(char*));
                il[ilcnt++] = entrylist[a];
              }
            }
            break;
        }
    }   
    unpost_menu(my_menu);
    for(i = 0; i < n_choices; ++i)
        free_item(my_items[i]);
    free_menu(my_menu);
    endwin();
}
#endif

void menu_()
{    ITEM **my_items;
    int c;               
    MENU *my_menu;
    int n_choices, i;
    ITEM *cur_item;
    int current = 0;

    initscr();
    cbreak();
    noecho();
    keypad(stdscr, TRUE);
   
    il = (char**) malloc(sizeof(char**));
    ilsz+=sizeof(char*);
    ilcnt = 0;

    n_choices = (int) entrylist_count;
    choices = entrylist;
    my_items = (ITEM **)calloc(n_choices + 1, sizeof(ITEM *));

    for(i = 0; i < n_choices; ++i)
            my_items[i] = new_item(choices[i], NULL);
    my_items[n_choices] = (ITEM *)NULL;

    my_menu = new_menu((ITEM **)my_items);
    { int x, y;
        getmaxyx(stdscr, y, x);
        set_menu_format(my_menu, y-10, 1);
    }
   
    if ( opts->print_processed_list ) {
      mvprintw(LINES - 2, 0, "'E' to Exit. Press 'Enter' for each file to decrypt, Press 'A' to select all.");
    }
    else {
      mvprintw(LINES - 2, 0, "'E' to Exit. Press 'Enter' for each file to Encrypt");
    }
   
    post_menu(my_menu);
    refresh();

    while((c = getch()) != 'E')
    {   switch(c)
        {    case KEY_DOWN:
                menu_driver(my_menu, REQ_DOWN_ITEM);
                break;
            case KEY_UP:
                menu_driver(my_menu, REQ_UP_ITEM);
                break;
            case '\n':
                il = (char**) realloc(il, ilsz+=sizeof(char*));
                il[ilcnt++] = item_name(current_item(my_menu));
            break;
            case 'A':
            { int a;
              for(a=0; a<entrylist_count; a++) {
                il = (char**) realloc(il, ilsz+=sizeof(char*));
                il[ilcnt++] = entrylist[a];
              }
            }
            break;
        }
    }   

    free_item(my_items[0]);
    free_item(my_items[1]);
    free_menu(my_menu);
    endwin();
}


#if 0
const char *processedrecoverlist_filename = "/.cpdu_processedrecoverlist";
char** recover_hash_list;
unsigned long recover_hash_list_size;
unsigned long recover_hash_list_count;

void add_to_processedrecoverlist(char* string_filename)
{
  FILE* f;
  char* filename;
  unsigned char dg[SHA1_DIGESTSIZE];
  filename = (char*) malloc(strlen(getenv("HOME"))+strlen(processedrecoverlist_filename)+1);
  strcpy(filename, getenv("HOME"));
  strcat(filename, processedrecoverlist_filename);
  f = fopen(filename, "a+");
  //&dg[0] = sha1_get_file_hash(string_filename);

  //fprintf(f, "%s %s\n", string_filename, &dg[0]);
  fprintf(f, "%s\n", string_filename);

  fclose(f);
}

void print_recoverprocessed_list()
{
 char* string;
 int sz;
 char *c;
 char* filename;
 FILE *f;
 struct stat sb;
 unsigned char dg[SHA1_DIGESTSIZE];

 size_t sizefile = 0;

  filename = (char*) malloc(strlen(getenv("HOME"))+strlen(processedrecoverlist_filename)+1);
  strcpy(filename, getenv("HOME"));
  strcat(filename, processedrecoverlist_filename);
 
 f = fopen(filename, "r");
 stat(filename, &sb);
 
 entrylist = NULL;
 entrylist_count = 0;
 entrylist_size = 0;
 string = NULL;
 sz = 0;
 recover_hash_list = NULL;
 recover_hash_list_size = 0;
 recover_hash_list_count = 0;

 do {
    char c;
    fread(&c, 1, 1, f); sizefile++;
    if ( sizefile == sb.st_size ) goto menu__;
    //if ( feof(f) ) goto menu__;
    if ( c == '\n' ) {
      if ( entrylist == NULL ) { entrylist = (char**) malloc(entrylist_size+=sizeof(char**)); }
      entrylist = (char**) realloc(entrylist, entrylist_size+=sizeof(char*));
      entrylist_count += 1;
      string = (char*) realloc(string, ++sz);
      string[sz-1] = '\0';
      entrylist[entrylist_count-1] = strdup(string);
 //fprintf(stderr, "entrylist: %s. string: %s\n", entrylist[entrylist_count-1], string);
      sz = 0;

#if 0
    } else if ( c == ' ' ) {
      if ( recover_hash_list == NULL ) { recover_hash_list = malloc(recover_hash_list_size+=(unsigned char**)); recover_hash_list_size++; }
      recover_hash_list = (unsigned char**) realloc(recover_hash_list, recover_hash_list_size+=sizeof(unsigned char*));
      fread(&dg[0], SHA1_DIGESTSIZE, 1, f);
      recover_hash_list_count++;
      recover_hash_list[recover_hash_list_count-1] = strdup(&dg[0]);
#endif
    } else {
     if ( sz == 0 ) { string = (char*) malloc(1); sz++; }
     else { string = (char*) realloc(string, ++sz); }
     string[sz-1] = c;
    }
 } while( !feof(f) );
 menu__:
 fclose(f);
 menu_();
}
#endif
#if 0
void _run_keystore_daemon()
{

FILE *fp= NULL;
pid_t process_id = 0;
pid_t sid = 0;
char *keystore_master = NULL;
char *keystore_slkey = NULL;

keystore_master = (char*) malloc(strlen(make_mykeydir())+strlen(keystore_master)+strlen(".masterkeylist")+2);
strcpy(keystore_master, make_mykeydir());
strcat(keystore_master, "/");
strcat(keystore_master, ".masterkeylist");

keystore_slkey = (char*) malloc(strlen(make_mykeydir())+strlen(keystore_slkey)+strlen(".keyfile")+2);
strcpy(keystore_slkey, make_mykeydir());
strcat(keystore_slkey, "/");
strcat(keystore_slkey, ".keyfile");



// Create child process
process_id = fork();
// Indication of fork() failure
if (process_id < 0)
{
printf("fork failed!\n");
// Return failure in exit status
exit(1);
}

//unmask the file mode
umask(0);
//set new session
sid = setsid();
if(sid < 0)
{
// Return failure
exit(1);
}

{ int fdslk; int fdmkl;
    fdslk = open(keystore_slkey, __O_PATH);
    fdmkl = open(keystore_master, __O_PATH);
    flock(fdslk, LOCK_EX);
    flock(fdmkl, LOCK_EX);
}   

return (0);
}
#endif

void add_to_processedlist(char* string_filename)
{
  FILE* f;
  char* filename;
  filename = (char*) malloc(strlen(getenv("HOME"))+strlen(processedlist_filename)+1);
  strcpy(filename, getenv("HOME"));
  strcat(filename, processedlist_filename);
  f = fopen(filename, "a+");
  fprintf(f, "%s\n", string_filename);
  fclose(f);
}


void write_recovery_log(int argc, char** argv)
{
        time_t log_time;
        FILE* log;
        char* filename;
        filename = (char*) malloc(strlen(getenv("HOME"))+strlen("/.cpdu/cpdu_sessions_log")+1);
        sprintf(filename, "%s%s\0", getenv("HOME"), "/.cpdu/cpdu_sessions_log");
        log = fopen(filename, "a+");
        time(&log_time);
        fprintf(log, "\n-------------------------\n");
        fprintf(log, "%sCryptographic Data Utility Session", ctime(&log_time));
        fprintf(log, "\nWorking directory: %s", get_current_dir_name());
        fprintf(log, "\n-------------------------\n");
        fprintf(log, "Number of files: %d\n", entrylist_count);
        fprintf(log, "Command Line: ");
        {
            int i;
            for(i=0;i<argc;i++) {
                fprintf(log, "%s ", argv[i]);
            }
        }
        if ( access_lock_warning ) fprintf(log, "\nWARNING: INVALID PASSWORD FOR PROGRAM ACCESS!");
        fprintf(log, "\n-------------------------\n");
        /* 9 line breaks before entrylist */
        {
            int i;
            for(i=0;i<entrylist_count;i++) {
                fprintf(log, "%s\n", entrylist[i]);
            }
        }
}

int print_processed_list()
{
 char* string;
 int sz;
 char *c;
 char* filename;
 FILE *f;
 struct stat sb;
 size_t sizefile = 0;
 int null_count = 0;

  filename = (char*) malloc(strlen(getenv("HOME"))+strlen(processedlist_filename)+1);
  strcpy(filename, getenv("HOME"));
  strcat(filename, processedlist_filename);
 
 f = fopen(filename, "r");
 { int r; r = stat(filename, &sb); if ( r == -1 ) { merror("no files are encrypted\n"); return 1; } }
 
 entrylist = NULL;
 entrylist_count = 0;
 entrylist_size = 0;
 string = NULL;
 sz = 0;

 do {
    int r;
    char c;
    r = fread(&c, 1, 1, f);
    if ( sb.st_size == ++sizefile) goto string__;
    if ( c == '\n' ) {
      string__:
      string = (char*) realloc(string, ++sz);
      string[sz-1] = '\0';
    if ( cpdu_query_file_type(string) == cpdu_none ) { sz = 0; null_count = 1; continue; }
    if ( entrylist == NULL ) { entrylist = (char**) malloc(entrylist_size+=sizeof(char**)); }
      entrylist = (char**) realloc(entrylist, entrylist_size+=sizeof(char*));
      entrylist_count += 1;
      entrylist[entrylist_count-1] = strdup(string);
 //fprintf(stderr, "entrylist: %s. string: %s\n", entrylist[entrylist_count-1], string);
      sz = 0;
    } else {
     if ( sz == 0 ) { string = (char*) malloc(1); sz++; }
     else { string = (char*) realloc(string, ++sz); }
     string[sz-1] = c;
    }
 } while( !(sb.st_size == sizefile) );
 menu__:
 //if ( null_count && entrylist_count ) { fclose(f); remove(filename); { int i; for ( i = 0; i<entrylist_count; i++)
   //  add_to_processedlist(entrylist[i]);
 //}
 if ( null_count && !entrylist_count ) { merror("no files are encrypted\n"); fclose(f); return 1; } else { fclose(f); }
 menu_();
 return 0;
}

#if 0
char *session_total_progress_string_update()
{
    static char sbuf[2000] = {' '};
    static unsigned long long percent;
    static unsigned char pb[51];
    pb[0] = '|';
    pb[49] = '|';
    pb[50] = '\0';
    memset(pb+1, ' ', 48);
    memset(pb+1, ciphermode == 1 ? '.' : '.', session_current_size*48/session_total_size);
    //percent = session_current_size*100/session_total_size;
    //if ( percent > 100 ) percent = 100;
    sprintf(sbuf, "%s\0", pb);
    return sbuf;
}
#endif

#if 0
char* get_archive_ext()
{
    long bytes;
    int r;
    struct stat sb;
    char buffer[2000] = {' '};
    char extfile[2000] = {' '};
    int exist = 0, fd;
    char *n;
    FILE *f;
   
    strcpy(extfile, make_mydir());
    strcat(extfile, "/");
    strcat(extfile, archive_ext_set_file);
    strcat(extfile, '\0');

    //fprintf(stderr, "\nextfile: %s\n", extfile);
   
    r = stat(extfile, &sb);
    if ( r == -1 ) {
        exist = 0;
    } else {
        exist = 1;
    }

    if ( !exist ) {
    fd = open(extfile, O_CREAT, S_IWUSR|S_IRUSR);
    close(fd);
    }

    if ( !exist ) {
    f = fopen(extfile, "w");
    fprintf(f, "%s", cur_ext);
    fclose(f);
    return cur_ext;
    }
   
    f = fopen(extfile, "r");
    fread(buffer, 1, sb.st_size, f);
    fclose(f);
   
    cur_ext = (char*) malloc(sb.st_size+1);
   
    memset(cur_ext, 0, sb.st_size+1);
    strncpy(cur_ext, buffer, sb.st_size);
    strcat(cur_ext, "\0");
    fprintf(stderr, "cur_Ext: %s", cur_ext);
    return cur_ext;
}
#endif

/* -- end cpdu.c functions -- */

  Immanuel Kant Prolegomena to Any Future Metaphysics   ...