/****************************************************************************

HDEnv 1.1 (20.8.95)
Copyright (C) 1995 by Michael Fedrowitz <mfedrowi@ix.urz.uni-heidelberg.de>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*****************************************************************************/


#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <stdlib.h>
#include <strings.h>
#include <dos.h>


#define VERSIONTAG "$VER: HDEnv 1.1 " __AMIGADATE__

#define ERR_BREAK 10001


const char *versiontag = VERSIONTAG;

extern long __oslibversion = 37;

long error_code = 0;


void __regargs _CXBRK(void) {

    error_code = ERR_BREAK;
}


void del_file(char *name) {

    char *path;
    BPTR l;

    if(path = AllocMem(256,MEMF_CLEAR)) {
        strmfp(path,"ENVARC:",name);
        if(!(l = Lock(path,ACCESS_READ)))
            Printf("Delete \"ENV:%s\" QUIET\n",name);
        else UnLock(l);
        FreeMem(path,256);
    }
    else error_code = ERROR_NO_FREE_STORE;
}

void del_dir(char *dir) {

    BOOL rc;
    BPTR l;
    long err;
    char *path;
    struct FileInfoBlock *fib;

    if(fib = AllocDosObject(DOS_FIB,NULL)) {
        if(path = AllocMem(256,MEMF_CLEAR)) {
            strmfp(path,"ENVARC:",dir);
            if(!(l = Lock(path,ACCESS_READ)))
                Printf("Delete \"ENV:%s\" ALL QUIET\n",dir);
            else {
                UnLock(l);
                if(l = Lock(dir,ACCESS_READ)) {
                    rc = Examine(l,fib);
                    if(rc) rc = ExNext(l,fib);
                    while(rc) {
                        strmfp(path,dir,fib->fib_FileName);
                        if(fib->fib_DirEntryType>0) del_dir(path);
                        else del_file(path);
                        chkabort();
                        if(error_code) break;
                        rc = ExNext(l,fib);
                    }
                    if(!error_code) {
                        err = IoErr();
                        if(err != ERROR_NO_MORE_ENTRIES) error_code = err;
                    }
                    UnLock(l);
                }
            }
            FreeMem(path,256);
        }
        else error_code = ERROR_NO_FREE_STORE;
        FreeDosObject(DOS_FIB,fib);
    }
    else error_code = ERROR_NO_FREE_STORE;
}


void copy_file(char *name,struct FileInfoBlock *src_fib) {

    BOOL copy=FALSE;
    char *path;
    BPTR l;
    struct FileInfoBlock *dest_fib;

    if(dest_fib = AllocDosObject(DOS_FIB,NULL)) {
        if(path = AllocMem(256,MEMF_CLEAR)) {
            strmfp(path,"ENV:",name);
            if(!(l = Lock(path,ACCESS_READ))) copy = TRUE;
            else {
                Examine(l,dest_fib);
                if(CompareDates(&src_fib->fib_Date,&dest_fib->fib_Date) != 0)
                    copy = TRUE;
                UnLock(l);
            }
            if(copy) Printf("Copy \"ENVARC:%s\" \"ENV:%s\" CLONE QUIET NOREQ\n",name,name);
            FreeMem(path,256);
        }
        else error_code = ERROR_NO_FREE_STORE;
        FreeDosObject(DOS_FIB,dest_fib);
    }
    else error_code = ERROR_NO_FREE_STORE;
}

void copy_dir(char *dir) {

    BOOL rc;
    BPTR l;
    long err;
    char *path;
    struct FileInfoBlock *fib;

    if(fib = AllocDosObject(DOS_FIB,NULL)) {
        if(path = AllocMem(256,MEMF_CLEAR)) {
            strmfp(path,"ENV:",dir);
            if(!(l = Lock(path,ACCESS_READ))) {
                Printf("MakeDir \"%s\"\n",path);
                Printf("Copy \"ENVARC:%s\" \"ENV:%s\" CLONE ALL QUIET NOREQ\n",dir,dir);
            }
            else {
                UnLock(l);
                if(l = Lock(dir,ACCESS_READ)) {
                    rc = Examine(l,fib);
                    if(rc) rc = ExNext(l,fib);
                    while(rc) {
                        strmfp(path,dir,fib->fib_FileName);
                        if(fib->fib_DirEntryType > 0) copy_dir(path);
                        else copy_file(path,fib);
                        chkabort();
                        if(error_code) break;
                        rc = ExNext(l,fib);
                    }
                    if(!error_code) {
                        err = IoErr();
                        if(err != ERROR_NO_MORE_ENTRIES) error_code = err;
                    }
                    UnLock(l);
                }
            }
            FreeMem(path,256);
        }
        else error_code = ERROR_NO_FREE_STORE;
        FreeDosObject(DOS_FIB,fib);
    }
    else error_code = ERROR_NO_FREE_STORE;
}


void main(void) {

    BPTR old,l;

    l = Lock("ENV:",ACCESS_READ);
    old = CurrentDir(l);
    del_dir("");
    UnLock(l);
    if(!error_code) {
        l = Lock("ENVARC:",ACCESS_READ);
        CurrentDir(l);
        copy_dir("");
        UnLock(l);
    }
    CurrentDir(old);
    if(error_code) {
        if(error_code != ERR_BREAK) {
            PrintFault(error_code,"HDEnv");
            exit(RETURN_WARN);
        }
        else PutStr("***Break\n");
    }
    exit(RETURN_OK);
}
