home *** CD-ROM | disk | FTP | other *** search
- /* do_req.c
- *
- * Manage the requester window for PIV.
- *
- * (c) Copyright 1991 J.E.Hanway
- *
- * $Id: do_req.c,v 1.1 91/03/13 22:32:41 jeh Exp $
- *
- * $Log: do_req.c,v $
- * Revision 1.1 91/03/13 22:32:41 jeh
- * Initial revision
- *
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <intuition/intuition.h>
- #include <proto/exec.h>
- #include <proto/intuition.h>
- #include <proto/dos.h>
- #include <string.h>
- #include <stdarg.h>
-
- #include "PIV.h"
-
- /* Semaphore that is held whenever the code is in use
- */
- struct SignalSemaphore inuse_sema;
-
- /* use count
- */
- struct SignalSemaphore usecount_sema;
- long usecount = 0;
-
- /* keep track of the previous operation for the "cancel once" feature
- */
- static struct SignalSemaphore rc_sema;
- static char lastvol[40] = "";
- static long lastrc = -1L;
-
- void
- init_semaphores(void)
- {
- InitSemaphore(&inuse_sema);
- InitSemaphore(&usecount_sema);
- InitSemaphore(&rc_sema);
- }
-
- static void
- free_context(context_t *ct)
- {
- FreeMem(ct, sizeof(context_t));
- }
-
- static context_t *
- get_context(void)
- {
- int i;
-
- context_t *ct = AllocMem(sizeof(context_t), MEMF_CLEAR);
-
- if(ct) {
- for(i = 0; i < 6; i++) {
- ct->g[i] = *gproto[i];
- ct->g[i].NextGadget = &ct->g[i+1];
- }
- ct->g[4].SpecialInfo = (APTR) &ct->si;
- ct->g[5].GadgetText = &ct->it;
- ct->g[5].NextGadget = NULL;
- ct->si.Buffer = ct->strbuf;
- ct->si.MaxChars = 80;
- ct->nw = nw_proto;
- ct->nw.FirstGadget = &ct->g[0];
- ct->it = *vol_text;
- ct->it.IText = ct->line;
- }
-
- return ct;
- }
-
- /* cat() concatenates strings together and avoids linking in a large
- * implementation of sprintf.
- *
- * Usage: cat(s1, s2, s3, ..., NULL);
- * (s1 had better have enough room!)
- */
- static void
- cat(char *s, ...)
- {
- char *s1;
- va_list ap;
-
- va_start(ap, s);
-
- *s = '\0';
-
- while(s1 = va_arg(ap, char *)) {
- strcat(s, s1);
- }
-
- va_end(ap);
- }
-
- long
- do_req(struct Window *client_win, char *volume)
- {
- struct Window *win;
- struct IntuiMessage *msg;
- extern BPTR nilfh;
- context_t *ct;
- long rc = -1; /* return code */
-
- /* bump the use count
- */
- ObtainSemaphore(&usecount_sema);
- usecount++;
-
- /* If we're the first use, grab the inuse semaphore
- */
- if(1L == usecount)
- ObtainSemaphore(&inuse_sema);
- ReleaseSemaphore(&usecount_sema);
-
- /* If this requester is exactly the same as one which was just canceled,
- * then don't bother displaying anything, just cancel it again.
- * This gets around some programs that like to retry three times.
- *
- * Note that the string comparison is case sensitive, so if you
- * accidentally cancel something you didn't mean to, you can force a
- * requester to appear by fudging the case.
- */
- ObtainSemaphore(&rc_sema);
- if(lastrc == 0 && !strcmp(volume, lastvol)) {
- ReleaseSemaphore(&rc_sema);
- rc = 0;
- goto done;
- }
- ReleaseSemaphore(&rc_sema);
-
- if(!(ct = get_context())) {
- goto done;
- }
-
- if(client_win) {
- ct->nw.Screen = client_win->WScreen;
- ct->nw.Type = CUSTOMSCREEN;
- } else {
- ct->nw.Screen = NULL;
- ct->nw.Type = WBENCHSCREEN;
- }
-
- cat(ct->line, "Volume ", volume, NULL);
-
- if(win = OpenWindow(&ct->nw)) {
- (void) ActivateGadget(&ct->g[4], win, NULL);
- while(rc == -1) {
- Wait(1L << win->UserPort->mp_SigBit);
- while(msg = (struct IntuiMessage *) GetMsg(win->UserPort)) {
- struct Gadget *gad = (struct Gadget *)(msg->IAddress);
-
- ReplyMsg((struct Message *) msg);
- switch(gad->GadgetID) {
- case RETRY:
- rc = 1;
- break;
- case MOUNT:
- cat(ct->cmd, "mount ", volume, ":\n", NULL);
- (void) Execute(ct->cmd, nilfh, nilfh);
- rc = 1;
- break;
- case ASSIGN:
- cat(ct->cmd, "assign ", volume, ": ", ct->strbuf, "\n", NULL);
- (void) Execute(ct->cmd, nilfh, nilfh);
- rc = 1;
- break;
- case CANCEL:
- rc = 0;
- break;
- }
- }
- }
- CloseWindow(win);
- }
-
- free_context(ct);
-
- done:
- /* save the return code
- */
- ObtainSemaphore(&rc_sema);
- lastrc = rc;
- if(0 == rc)
- strncpy(lastvol, volume, 40);
- ReleaseSemaphore(&rc_sema);
-
- /* One less user
- */
- ObtainSemaphore(&usecount_sema);
- usecount--;
- /* If we're the last to leave, release the inuse semaphore
- */
- if(0L == usecount)
- ReleaseSemaphore(&inuse_sema);
- ReleaseSemaphore(&usecount_sema);
-
- return rc;
- }
-