/*  $Id: SFSobject.cpp 1.6 2002/03/23 18:19:33 Helios Exp $

    Sets object attributes of SmartFilesystem objects
    
    Now licensed under the GPL V2+!
*/

#include <dos/dos.h>
#include <dos/dosextens.h>
#include <utility/tagitem.h>
#include "fs/packets.h"
#include "fs/query.h"
#include "fs/objects.h"

#include <proto/dos.h>

const char *version_str = "\0$VER: SFSobject 1.5 (23.3.2002) (C) by Martin Steigerwald\r\n";

#define TEMPLATE "OBJECT/A,SHOW=UNHIDE/S,HIDE/S,DELETEABLE=DELABLE/S,UNDELETEABLE=UNDELABLE/S"

int main(void);

int main(void)
{
    int rc=RETURN_OK;
    struct RDArgs *rdargs=NULL;

    struct {
        char  *file;
        ULONG show;
        ULONG hide;
        ULONG delable;
        ULONG undelable;
    } args={NULL, 0, 0};

    rdargs = ReadArgs(TEMPLATE, (LONG *)&args, NULL);

    if (rdargs == NULL) {
        PrintFault(IoErr(), "SFSobject");
        exit(RETURN_ERROR);
    }
    else {
        BPTR  lock=NULL;


        // really change something?
        if (args.show!=0 || args.hide!=0 || args.delable!=0 || args.undelable!=0) {

            // checking mutually exclusive options
            if ((args.show!=0 && args.hide!=0) ||
                (args.delable!=0 && args.undelable!=0))
            {
                PutStr("Please make a clear decision. You chose mutually exclusive options.\n");
            }
            else {
                lock = Lock(args.file, SHARED_LOCK);
                if (lock) {
                    struct DevProc *devproc=NULL;

                    devproc = GetDeviceProc(args.file, NULL);
                    if (devproc) {
                        //struct TagItem tags[] =
                        //{
                        //    ASQ_HAS_RECYCLED, 0,
                        //    TAG_DONE
                        //};
                        struct MsgPort *port=devproc->dvp_Port;
                        LONG errorcode=0;
                        ULONG bits=0;
                        char name[1];
                        BSTR namebcpl=NULL;
                        // APTR rlock=NULL;

                        // quick SFS bug work around,
                        // SFS 1.81 throws a hit when a pass a NULL pointer
                        // to BSTR name argument in ACTION_SFS_SET_OBJECTBITS

                        name[0]=0;
                        namebcpl=MKBADDR(name);

                        if (args.hide) {
                            bits = bits | OTYPE_HIDDEN;
                        }


                        //checking code for .recycled-directory!

                        if ((((struct FileLock *)(BADDR(lock)))->fl_Key)==2 & (args.undelable==0)) {
                            PutStr("I could not allow you to set the recycled directory to deleteable!\n");
                            PutStr("Setting UNDELETEABLE option!\n");
                            args.undelable=1;
                        }

                        // above code saved me two dozen of lines, thanks to Jörg Strohmayer

                        // old recycled dir code that still does not work correctly
                          /*
                        errorcode = DoPkt(port, ACTION_SFS_QUERY, (LONG)&tags, 0, 0, 0, 0);
                        if (errorcode!=DOSFALSE) {
                            if (tags[0].ti_Data!=0) {
                                Printf("Has recycled!\n");
                                rlock = (APTR) DoPkt(port, ACTION_SFS_LOCATE_OBJECT, RECYCLEDNODE, SHARED_LOCK, 0, 0, 0);
                                if (rlock!=NULL) {
                                    BPTR rlockbtr=(BPTR) MKBADDR(rlock);

                                    Printf("Got lock on recycled!\n");

                                    if (SameLock(lock, rlockbtr)==LOCK_SAME) {
                                        Printf("Same lock\n");
                                        if (args.undelable==0) {
                                            Printf("I could not allow you to set .recycled to deleteable. Sorry!\n");
                                        }
                                        args.undelable=1
                                    }

                                    UnLock(rlockbtr);
                                }
                                else {
                                    Printf("This should not happen. Report to author!\n");
                                    PrintFault(IoErr(), "SFSobject");
                                }
                            }

                        } // has recycled?
                        else {
                            Printf("Could not query HAS_RECYCLED. No SFS volume?\n");
                            PrintFault(IoErr(), "SFSobject");
                        } // has recycled?

                            */

                        if (args.undelable) {
                            bits = bits | OTYPE_UNDELETABLE;
                        }

                        errorcode = DoPkt(port, ACTION_SFS_SET_OBJECTBITS, 0, lock, namebcpl, (LONG) bits, 0);
                        if (errorcode==DOSFALSE) {
                            PutStr("Could not set object attributes!\n");
                            PrintFault(IoErr(), "SFSobject");
                            rc=RETURN_ERROR;
                        }

                        FreeDeviceProc(devproc);
                    } // devproc
                    UnLock(lock);
                } // lock
                else {
                    PrintFault(IoErr(), "SFSobject");
                    rc=RETURN_ERROR;
                } // lock

            } // checking mutually exclusive options

        } // change something?

        FreeArgs(rdargs);
    } // ReadArgs

    exit(rc);
}

