home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1990 Commodore-Amiga, Inc.
- * All rights reserved
- */
-
- /*
- * $Id: fn_handler.c,v 1.11 90/06/23 13:29:46 ewout Exp Locker: ewout $
- *
- */
-
- /*
- * Example handler for AppShell.
- *
- * Handler sets up a process and lets the application/user have a file polled
- * with a specified interval. Applictation is expected to supply the address
- * of a function, which will be called in case of a change in the file
- * status.
- *
- * Note that this is just an example handler with a lot of overhead for
- * file notification.
- *
- */
-
- #include <libraries/appshell.h>
- #include <dos/dostags.h>
- #include <dos/dosextens.h>
- #include <devices/timer.h>
- #include <string.h>
- #include "fn_handler.h"
- #include "fn_error.h"
-
- #include <clib/appshell_protos.h>
- #include <clib/alib_protos.h>
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
-
-
-
- /* I N T E R N A L F U N C T I O N P R O T O T Y P E S */
-
- void __saveds FileNotifier(void);
- struct TargetNode *FindTarget(struct MinList * list, UBYTE * name);
- struct TargetNode *AllocNodeMem(UBYTE * filename, struct PoolHeader * ph);
- void FreeNodeMem(struct TargetNode * node, struct PoolHeader * ph);
- struct Process *__stdargs CreateAProcess(ULONG firsttag,...);
-
- struct MsgHandler *setup_fnA(struct AppInfo *, struct TagItem *);
- BOOL open_fn(struct AppInfo *, struct MsgHandler *, struct TagItem *);
- BOOL handle_fn(struct AppInfo *, struct MsgHandler *, struct TagItem *);
- BOOL close_fn(struct AppInfo *, struct MsgHandler *, struct TagItem *);
- BOOL shutdown_fn(struct AppInfo *, struct MsgHandler *, struct TagItem *);
- void FileNotifyA(struct AppInfo *, STRPTR, struct TagItem *);
-
- /* The message structure passed to the process to exchange
- * port addresses.
- */
- struct StartUpMessage {
- struct Message su_Msg;
- struct MsgPort *su_Port;
- LONG su_Error;
- };
-
- /* node for the hitlist maintained by the process */
- struct TargetNode {
- struct MinNode tnm_Node;
- struct timerequest *fntr;
- struct SIPCMessage *ntfymsg;
- struct FNData *fndata;
- LONG FileSize;
- struct DateStamp datestamp;
- };
-
- #define FNotifyID APSH_FN_ID+1
- #define FN_NOTIFICATION APSH_FN_ID+2
-
- #define FN_SHUTDOWN 5
-
- /* Function address for NOTIFICATION will be supplied in setup_fnA */
- struct Funcs fn_funcs[] =
- {
- {"NOTIFY", FileNotifyA, FNotifyID,},
- {"NOTIFICATION", 0L, FN_NOTIFICATION, NULL, NULL, APSH_FF_PRIVATE,},
- {NULL, NO_FUNCTION,}
- };
-
-
- struct MsgHandler *
- setup_fnA(struct AppInfo * ai, struct TagItem * tl)
- {
- struct MsgHandler *mh;
- struct MHObject *mho;
- struct FNInfo *fni;
- struct Process *mp;
- struct MsgPort *port;
- struct StartUpMessage *sumsg;
- ULONG hstatus;
- BOOL FAILED = TRUE;
-
- ai->ai_TextRtn = NULL;
-
- /* Allocate all we need to get going */
-
- /* Get some memory */
- if (mh = (struct MsgHandler *)
- AllocVec(sizeof(struct MsgHandler) +
- sizeof(struct FNInfo) +
- sizeof(struct SIPCMessage) +
- sizeof(struct FNData) +
- sizeof(ULONG) * 4, MEMF_CLEAR | MEMF_PUBLIC)) {
- mho = &(mh->mh_Header);
- /* It's a handler so the Type is handler type and the
- * priority handler priority.
- */
- mho->mho_Node.ln_Type = MH_HANDLER_T;
- mho->mho_Node.ln_Pri = MH_HANDLER_P;
- /* Give the handler a name */
- mho->mho_Node.ln_Name = "FN";
- NewList(&(mho->mho_ObjList));
- /* Give the handler an ID */
- mho->mho_ID = APSH_FN_ID;
- /* Inititally the handler is closed and disabled */
- mho->mho_Status = (MHS_ENABLED | MHS_CLOSE);
- mho->mho_SysData = fni = MEMORY_FOLLOWING(mh);
- fni->fni_sipcmsg = MEMORY_FOLLOWING(fni);
- fni->fni_fndata = MEMORY_FOLLOWING(fni->fni_sipcmsg);
- mh->mh_NumFuncs = 4;
- mh->mh_Func = MEMORY_FOLLOWING(fni->fni_fndata);
- if (fni->fni_clientport = CreatePort(0, 0)) {
- if (fni->fni_replyport = CreatePort(0, 0)) {
- /* Fire up process */
- if (mp = (struct Process *)
- CreateAProcess(NP_Entry, FileNotifier,
- NP_Name, "File Notify",
- NP_StackSize, 8000,
- NP_Priority, 5,
- TAG_END)) {
- sumsg = AllocVec(sizeof(struct StartUpMessage), MEMF_CLEAR);
- sumsg->su_Msg.mn_Node.ln_Type = NT_MESSAGE;
- sumsg->su_Msg.mn_Length = sizeof(struct StartUpMessage);
- sumsg->su_Msg.mn_ReplyPort = fni->fni_replyport;
- sumsg->su_Port = fni->fni_clientport;
- port = &(mp->pr_MsgPort);
- PutMsg((struct MsgPort *) port, (struct Message *) sumsg);
- WaitPort(fni->fni_replyport);
- while (GetMsg(fni->fni_replyport));
- if (sumsg->su_Error == RETURN_OK) {
- FAILED = FALSE;
- fni->fni_fnport = sumsg->su_Port;
- }
- FreeVec(sumsg);
- }
- }
- }
- }
- /* Hmmm. Oh well. */
- if (FAILED) {
- if (mh) {
- if (fni->fni_clientport) {
- if (fni->fni_replyport)
- DeletePort(fni->fni_replyport);
- DeletePort(fni->fni_clientport);
- }
- FreeVec(mh);
- mh = NULL;
- }
- ai->ai_Pri_Ret = RETURN_FAIL;
- ai->ai_Sec_Ret = APSH_CLDNT_INIT_MSGH;
- ai->ai_TextRtn = PrepText(ai, APSH_MAIN_ID, ai->ai_Sec_Ret, "File Notification");
- } else {
- hstatus = GetTagData(APSH_Status, NULL, tl);
- /* Declare the handler active if so defined in initialisation */
- if (hstatus & P_ACTIVE)
- open_fn(ai, mh, tl);
-
- /* Store the address of the basic handlers functions in the
- * message handler structure.
- */
- mh->mh_Func[MH_OPEN] = open_fn;
- mh->mh_Func[MH_HANDLE] = handle_fn;
- mh->mh_Func[MH_CLOSE] = close_fn;
- mh->mh_Func[MH_SHUTDOWN] = shutdown_fn;
- mh->mh_SigBits = (1L << fni->fni_clientport->mp_SigBit);
- mh->mh_DefText = FN_ErrorMsgs;
- /*
- * Get address of appliction function to call, use donothing
- * (StubFunc()) if not supplied
- */
- fn_funcs[1].fe_Func = (VOID *) GetTagData(APSH_CmdData, (ULONG) StubFunc, tl);
- AddFuncEntries(ai, fn_funcs);
- }
- return (mh);
- }
-
-
- /* Enable handler */
- BOOL
- open_fn(struct AppInfo * ai, struct MsgHandler * mh, struct TagItem * tl)
- {
- struct MHObject *mho = &(mh->mh_Header);
-
- mho->mho_Status &= ~MHS_CLOSE;
- mho->mho_Status |= MHS_OPEN;
-
- return (TRUE);
- }
-
- /* Disable handler */
- BOOL
- close_fn(struct AppInfo * ai, struct MsgHandler * mh, struct TagItem * tl)
- {
- struct MHObject *mho = &(mh->mh_Header);
-
- mho->mho_Status &= ~MHS_OPEN;
- mho->mho_Status |= MHS_CLOSE;
-
- return (TRUE);
- }
-
- /* Handle incoming messages */
- BOOL
- handle_fn(struct AppInfo * ai, struct MsgHandler * mh, struct TagItem * tl)
- {
- struct MHObject *mho = &(mh->mh_Header);
- struct FNInfo *fni = (struct FNInfo *) mho->mho_SysData;
- struct MsgPort *ClientPort = fni->fni_clientport;
- struct SIPCMessage *sipcmsg;
- struct FNData *fwd_fndata;
- struct TagItem tg[3];
- ULONG FuncID;
-
- while (sipcmsg = (struct SIPCMessage *) GetMsg(ClientPort)) {
- FuncID = sipcmsg->sipc_Type;
-
- if ((FuncID != NO_FUNCTION) && (mho->mho_Status & MHS_OPEN) && (mho->mho_Status & MHS_ENABLED)) {
- fwd_fndata = fni->fni_fndata;
- CopyMem(sipcmsg->sipc_Data, fwd_fndata, sizeof(struct FNData));
-
- /* Make fn taglist, pass tl for consistency */
- tg[0].ti_Tag = APSH_CmdData;
- tg[0].ti_Data = (ULONG) fwd_fndata;
- tg[1].ti_Tag = APSH_CmdDataLength;
- tg[1].ti_Data = sizeof(struct FNData);
- tg[2].ti_Tag = TAG_MORE;
- tg[2].ti_Data = (ULONG) tl;
-
- /* Call the function */
- PerfFunc(ai, FuncID, NULL, tg);
- }
- ReplyMsg((struct Message *) sipcmsg);
- }
- return (TRUE);
- }
-
- /* Shutdown process, free all allocations */
- BOOL
- shutdown_fn(struct AppInfo * ai, struct MsgHandler * mh, struct TagItem * tl)
- {
- struct MHObject *mho;
- struct FNInfo *fni;
- struct SIPCMessage *sipcmsg;
-
- if (mh) {
- mho = &(mh->mh_Header);
- fni = mho->mho_SysData;
-
- /* Inform the process it's time to leave. */
- sipcmsg = fni->fni_sipcmsg;
- sipcmsg->sipc_Msg.mn_Node.ln_Type = NT_MESSAGE;
- sipcmsg->sipc_Msg.mn_Length = sizeof(struct SIPCMessage);
- sipcmsg->sipc_Msg.mn_ReplyPort = fni->fni_replyport;
- sipcmsg->sipc_Type = FN_SHUTDOWN;
- PutMsg((struct MsgPort *) fni->fni_fnport, (struct Message *) sipcmsg);
-
- WaitPort((struct MsgPort *) (fni->fni_replyport));
- while (GetMsg(fni->fni_replyport));
-
- DeletePort(fni->fni_replyport);
- DeletePort(fni->fni_clientport);
- Remove((struct Node *) mh);
- FreeVec(mh);
- }
- return (TRUE);
- }
-
-
- /****** fn_handler/NOTIFY *********************************************
- *
- * NAME
- * NOTIFY - Send a command to the fn_handler
- *
- * SYNOPSIS
- * FNotifyID <Command> <FILE=filename> [INT=interval]
- * [RET=retries] [FLAGS=flags]
- *
- * FUNCTION
- * Allows command line commands to be directly send to the handler.
- *
- * Accepted commands: ADD, DEL, SYNC.
- * See fn_handler.h for valid flags.
- * If optional arguments are ommited, interval defaults to 60,
- * retries to -1, flags to FN_NEWER.
- *
- * EXAMPLE
- *
- * NOTIFY ADD FILE=topcat:mbox INT=20 RET=-1 FLAGS=FN_NEWER|FN_MUSTEXIST
- *
- *
- * SEE ALSO
- * FileNotify() / fn_handler.h
- *
- ***********************************************************************
- */
-
- VOID
- FileNotifyA(struct AppInfo * ai, STRPTR str, struct TagItem * tl)
- {
- struct MsgHandler *mh;
- struct MHObject *mho;
- struct FNInfo *fni;
- struct TagItem *fti;
- struct SIPCMessage *sipcmsg;
- struct FNData *fndata;
- struct FNData *userbuffer = NULL;
- STRPTR argv[MAXARG];
- ULONG argc;
- STRPTR parsedline;
- STRPTR tmpptr;
- BOOL *usererror = NULL;
-
- if (mh = HandlerData(ai, APSH_Handler, "FN", TAG_DONE)) {
- mho = &(mh->mh_Header);
- fni = mho->mho_SysData;
- sipcmsg = fni->fni_sipcmsg;
- fndata = fni->fni_fndata;
- fndata->fnd_Flags = 0;
-
- parsedline = BuildParseLine(str, &argc, argv);
-
- /* Always gets at least the function nameid string passed */
- if (argc >= 2) {
- if (QStrCmpI(argv[1], "ADD"))
- sipcmsg->sipc_Type = FN_ADDTARGET;
- else if (QStrCmpI(argv[1], "DEL"))
- sipcmsg->sipc_Type = FN_DELTARGET;
- else if (QStrCmpI(argv[1], "SYNC"))
- sipcmsg->sipc_Type = FN_SYNC;
- else
- sipcmsg->sipc_Type = 0;
-
- if (sipcmsg->sipc_Type != 0) {
- tmpptr = FindType(argv, "INT", "60");
- stcd_l(tmpptr, &(fndata->fnd_Interval));
- tmpptr = FindType(argv, "RET", "-1");
- stcd_l(tmpptr, &(fndata->fnd_Retries));
- fndata->fnd_Filename = FindType(argv, "FILE", NULL);
- tmpptr = FindType(argv, "FLAGS", "FN_NEWER");
- if (MatchValue(tmpptr, "FN_MUSTEXIST"))
- fndata->fnd_Flags |= FN_MUSTEXIST;
- if (MatchValue(tmpptr, "FN_CREATED"))
- fndata->fnd_Flags |= FN_CREATED;
- if (MatchValue(tmpptr, "FN_SMALLER"))
- fndata->fnd_Flags |= FN_SMALLER;
- if (MatchValue(tmpptr, "FN_BIGGER"))
- fndata->fnd_Flags |= FN_BIGGER;
- if (MatchValue(tmpptr, "FN_NEWER"))
- fndata->fnd_Flags |= FN_NEWER;
- }
- } else {
- /* No commandline or arexx arguments, check for tags. */
- userbuffer = (struct FNData *) GetTagData(FN_Buffer, NULL, tl);
- fndata->fnd_Retries = (LONG) GetTagData(FN_Retries, -1, tl);
- fndata->fnd_Interval = (LONG) GetTagData(FN_Interval, 60, tl);
- fndata->fnd_Flags = (ULONG) GetTagData(FN_Flags, FN_NEWER, tl);
- fndata->fnd_Filename = (UBYTE *) GetTagData(FN_Filename, NULL, tl);
- sipcmsg->sipc_Type = (LONG) GetTagData(FN_Command, 0L, tl);
- usererror = (BOOL *) GetTagData(FN_Error, NULL, tl);
-
- /*
- * Removes all tags. Individual flags can be set and override
- * FN_Flags tag.
- */
-
- do {
- fti = NextTagItem(&tl);
- if (fti) {
- switch (fti->ti_Tag) {
- case FN_MustExist:
- if ((BOOL) fti->ti_Data)
- fndata->fnd_Flags |= FN_MUSTEXIST;
- else
- fndata->fnd_Flags ^= FN_MUSTEXIST;
- break;
- case FN_Created:
- if ((BOOL) fti->ti_Data)
- fndata->fnd_Flags |= FN_CREATED;
- else
- fndata->fnd_Flags ^= FN_CREATED;
- break;
- case FN_Deleted:
- if ((BOOL) fti->ti_Data)
- fndata->fnd_Flags |= FN_DELETED;
- else
- fndata->fnd_Flags ^= FN_DELETED;
- break;
- case FN_Smaller:
- if ((BOOL) fti->ti_Data)
- fndata->fnd_Flags |= FN_SMALLER;
- else
- fndata->fnd_Flags ^= FN_SMALLER;
- break;
- case FN_Bigger:
- if ((BOOL) fti->ti_Data)
- fndata->fnd_Flags |= FN_BIGGER;
- else
- fndata->fnd_Flags ^= FN_BIGGER;
- break;
- case FN_Newer:
- if ((BOOL) fti->ti_Data)
- fndata->fnd_Flags |= FN_NEWER;
- else
- fndata->fnd_Flags ^= FN_NEWER;
- break;
- }
- }
- } while (fti != TAG_DONE);
- }
-
- ai->ai_Pri_Ret = RETURN_WARN;
- ai->ai_Sec_Ret = RETURN_OK;
-
- /* If arguments were passed, either string or tags, we have
- * them now. Check if they are valid.
- */
- if (sipcmsg->sipc_Type > 0 && sipcmsg->sipc_Type < 5) {
- if (strlen(fndata->fnd_Filename) != 0) {
- if (!(sipcmsg->sipc_Type == FN_ADDTARGET && (fndata->fnd_Flags & FN_ALLFLAGS) == 0)) {
- /* Seems we got a valid set of arguments.
- * Make a message and send to the notify process.
- */
- sipcmsg->sipc_Msg.mn_Node.ln_Type = NT_MESSAGE;
- sipcmsg->sipc_Msg.mn_Length = sizeof(struct SIPCMessage);
- sipcmsg->sipc_Msg.mn_ReplyPort = fni->fni_replyport;
- /* Pass it a pointer to the relevant data */
- sipcmsg->sipc_Data = (APTR) fndata;
- PutMsg((struct MsgPort *) fni->fni_fnport, (struct Message *) sipcmsg);
- WaitPort((struct MsgPort *) fni->fni_replyport);
- while (GetMsg(fni->fni_replyport));
-
- /* Copy the return values from the notify process,
- * the dispatcher will deal with them.
- */
- ai->ai_Pri_Ret = sipcmsg->sipc_Pri_Ret;
- ai->ai_Sec_Ret = sipcmsg->sipc_Sec_Ret;
- ai->ai_TextRtn = FN_ErrorMsgs[sipcmsg->sipc_Sec_Ret];
-
- if (ai->ai_Pri_Ret == RETURN_OK) {
- /*
- * If desired, return arguments in application
- * supplied buffer
- */
- if (userbuffer) {
- CopyMem(sipcmsg->sipc_Data, userbuffer, sizeof(struct FNData));
- /* Give back own ptr to targetname, not ours */
- userbuffer->fnd_Filename = fndata->fnd_Filename;
- }
- }
- } else { /* No flags were set */
- ai->ai_Sec_Ret = FN_FLAGS_ERR;
- ai->ai_TextRtn = PrepText(ai, APSH_FN_ID, ai->ai_Sec_Ret, NULL);
- }
- } else { /* No targetname was given */
- ai->ai_Sec_Ret = FN_FILENAME_ERR;
- ai->ai_TextRtn = PrepText(ai, APSH_FN_ID, ai->ai_Sec_Ret, NULL);
- }
- } else { /* No handler command found */
- ai->ai_Sec_Ret = FN_COMMAND_ERR;
- ai->ai_TextRtn = ai->ai_TextRtn = PrepText(ai, APSH_FN_ID, ai->ai_Sec_Ret, NULL);
- }
- if (str)
- FreeParseLine(parsedline);
- } else { /* The handler data could not be found */
- ai->ai_Pri_Ret = RETURN_FAIL;
- ai->ai_Sec_Ret = FN_HANDLER_ERR;
- ai->ai_TextRtn = PrepText(ai, APSH_FN_ID, ai->ai_Sec_Ret, NULL);
- }
- if (usererror) /* Return the error to the appliction, if desired */
- *usererror = ai->ai_Pri_Ret;
- }
-
- /* The notify process */
- void __saveds
- FileNotifier(void)
- {
- struct PoolHeader *ph;
-
- struct MsgPort *fnport;
- struct MsgPort *clientport;
- struct MsgPort *timerport;
- struct MsgPort *dosport;
-
- struct timerequest *tr;
- struct SIPCMessage *msg;
- struct SIPCMessage *finalmsg;
- struct StartUpMessage *startupmsg;
- struct Message *timermsg;
-
- struct FNData *fndata;
-
- struct MinList *hitlist;
- struct TargetNode *tnode, *wnode, *nnode;
- struct FileInfoBlock *fib;
- LONG lock;
- BOOL ABORT = FALSE;
- long pri_error, sec_error, result;
- BOOL FAILED = TRUE;
- ULONG client_sig, timer_sig, signal;
-
- /* Chi sono? */
- dosport = &(((struct Process *) FindTask(NULL))->pr_MsgPort);
- WaitPort(dosport);
- startupmsg = (struct StartUpMessage *) GetMsg(dosport);
-
- if (fnport = (struct MsgPort *) CreatePort(0, 0)) {
- if (timerport = (struct MsgPort *) CreatePort(0, 0)) {
- if (ph = (struct PoolHeader *) CreatePrivatePool(MEMF_CLEAR | MEMF_PUBLIC, 4096, 0)) {
- fib = (struct FileInfoBlock *) AllocPooled(sizeof(struct FileInfoBlock), ph);
- tr = (struct timerequest *) AllocPooled(sizeof(struct timerequest), ph);
- hitlist = (struct MinList *) AllocPooled(sizeof(struct MinList), ph);
- NewList((struct List *) hitlist);
- if (!(OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest *) tr, 0))) {
-
- /* Get client port address & return my port */
- clientport = (struct MsgPort *) startupmsg->su_Port;
- startupmsg->su_Error = 0L;
- startupmsg->su_Port = fnport;
- ReplyMsg((struct Message *) startupmsg);
- FAILED = FALSE;
- client_sig = 1L << fnport->mp_SigBit;
- timer_sig = 1L << timerport->mp_SigBit;
-
- for (;;) {
- signal = Wait(client_sig | timer_sig);
-
- /* C L I E N T S I G N A L */
-
- if (signal & client_sig) {
- while (msg = (struct SIPCMessage *) GetMsg(fnport)) {
- fndata = (struct FNData *) msg->sipc_Data;
- /* Start out being OK */
- msg->sipc_Pri_Ret = RETURN_OK;
- msg->sipc_Sec_Ret = RETURN_OK;
-
- switch (msg->sipc_Type) {
-
- case FN_ADDTARGET:
-
- /*
- * Don't allow duplicate targetfiles no
- * more
- */
- if (tnode = FindTarget(hitlist, fndata->fnd_Filename)) {
- msg->sipc_Pri_Ret = RETURN_WARN;
- msg->sipc_Sec_Ret = FN_HASNOTIFICATION_ERR;
- } else {
- lock = Lock(fndata->fnd_Filename, ACCESS_READ);
- if (lock == NULL) { /* File doesn't exist */
- if (fndata->fnd_Flags & FN_MUSTEXIST) {
- msg->sipc_Pri_Ret = RETURN_WARN;
- msg->sipc_Sec_Ret = FN_DOESNOTEXIST_ERR;
- } else
- fib->fib_Size = 0;
- } else {
- /* this is more serious */
- if (!(Examine(lock, fib))) {
- msg->sipc_Pri_Ret = RETURN_ERROR;
- msg->sipc_Sec_Ret = FN_READ_ERR;
- } else {
- if (fib->fib_DirEntryType > 0) {
- msg->sipc_Pri_Ret = RETURN_WARN;
- msg->sipc_Sec_Ret = FN_NOTFILE_ERR;
- }
- UnLock(lock);
- }
- }
- }
- if (msg->sipc_Pri_Ret == RETURN_OK) {
- if (tnode = AllocNodeMem(fndata->fnd_Filename, ph)) {
- *(tnode->fntr) = *tr;
- tnode->fntr->tr_node.io_Command = TR_ADDREQUEST;
- tnode->fntr->tr_node.io_Message.mn_ReplyPort = timerport;
- tnode->fntr->tr_node.io_Message.mn_Node.ln_Pri = 0;
- tnode->fntr->tr_node.io_Message.mn_Node.ln_Name = NULL;
- tnode->ntfymsg = NULL;
- strcpy(tnode->fndata->fnd_Filename, fndata->fnd_Filename);
- tnode->fndata->fnd_Interval = fndata->fnd_Interval;
- tnode->fndata->fnd_Retries = fndata->fnd_Retries;
- tnode->fndata->fnd_Flags = fndata->fnd_Flags;
- tnode->FileSize = fib->fib_Size;
- if (tnode->FileSize != 0)
- CopyMem(&(fib->fib_Date), &(tnode->datestamp), sizeof(struct DateStamp));
- AddTail((struct List *) hitlist, (struct Node *) tnode);
- tnode->fntr->tr_time.tv_secs = tnode->fndata->fnd_Interval;
- tnode->fntr->tr_time.tv_micro = 0;
- SendIO((struct IORequest *) tnode->fntr);
- } else {
- msg->sipc_Pri_Ret = RETURN_ERROR;
- msg->sipc_Sec_Ret = FN_NOMEM_ERR;
- }
- }
- break;
-
- case FN_DELTARGET:
- if (tnode = (struct TargetNode *) FindTarget(hitlist, fndata->fnd_Filename)) {
- if (!(CheckIO((struct IORequest *) tnode->fntr))) {
- AbortIO((struct IORequest *) tnode->fntr);
- WaitIO((struct IORequest *) tnode->fntr);
- }
- FreeNodeMem(tnode, ph);
- msg->sipc_Pri_Ret = 0;
- } else {
- msg->sipc_Pri_Ret = RETURN_WARN;
- msg->sipc_Sec_Ret = FN_UNKNOWN_ERR;
- }
- break;
-
- case FN_INQUIRY:
- if (tnode = (struct TargetNode *) FindTarget(hitlist, fndata->fnd_Filename)) {
- msg->sipc_Data = tnode->fndata;
- } else {
- msg->sipc_Pri_Ret = RETURN_WARN;
- msg->sipc_Sec_Ret = FN_UNKNOWN_ERR;
- }
- break;
-
- case FN_SHUTDOWN:
- wnode = (struct TargetNode *) hitlist->mlh_Head;
- while (nnode = (struct TargetNode *) (wnode->tnm_Node.mln_Succ)) {
- if (!(CheckIO((struct IORequest *) wnode->fntr))) {
- AbortIO((struct IORequest *) wnode->fntr);
- WaitIO((struct IORequest *) wnode->fntr);
- }
- FreeNodeMem(wnode, ph);
- wnode = nnode;
- }
- ABORT = TRUE;
- finalmsg = msg;
- break;
-
- case FN_SYNC:
- if (tnode = (struct TargetNode *) FindTarget(hitlist, fndata->fnd_Filename)) {
- if (!(CheckIO((struct IORequest *) tnode->fntr))) {
- AbortIO((struct IORequest *) tnode->fntr);
- WaitIO((struct IORequest *) tnode->fntr);
- }
- tnode->fntr->tr_time.tv_secs = 0;
- tnode->fntr->tr_time.tv_micro = 0;
- SendIO((struct IORequest *) tnode->fntr);
- } else {
- msg->sipc_Pri_Ret = RETURN_WARN;
- msg->sipc_Sec_Ret = FN_UNKNOWN_ERR;
- }
- break;
-
- case FN_NOTIFICATION:
- /* Meglio tardi che mai! */
- if (tnode = (struct TargetNode *) FindTarget(hitlist, fndata->fnd_Filename)) {
- if (fndata->fnd_Status & FN_DONE) {
- FreeNodeMem(tnode, ph);
- } else {
- if (lock = Lock(tnode->fndata->fnd_Filename, ACCESS_READ)) {
- if (Examine(lock, fib)) {
- tnode->FileSize = fib->fib_Size;
- }
- UnLock(lock);
- }
- tnode->fntr->tr_time.tv_secs = tnode->fndata->fnd_Interval;
- tnode->fntr->tr_time.tv_micro = 0;
- SendIO((struct IORequest *) tnode->fntr);
- }
- }
- break;
- }
- if (msg->sipc_Msg.mn_Node.ln_Type != NT_REPLYMSG && ABORT == FALSE)
- ReplyMsg((struct Message *) msg);
- }
- }
- /* T I M E R S I G N A L */
-
- if (signal & timer_sig) {
- while (timermsg = (struct Message *) GetMsg(timerport)) {
- for (tnode = (struct TargetNode *) hitlist->mlh_Head; tnode->tnm_Node.mln_Succ; tnode = (struct TargetNode *) tnode->tnm_Node.mln_Succ) {
- if (tnode->fntr == (struct timerequest *) timermsg) {
- break;
- }
- }
- if (tnode->fntr == (struct timerequest *) timermsg) {
- pri_error = sec_error = RETURN_OK;
- result = fib->fib_Size = 0;
- if (tnode->fndata->fnd_Retries > 0)
- tnode->fndata->fnd_Retries--;
- if (tnode->fndata->fnd_Retries == 0)
- result |= FN_DONE;
- if (lock = Lock(tnode->fndata->fnd_Filename, ACCESS_READ)) {
- if (!(Examine(lock, fib))) {
- pri_error = RETURN_ERROR;
- sec_error = FN_READ_ERR;
- }
- UnLock(lock);
- }
- if (pri_error == RETURN_OK) {
- if (!(lock)) {
- if (tnode->fndata->fnd_Flags & FN_DELETED && tnode->FileSize > 0)
- result |= FN_DELETED;
- if (tnode->fndata->fnd_Flags & FN_SMALLER && tnode->FileSize > 0)
- result |= FN_SMALLER;
- } else {
- if (tnode->fndata->fnd_Flags & FN_CREATED && tnode->FileSize == 0)
- result |= FN_CREATED;
- if (tnode->fndata->fnd_Flags & FN_NEWER && tnode->FileSize == 0)
- result |= FN_NEWER;
- if (tnode->fndata->fnd_Flags & FN_SMALLER && fib->fib_Size < tnode->FileSize)
- result |= FN_SMALLER;
- if (tnode->fndata->fnd_Flags & FN_BIGGER && fib->fib_Size > tnode->FileSize)
- result |= FN_BIGGER;
- if (tnode->fndata->fnd_Flags & FN_NEWER && tnode->FileSize != 0) {
- if (CompareDates(&(tnode->datestamp), &(fib->fib_Date)))
- result |= FN_NEWER;
- }
- }
-
- tnode->FileSize = fib->fib_Size;
-
- if (result != 0 || pri_error != RETURN_OK) {
- /* OK, it's a go. */
- tnode->fndata->fnd_Status = result;
- tnode->ntfymsg = (struct SIPCMessage *) AllocPooled(sizeof(struct SIPCMessage), ph);
- if (tnode->FileSize != 0)
- CopyMem(&(fib->fib_Date), &(tnode->datestamp), sizeof(struct DateStamp));
- tnode->ntfymsg->sipc_Msg.mn_Node.ln_Type = NT_MESSAGE;
- tnode->ntfymsg->sipc_Msg.mn_Length = sizeof(struct SIPCMessage);
- tnode->ntfymsg->sipc_Msg.mn_ReplyPort = fnport;
- tnode->ntfymsg->sipc_Type = FN_NOTIFICATION;
- tnode->ntfymsg->sipc_Data = tnode->fndata;
- tnode->ntfymsg->sipc_DSize = sizeof(struct FNData) + strlen(tnode->fndata->fnd_Filename) + 1;
- tnode->ntfymsg->sipc_Pri_Ret = pri_error;
- tnode->ntfymsg->sipc_Sec_Ret = sec_error;
- PutMsg((struct MsgPort *) clientport, (struct Message *) tnode->ntfymsg);
- } else {
- tnode->fntr->tr_time.tv_secs = tnode->fndata->fnd_Interval;
- tnode->fntr->tr_time.tv_micro = 0;
- SendIO((struct IORequest *) tnode->fntr);
- }
- }
- }
- }
- }
- if (ABORT)
- break;
- }
- CloseDevice((struct IORequest *) tr);
- }
- FreePooled(hitlist, ph);
- FreePooled(tr, ph);
- FreePooled(fib, ph);
-
- DeletePrivatePool(ph);
- }
- DeletePort(timerport);
- }
- DeletePort(fnport);
- }
- Forbid();
-
- if (FAILED) {
- startupmsg->su_Error = RETURN_FAIL;
- startupmsg->su_Port = NULL;
- ReplyMsg((struct Message *) startupmsg);
- } else {
- ReplyMsg((struct Message *) finalmsg);
- }
- }
-
-
- struct TargetNode *
- FindTarget(struct MinList * list, UBYTE * name)
- {
- struct TargetNode *node;
-
- for (node = (struct TargetNode *) list->mlh_Head; node->tnm_Node.mln_Succ; node = (struct TargetNode *) node->tnm_Node.mln_Succ) {
- if (strcmp(name, node->fndata->fnd_Filename) == 0)
- return (node);
- }
- return (NULL);
- }
-
-
- struct TargetNode *
- AllocNodeMem(UBYTE * filename, struct PoolHeader * ph)
- {
- struct TargetNode *node;
-
- if (node = (struct TargetNode *) AllocPooled(sizeof(struct TargetNode), ph)) {
- if (node->fntr = (struct timerequest *) AllocPooled(sizeof(struct timerequest), ph)) {
- if (node->fndata = (struct FNData *) AllocPooled(sizeof(struct FNData), ph)) {
- if (!(node->fndata->fnd_Filename = (UBYTE *) AllocPooled(strlen(filename) + 1, ph))) {
- FreePooled(node->fndata, ph);
- FreePooled(node->fntr, ph);
- FreePooled(node, ph);
- node = NULL;
- }
- } else {
- FreePooled(node->fntr, ph);
- FreePooled(node, ph);
- node = NULL;
- }
- } else {
- FreePooled(node, ph);
- node = NULL;
- }
- }
- return (node);
- }
-
-
- void
- FreeNodeMem(struct TargetNode * node, struct PoolHeader * ph)
- {
- FreePooled(node->fndata->fnd_Filename, ph);
- FreePooled(node->fndata, ph);
- FreePooled(node->fntr, ph);
- if (node->ntfymsg) {
- FreePooled(node->ntfymsg, ph);
- }
- Remove((struct Node *) node);
- FreePooled(node, ph);
- }
-
-
-
- /* stack to tag */
-
- struct MsgHandler *
- setup_fn(struct AppInfo * ai, ULONG tags,...)
- {
- return (setup_fnA(ai, (struct TagItem *) & tags));
- }
-
- /****** fn_handler/FileNotify *****************************************
- *
- * NAME
- * FileNotify - Send command to fn_handler
- *
- * SYNOPSIS
- * FileNotify(struct AppInfo * ai, STRPTR str, ULONG tags,...)
- *
- * struct AppInfo *ai;
- * STRPTR str;
- * ULONG tags,...
- *
- * FUNCTION
- * This function lets the application send commands to the fn_handler.
- *
- * EXAMPLE
- * FileNotify(ai, NULL,
- * FN_Command, FN_INQUIRY,
- * FN_Filename, "dh0:testfile"
- * FN_Error, &error,
- * FN_Buffer, fndata,
- * TAG_DONE);
- *
- * INPUTS
- * ai - pointer to the AppInfo structure for this application.
- * str - pointer to a command line like string or NULL
- * tags - stack based TagItems.
- *
- *
- * RESULT
- * Error values are returned in ai->Pri_Err and ai->Sec_Err.
- * If requested, the primary error value is returned in an
- * application supplied BOOL variable.
- * If requested, the data as used by the fn_handler is returned
- * in an application supplied FNData structure.
- *
- * SEE ALSO
- * NOTIFY / fn_handler.h
- *
- ***********************************************************************
- */
-
- VOID
- FileNotify(struct AppInfo * ai, STRPTR str, ULONG tags,...)
- {
- PerfFunc(ai, FNotifyID, str, (struct TagItem *) & tags);
- }
-
- struct Process *__stdargs
- CreateAProcess(ULONG firsttag,...)
- {
- return (CreateNewProc((struct TagItem *) & firsttag));
- }
-