Beispiel #1
0
int main()
{
    LONG result = 0;
    LONG ioerr = 0;
    TEXT buffer[16];

    fh = Open("T:a", MODE_NEWFILE);

    /* Invalid parameters */
    SetIoErr(0);
    result = FRead(fh, buffer, 0, 0);
    ioerr = IoErr();
    TEST((result == 0));
    TEST((ioerr == 0));

    /* EOF */
    SetIoErr(0);
    result = FRead(fh, buffer, 1, 1);
    ioerr = IoErr();
    TEST((result == 0));
    TEST((ioerr == 0));

    /* BNULL file handle */
    SetIoErr(0);
    result = FRead(BNULL, buffer, 1, 1);
    ioerr = IoErr();
    TEST((result == 0));
    TEST((ioerr == 0));

    cleanup();

    return OK;
}
Beispiel #2
0
IPTR Ascii__OM_NEW(Class * cl, Object *o, struct opSet *msg)
{
    IPTR retval;
    
    if ((retval = DoSuperMethodA (cl, o, (Msg)msg)))
    {
         struct AsciiData 	*data;
         IPTR 			len, estlines, poolsize;
         BOOL 			success = FALSE;
         STRPTR 		buffer;

         /* Get a pointer to the object data */
         data = INST_DATA (cl, (Object *) retval);

         /* Get the attributes that we need to determine
	  * memory pool size */
         GetDTAttrs ((Object *) retval,
                     TDTA_Buffer	, (IPTR)&buffer,
                     TDTA_BufferLen	, (IPTR)&len,
                     TAG_DONE);

	D(bug("AsciiDataType_new: buffer = %x  bufferlen = %d\n", buffer, len));

         /* Make sure we have a text buffer */
         if (buffer && len)
         {
             /* Estimate the pool size that we will need */
             estlines = (len / 80) + 1;
             estlines = (estlines > 200) ? 200 : estlines;
             poolsize = sizeof (struct Line) * estlines;

             /* Create a memory pool for the line list */
             if ((data->Pool = CreatePool (MEMF_CLEAR | MEMF_PUBLIC, poolsize, poolsize)))
                 success = TRUE;
	     else
		 SetIoErr (ERROR_NO_FREE_STORE);
         }
         else
         {
	     /* Indicate that something was missing that we
	      * needed */
             SetIoErr (ERROR_REQUIRED_ARG_MISSING);
         }

         if (!success)
         {
             CoerceMethod (cl, (Object *) retval, OM_DISPOSE);
             retval = 0;
         }
     }
     
     return retval;     
}
Beispiel #3
0
static int load_hunk
(
    BPTR                file,
    BPTR              **next_hunk_ptr,
    struct pheader     *ph,
    SIPTR              *funcarray,
    struct DosLibrary  *DOSBase
)
{
    struct hunk *hunk;

    /* Sanity check */
    if (ph->memsz < ph->filesz)
    {
      SetIoErr(ERROR_BAD_HUNK);
      return 0;
    }
    
    if (!ph->memsz)
        return 1;

    hunk = MyAlloc(ph->memsz + sizeof(struct hunk), MEMF_ANY);
    if (hunk)
    {
	hunk->size = ph->memsz + sizeof(struct hunk);

        ph->paddr = hunk->data;

        /* Link the new hunk with the old next one. This makes it possible
           to handle insertion */
        hunk->next = BPTR2HUNK(*next_hunk_ptr)->next;
        
        /* Link the previous one with the new one */
        BPTR2HUNK(*next_hunk_ptr)->next = HUNK2BPTR(hunk);

        /* Update the pointer to the previous one, which is now the current one */
        *next_hunk_ptr = HUNK2BPTR(hunk);

        /* Clear out the memory that is not filled with file contents */
        memset(hunk->data + ph->filesz, 0, ph->memsz - ph->filesz);
        
        /* Finally read the segment from the file into memory */
        return read_block(file, ph->offset, hunk->data, ph->filesz, funcarray, DOSBase);
    }

    SetIoErr(ERROR_NO_FREE_STORE);

    return 0;
}
Beispiel #4
0
struct DosList *MyMakeDosEntry(struct Handler *handler, const TEXT *name, LONG type)
{
   struct DosList *entry;
   LONG error = 0;

   entry = AllocMem(sizeof(struct DosList), MEMF_CLEAR | MEMF_PUBLIC);

   if(entry != NULL)
   {
      if(!MyRenameDosEntry(handler, entry, name))
         error = IoErr();
      entry->dol_Type = type;
   }
   else
      error = IoErr();

   if(error != 0)
   {
      MyFreeDosEntry(handler, entry);
      entry = NULL;
   }

   SetIoErr(error);
   return entry;
}
Beispiel #5
0
static inline SIPTR readargs_file(CONST_STRPTR format, IPTR *args, CONST_STRPTR input, struct RDArgs **retp)
{
    SIPTR retval;
    struct RDArgs *ret;
    BPTR oldin;
    BPTR io;
    CONST_STRPTR tmpfile = "RAM:readargs.test";
    BPTR oldout;
    oldout = SelectOutput(Open("NIL:", MODE_NEWFILE));
   
    io = Open(tmpfile, MODE_NEWFILE);
    Write(io, input, strlen(input));
    Close(io);

    io = Open(tmpfile, MODE_OLDFILE);

    oldin = Input();
    SelectInput(io);
    SetIoErr(0);
    ret = ReadArgs(format, args, NULL);

    *retp = ret;
    retval = (ret != NULL) ? RETURN_OK : IoErr();

    Close(SelectInput(oldin));
    Close(SelectOutput(oldout));

    DeleteFile(tmpfile);

    return retval;
}
Beispiel #6
0
LONG DoIOFS(struct IOFileSys *iofs, struct DevProc *dvp, CONST_STRPTR name,
    struct DosLibrary *DOSBase) {
    BOOL freedvp = FALSE;

    if (dvp == NULL) {
        if ((dvp = GetDeviceProc(name, NULL)) == NULL)
            return IoErr();

        freedvp = TRUE;
    }

    iofs->IOFS.io_Device = (struct Device *) dvp->dvp_Port;

    if (dvp->dvp_Lock != NULL)
        iofs->IOFS.io_Unit = ((struct FileHandle *) BADDR(dvp->dvp_Lock))->fh_Unit;
    else
        iofs->IOFS.io_Unit = dvp->dvp_DevNode->dol_Ext.dol_AROS.dol_Unit;

    if (name != NULL)
        iofs->io_Union.io_NamedFile.io_Filename = StripVolume(name);

    DosDoIO((struct IORequest *)iofs);

    if (freedvp)
        FreeDeviceProc(dvp);

    SetIoErr(iofs->io_DosError);

    return iofs->io_DosError;
}
Beispiel #7
0
/* this function waits for a packet to come back from the file system. If no
 * packet is pending, state from the previous packet is returned. This ensures
 * that once an error occurs, it state is maintained for the rest of the life
 * of the file handle.
 *
 * This function also deals with IO errors, bringing up the needed DOS
 * requesters to let the user retry an operation or cancel it.
 */
LONG
AS_WaitPacket( AsyncFile *file )
{
#ifdef ASIO_NOEXTERNALS
	struct ExecBase		*SysBase = file->af_SysBase;
	struct DosLibrary	*DOSBase = file->af_DOSBase;
#endif
	LONG bytes;

	if( file->af_PacketPending )
	{
		while( TRUE )
		{
			/* This enables signalling when a packet comes back to the port */
			file->af_PacketPort.mp_Flags = PA_SIGNAL;

			/* Wait for the packet to come back, and remove it from the message
			 * list. Since we know no other packets can come in to the port, we can
			 * safely use Remove() instead of GetMsg(). If other packets could come in,
			 * we would have to use GetMsg(), which correctly arbitrates access in such
			 * a case
			 */
			Remove( ( struct Node * ) WaitPort( &file->af_PacketPort ) );

			/* set the port type back to PA_IGNORE so we won't be bothered with
			 * spurious signals
			 */
			file->af_PacketPort.mp_Flags = PA_IGNORE;

			/* mark packet as no longer pending since we removed it */
			file->af_PacketPending = FALSE;

			bytes = file->af_Packet.sp_Pkt.dp_Res1;

			if( bytes >= 0 )
			{
				/* packet didn't report an error, so bye... */
				return( bytes );
			}

			/* see if the user wants to try again... */
			if( ErrorReport( file->af_Packet.sp_Pkt.dp_Res2, REPORT_STREAM, file->af_File, NULL ) )
			{
				return( -1 );
			}

			/* user wants to try again, resend the packet */
			AS_SendPacket( file,
				file->af_Buffers[ file->af_ReadMode ?
					file->af_CurrentBuf :
					1 - file->af_CurrentBuf ] );
		}
	}

	/* last packet's error code, or 0 if packet was never sent */
	SetIoErr( file->af_Packet.sp_Pkt.dp_Res2 );

	return( file->af_Packet.sp_Pkt.dp_Res1 );
}
Beispiel #8
0
STRPTR AllocateNameFromLock(BPTR lock)
{
    ULONG  length = 512;
    STRPTR buffer = NULL;
    BOOL   done   = FALSE;
    
    while (!done)
    {
        if (buffer != NULL) FreeVec(buffer);
        
        buffer = AllocVec(length, MEMF_ANY);
        if (buffer != NULL)
        {
            if (NameFromLock(lock, buffer, length))
            {
                done = TRUE;
                break;
            }
            else
            {
                if (IoErr() == ERROR_LINE_TOO_LONG)
                {
                    length += 512;
                    continue;
                }
                else
                {
                    break;
                }                
            }
        }
        else
        {
            SetIoErr(ERROR_NO_FREE_STORE);
            break;
        }
    }
    
    if (done)
    {
        return buffer;
    }
    else
    {
        if (buffer != NULL) FreeVec(buffer);
        return NULL;
    }
}
Beispiel #9
0
PINT SetString(struct Handler *handler, TEXT **field, const TEXT *new_str)
{
   LONG error = 0;
   UPINT size;
   TEXT *str_copy = NULL, *old_str;
   PINT block_diff = 0;

   /* Allocate new string */

   size = StrSize(new_str);
   if(size > 1)
   {
      str_copy = AllocPooled(handler->muddy_pool, size);
      if(str_copy != NULL)
      {
         CopyMem(new_str, str_copy, size);
      }
      else
         error = ERROR_DISK_FULL;
   }
   else
      size = 0;

   if(error == 0)
   {
      /* Deallocate old string */

      if(size > 0)
         block_diff = MEMBLOCKS(size);
      old_str = *field;
      if(old_str != NULL)
      {
         size = StrSize(old_str);
         FreePooled(handler->muddy_pool, old_str, size);
         block_diff -= MEMBLOCKS(size);
      }

      /* Store new string */

      *field = str_copy;
   }

   /* Store error and return difference in block utilisation */

   SetIoErr(error);
   return block_diff;
}
Beispiel #10
0
static inline SIPTR readargs_buff(CONST_STRPTR format, IPTR *args, CONST_STRPTR input, struct RDArgs **retp)
{
    SIPTR retval;
    struct RDArgs *ret, *in;

    in = AllocDosObject(DOS_RDARGS, NULL);
    in->RDA_Source.CS_Buffer = (APTR)input;
    in->RDA_Source.CS_Length = strlen(input);
    in->RDA_Source.CS_CurChr = 0;
   
    SetIoErr(0);
    ret = ReadArgs(format, args, in);

    *retp = ret;
    retval = (ret != NULL) ? RETURN_OK : IoErr();

    return retval;
}
Beispiel #11
0
void readFileAreas(void) {
  BPTR fh;
  int i;
  if(!(fh = Open("NiKom:DatoCfg/Areor.dat", MODE_OLDFILE))) {
    cleanup(EXIT_ERROR,"Could not open NiKom:DatoCfg/Areor.dat");
  }
  SetIoErr(0L);
  Servermem->info.areor = FRead(fh, (void *)Servermem->areor,
                                sizeof(struct Area), MAXAREA);
  if(IoErr()) {
    cleanup(EXIT_ERROR, "Error reading Areor.dat");
  }
  Close(fh);
  for(i = 0; i < MAXAREA; i++) {
    NewList((struct List *)&Servermem->areor[i].ar_list);
  }
  printf("Read %d file areas.\n", Servermem->info.areor);
}
Beispiel #12
0
BOOL MyRenameDosEntry(struct Handler *handler, struct DosList *entry, const TEXT *name)
{
   LONG error = 0;
   UPINT length;
   TEXT *name_copy, *old_name;

   /* Allocate new string */

   name_copy = NULL;
   if(name != NULL)
   {
      length = StrLen(name);
#ifdef AROS_FAST_BPTR
      name_copy = AllocVec(length + 1, MEMF_PUBLIC);
      if(name_copy != NULL)
      {
         CopyMem(name, name_copy, length + 1);
      }
#else
      name_copy = AllocVec(length + 2, MEMF_PUBLIC);
      if(name_copy != NULL)
      {
         name_copy[0] = (UBYTE)(length > 255 ? 255 : length); 
         CopyMem(name, name_copy + 1, length + 1);
      }
#endif
      else
         error = IoErr();
   }

   /* Deallocate old string and set new one */

   if(error == 0)
   {
      old_name = BADDR(entry->dol_Name);
      FreeVec(old_name);
      entry->dol_Name = MKBADDR(name_copy);
   }

   /* Store error code and return success flag */

   SetIoErr(error);
   return error == 0;
}
Beispiel #13
0
static struct ph_packet *packet_alloc(void) {
    APTR pool;
    struct ph_packet *pkt;

    pool = CreatePool(MEMF_PUBLIC | MEMF_CLEAR, 1024, 256);
    if (pool == NULL) {
        SetIoErr(ERROR_NO_FREE_STORE);
        return NULL;
    }

    pkt = AllocPooled(pool, sizeof(struct ph_packet));

    pkt->dp.dp_Link = (struct Message *) pkt;
    pkt->msg.mn_Node.ln_Name = (char *) &(pkt->dp);

    pkt->pool = pool;

    return pkt;
}
Beispiel #14
0
static void * load_block
(
    BPTR               file,
    ULONG              offset,
    ULONG              size,
    SIPTR              *funcarray,
    struct DosLibrary *DOSBase
)
{
    void *block = MyAlloc(size, MEMF_ANY);
    if (block)
    {
        if (read_block(file, offset, block, size, funcarray, DOSBase))
            return block;

        MyFree(block, size);
    }
    else
        SetIoErr(ERROR_NO_FREE_STORE);

    return NULL;
}
Beispiel #15
0
static int read_block
(
    BPTR               file,
    ULONG              offset,
    APTR               buffer,
    ULONG              size,
    SIPTR              *funcarray,
    struct DosLibrary *DOSBase
)
{
    UBYTE *buf = (UBYTE *)buffer;
    LONG   subsize;

    if (Seek(file, offset, OFFSET_BEGINNING) < 0)
        return 0;

    while (size)
    {
        subsize = MyRead(file, buf, size);

        if (subsize <= 0)
        {
            if (subsize == 0)
            {
                D(bug("[ELF Loader] Error while reading from file.\n"));
                D(bug("[ELF Loader] Offset = %ld - Size = %ld\n", offset, size));
                SetIoErr(ERROR_BAD_HUNK);
            }

            return 0;
        }

        buf  += subsize;
        size -= subsize;
    }

    return 1;
}
Beispiel #16
0
void readGroupData(void) {
  BPTR fh;
  int x = 0;
  struct UserGroup *userGroup;

  NewList((struct List *)&Servermem->grupp_list);
  if(!(fh=Open("NiKom:DatoCfg/Grupper.dat",MODE_OLDFILE))) {
    cleanup(EXIT_ERROR, "Couldn't open NiKom:DatoCfg/Grupper.dat.");
  }
  
  for(;;) {
    if(!(userGroup=(struct UserGroup *)AllocMem(sizeof(struct UserGroup),
                                                MEMF_CLEAR | MEMF_PUBLIC))) {
      cleanup(EXIT_ERROR, "Out of memory.");
    }
    SetIoErr(0L);
    if(!FRead(fh, userGroup, sizeof(struct UserGroup), 1)) {
      if(IoErr()) {
        FreeMem(userGroup, sizeof(struct UserGroup));
        Close(fh);
        cleanup(EXIT_ERROR, "Error reading Grupper.dat");
      } else {
        FreeMem(userGroup, sizeof(struct UserGroup));
        break;
      }
    }
    if(!userGroup->namn[0]) {
      x++;
      continue;
    }
    AddTail((struct List *)&Servermem->grupp_list, (struct Node *)userGroup);
    userGroup->nummer = x;
    x++;
  }
  Close(fh);
  printf("Read %d user groups.\n", x);
}
Beispiel #17
0
BOOL Cache_Flush(APTR cache)
{
    struct Cache *c = cache;
    LONG error = 0, td_error;
    struct MinNode *n;
    struct BlockRange *b;

    while((n = (struct MinNode *)RemHead((struct List *)&c->dirty_list))
        != NULL && error == 0)
    {
        /* Write dirty block range to disk */

        b = NODE2(n);
        td_error = AccessDisk(TRUE, b->num, RANGE_SIZE, c->block_size,
            b->data, c->priv);

        /* Transfer block range to free list if unused, or put back on dirty
         * list upon an error */

        if(td_error == 0)
        {
            b->state = BS_VALID;
            if(b->use_count == 0)
                AddTail((struct List *)&c->free_list,
                    (struct Node *)&b->node2);
        }
        else
        {
            AddHead((struct List *)&c->dirty_list, (struct Node *)&b->node2);
            error = ERROR_UNKNOWN;
        }
    }

    SetIoErr(error);
    return error == 0;
}
Beispiel #18
0
BOOL MyRenameDosEntry(struct DosList *entry, const TEXT *name)
{
   LONG error = 0;
   UPINT length;
   TEXT *name_copy, *old_name;

   /* Allocate new string */

   name_copy = NULL;
   if(name != NULL)
   {
      length = StrLen(name);
      name_copy = AllocVec(length + 2, MEMF_PUBLIC);
      if(name_copy != NULL)
      {
         CopyMem(name, name_copy + 1, length + 1);
         *name_copy = length;
      }
      else
         error = IoErr();
   }

   /* Deallocate old string and set new one */

   if(error == 0)
   {
      old_name = BADDR(entry->dol_Name);
      FreeVec(old_name);
      entry->dol_Name = MKBADDR(name_copy);
   }

   /* Store error code and return success flag */

   SetIoErr(error);
   return error == 0;
}
Beispiel #19
0
LONG
main(VOID)
{
  struct DosLibrary *DOSBase;

  struct RDArgs  *readargs;
  LONG            rargs[5], vargs[5];
  UBYTE          *source, *target;
  ULONG           buffersize = 0;
  UBYTE          *sourcedir, *targetdir;
  UBYTE          *textbuffer, *tmp, *tmp1, *tmp2;
  struct AnchorPath *anchorpath;
  struct FileInfoBlock *fib, *targetfib;
  struct Process *process;
  APTR            wptr;
  BPTR            dirlock, filelock;
  BOOL            checkdatestamp, all;
  LONG            date, error, rc = 0;


  /* Fail silently if < 37 */
  if (DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 37))
  {
    rargs[0] = 0L;
    rargs[1] = 0L;
    rargs[2] = 0L;
    rargs[3] = 0L;
    rargs[4] = 0L;

    if (readargs = ReadArgs("SOURCE/A,TARGET/A,DATE/S,ALL/S,BUFFER/K/N", rargs, NULL))
    {

      source = (UBYTE *) rargs[0];
      target = (UBYTE *) rargs[1];
      checkdatestamp = (BOOL) rargs[2];
      all = (BOOL) rargs[3];

      if (!(sourcedir = AllocMem(StrLen(source) + 129, MEMF_CLEAR)))
        error = ERROR_NO_FREE_STORE;
      else
      {
        /* 128 bytes to print informative text */
        textbuffer = sourcedir + StrLen(source) + 1;

        /* use user specified buffersize if indicated */
        if (rargs[4])
          buffersize = *((LONG *) rargs[4]);
        if (buffersize < BUFFERSIZE || buffersize > 4096)
          buffersize = BUFFERSIZE;

        if (!(targetdir = AllocMem(buffersize, MEMF_CLEAR)))
          error = ERROR_NO_FREE_STORE;
        else
        {
          if (!(targetfib = AllocDosObject(DOS_FIB, NULL)))
            error = ERROR_NO_FREE_STORE;
          else
          {

            /*
             * Check if source and target are valid.
             *
             * Separate source path from pattern (if any). Use the source path figure
             * out what to append to the target.
             */

            /* No requesters */
            process = (struct Process *) FindTask(NULL);
            wptr = process->pr_WindowPtr;
            process->pr_WindowPtr = (APTR) - 1L;

            if ((error = GetPath(source, sourcedir, StrLen(source) + 1) == 0))
            {
              if (!(dirlock = Lock(sourcedir, SHARED_LOCK)))
                error = IoErr();
              else
              {
                UnLock(dirlock);
                if (!(dirlock = Lock(target, SHARED_LOCK)))
                  error = IoErr();
                else
                {
                  UnLock(dirlock);

                  if (anchorpath = AllocMem(sizeof(struct AnchorPath) + buffersize,
                                            MEMF_CLEAR))
                  {
                    anchorpath->ap_Strlen = buffersize;

                    /* Allow to break on CTRL-C */
                    anchorpath->ap_BreakBits = SIGBREAKF_CTRL_C;

                    if ((error = MatchFirst(source, anchorpath)) == 0)
                    {

                      do
                      {
                        fib = &(anchorpath->ap_Info);

                        /*
                         * APF_DIDDIR indicates that we used returned from a
                         * directory. In that case we clear both APF_DIDDIR and
                         * APF_DODIR, so we can start afresh with the next one.
                         */


                        if (anchorpath->ap_Flags & APF_DIDDIR)
                          anchorpath->ap_Flags &= ~(APF_DODIR | APF_DIDDIR);
                        else
                        {

                          /*
                           * Make a filename for the target directory. First copy
                           * targetname into buffer.
                           */
                          targetdir[0] = '\0';
                          tmp = targetdir;
                          tmp1 = target;
                          while (*tmp++ = *tmp1++);

                          /* Skip sourcename in ap_Buf */
                          tmp1 = sourcedir;
                          tmp2 = anchorpath->ap_Buf;
                          while (*tmp1++ == *tmp2++);
                          /* Skip back 1 if not after a separator */
                          if (*(tmp2 - 1) != '/')
                            tmp2--;

                          /*
                           * We hit the source itself, don't compare it, but enter
                           * it.
                           */
                          if (*tmp2 == 0)
                          {
                            anchorpath->ap_Flags |= APF_DODIR;
                            continue;
                          }

                          /* Build it */
                          if (AddPart(targetdir, tmp2, buffersize - 1))
                            vargs[0] = (LONG) targetdir;
                          else
                          {
                            PrintFault(ERROR_NO_FREE_STORE, NULL);
                            break;
                          }

                          /* Lock it and check it out */
                          if (filelock = Lock(targetdir, SHARED_LOCK))
                          {
                            if ((Examine(filelock, targetfib)) == DOSTRUE)
                            {
                              textbuffer[0] = '\0';

                              /*
                               * To get nice output without work I use AddPart() to
                               * add differences to the textbuffer.
                               */
                              if (targetfib->fib_DirEntryType
                                  != fib->fib_DirEntryType)
                                AddPart(textbuffer, "of different type", 128);
                              else
                              {
                                if (targetfib->fib_Size < fib->fib_Size)
                                  AddPart(textbuffer, "smaller", 128);
                                else if (targetfib->fib_Size > fib->fib_Size)
                                  AddPart(textbuffer, "larger", 128);

                                if (checkdatestamp)
                                {
                                  date = CompareDates((struct DateStamp *)
                                        & (fib->fib_Date),
                                      (struct DateStamp *) & (targetfib->fib_Date));
                                  if (date < 0)
                                    AddPart(textbuffer, "older", 128);
                                  else if (date > 0)
                                    AddPart(textbuffer, "newer", 128);
                                }
                              }


                              if (*textbuffer != NULL)
                              {
                                vargs[1] = (LONG) textbuffer;
                                VFPrintf(Output(), "%s: object %s\n", vargs);
                              }
                            }
                            else
                              PrintFault(IoErr(), targetdir);
                            UnLock(filelock);
                          }
                          else
                          {
                            PrintFault(IoErr(), targetdir);

                            /*
                             * If and error occured on a directory name, don't enter
                             * it.
                             */
                            if (fib->fib_DirEntryType > 0)
                              continue;

                          }

                          /*
                           * If the ALL keyword has been used and this is a directory
                           * enter it by setting the APF_DODIR flag.
                           */

                          if (fib->fib_DirEntryType > 0 && all != FALSE)
                            anchorpath->ap_Flags |= APF_DODIR;

                        }

                      } while ((error = MatchNext(anchorpath)) == 0);
                    }

                    MatchEnd(anchorpath);

                    if (error == ERROR_NO_MORE_ENTRIES)
                      error = 0;

                    FreeMem(anchorpath, sizeof(struct AnchorPath) + buffersize);
                  }
                }
              }
              /* Reset windowpointer */
              process->pr_WindowPtr = wptr;
            }
            else
              PrintFault(error, NULL);
            FreeDosObject(DOS_FIB, targetfib);
          }
          FreeMem(targetdir, buffersize);
        }
        FreeMem(sourcedir, StrLen(sourcedir) + 129);
      }
      FreeArgs(readargs);
    }
    else
      error = IoErr();

    SetIoErr(error);
    if (error)
    {
      PrintFault(error, NULL);
      if (error = ERROR_BREAK)
        rc = RETURN_WARN;
      else
        error = RETURN_FAIL;
    }
    CloseLibrary((struct Library *) DOSBase);
  }
  return (rc);
}
Beispiel #20
0
APTR Cache_GetBlock(APTR cache, ULONG blockNum, UBYTE **data)
{
    struct Cache *c = cache;
    struct BlockRange *b = NULL, *b2;
    LONG error = 0, data_offset;
    struct MinList *l =
        &c->hash_table[(blockNum >> RANGE_SHIFT) & (c->hash_size - 1)];
    struct MinNode *n;

    /* Change block number to the start block of a range and get byte offset
     * within range */

    data_offset = (blockNum - (blockNum & ~RANGE_MASK)) * c->block_size;
    blockNum &= ~RANGE_MASK;

    /* Check existing valid blocks first */

    ForeachNode(l, b2)
    {
        if(b2->num == blockNum)
            b = b2;
    }

    if(b != NULL)
    {
        /* Block found, so increment its usage count and remove it from the
         * free list */

        if(b->use_count++ == 0)
        {
            if(b->state != BS_DIRTY)
                Remove((struct Node *)&b->node2);
        }
    }
    else
    {
        /* Get a free buffer to read block from disk */

        n = (struct MinNode *)RemHead((struct List *)&c->free_list);
        if(n == NULL)
        {
            /* No free blocks, so flush dirty list to try and free up some
             * more blocks, then try again */

            Cache_Flush(c);

            n = (struct MinNode *)RemHead((struct List *)&c->free_list);
        }

        if(n != NULL)
        {
            b = (struct BlockRange *)NODE2(n);

            /* Read the block from disk */

            if(AccessDisk(FALSE, blockNum, RANGE_SIZE, c->block_size,
                b->data, c->priv) == 0)
            {
                /* Remove block from its old position in the hash */

                if(b->state == BS_VALID)
                    Remove((struct Node *)b);

                /* Add it to the hash at the new location */

                AddHead((struct List *)l, (struct Node *)&b->node1);
                b->num = blockNum;
                b->state = BS_VALID;
                b->use_count = 1;
            }
            else
            {
                /* Read failed, so put the block back on the free list */

                b->state = BS_EMPTY;
                AddHead((struct List *)&c->free_list,
                    (struct Node *)&b->node2);
                b = NULL;
                error = ERROR_UNKNOWN;
            }
        }
        else
            error = ERROR_NO_FREE_STORE;
    }

    /* Set data pointer and error, and return cache block handle */

    *data = b ? (b->data + data_offset) : NULL;
    SetIoErr(error);

    return b;
}
Beispiel #21
0
BOOL TaskRegSave( VOID )
{
	STRPTR data;
	ULONG data_len = 0;
	int items = 0;
	BOOL rc = FALSE;
	TaskReg *entry;
	struct DupsLog *d;
	
	ENTER();
	
	// this is executed uSemaLock()'ed or Forbid()'ed
	
	DBG_ASSERT(G && G->MagicID == GLOBAL_MAGIC);
	if(!G || G->MagicID != GLOBAL_MAGIC)
	{
		SetIoErr(ERROR_OBJECT_WRONG_TYPE);
		return FALSE;
	}
	
	if(IsMinListEmpty(G->TaskRegList))
	{
		DBG("The list is empty!\n");
		return TRUE;
	}
	
	NewList((struct List *) &tr_dups );
	
	ITERATE_LIST( G->TaskRegList, TaskReg *, entry)
	{
		if(IsDup(entry->TaskName,entry->AlertFlags,entry->ServerPort))
			continue;
		
		if((d = Malloc(sizeof(struct DupsLog))))
		{
			d->TaskName   = entry->TaskName;
			d->AlertFlags = entry->AlertFlags;
			d->ServerPort = entry->ServerPort;
			AddTail((struct List *)&tr_dups, (struct Node *)d);
		}
		
		items++;
		
		data_len += entry->TaskNameLength;
		#if DATABASE_RESERVED
		data_len += DATABASE_RESERVED;
		#endif
	}
	
	data_len += (sizeof(TaskReg) * items) + (sizeof(ULONG)*3);
	DBG_VALUE(data_len);
	
	if((data = Malloc(data_len)))
	{
		STRPTR ptr=data;
		BPTR fd;
		
		PutV( ptr, ULONG, DATABASE_ID);
		PutV( ptr, ULONG, DATABASE_VERSION);
		
		ITERATE_LIST( G->TaskRegList, TaskReg *, entry)
		{
			DBG_STRING(entry->TaskName);
			
			if(IsDup(entry->TaskName,entry->AlertFlags,entry->ServerPort))
				continue;
			
			PutV( ptr, UWORD, entry->TaskNameLength );
			PutX( ptr, entry->TaskNameLength, entry->TaskName );
			
			PutV( ptr, BYTE, entry->allow );
			PutV( ptr, BYTE, entry->remember );
			
			PutV( ptr, ULONG, entry->RegTime.ds_Days );
			PutV( ptr, ULONG, entry->RegTime.ds_Minute );
			PutV( ptr, ULONG, entry->RegTime.ds_Tick );
			
			PutV( ptr, ULONG, entry->ModTime.ds_Days );
			PutV( ptr, ULONG, entry->ModTime.ds_Minute );
			PutV( ptr, ULONG, entry->ModTime.ds_Tick );
			
			PutV( ptr, ULONG, entry->accesses   );
			PutV( ptr, ULONG, entry->FileCRC    );
			PutV( ptr, UWORD, entry->CRCMods    );
			PutV( ptr, UWORD, entry->AlertFlags );
			PutV( ptr, UWORD, entry->ServerPort );
			
			#if DATABASE_RESERVED
			ptr += DATABASE_RESERVED;
			#endif
		}
		
		PutV( ptr, ULONG, DATABASE_EOFID );
		
		if((fd = Open( DATABASE_FILE, MODE_NEWFILE )))
		{
			LONG len = (LONG)(ptr-data);
			DBG_VALUE(len);
			
			transcode( data, len );
			
			rc = (Write( fd, data, len ) == len);
			Close(fd);
		}
		
		Free(data);
	}
Beispiel #22
0
STRPTR BuildCommandLine(struct WBStartup *startup)
{
    const struct WBStartup *wbsstate = startup;
    STRPTR                  buffer   = NULL;
    /* 
       As C:Run seems to "eat" the quotes around the first argument it gets,
       let's feed it with quotes around an empty argument: it will be "eaten"
       and the real first argument that C:Execute will get will then be
       surrounded with quotes, which is needed when its path or name contains
       spaces. Of course it would be better to find and fix the real bug
       where it stands (probably dos.library/ReadArgs()).
    */
    ULONG                   length   = 2 /* NULL + '\n' */ + strlen("C:Run QUIET EXECUTE \"\"");
    int i;

    /*-- Calculate length of resulting string ------------------------------*/
    for (i = 1 ; i < wbsstate->sm_NumArgs ; i++)
    {
        BPTR lock = Lock((STRPTR) wbsstate->sm_ArgList[i].wa_Name, ACCESS_READ);
        if (lock != NULL)
        {
            BPTR cd   = CurrentDir(lock);
            STRPTR path = AllocateNameFromLock(lock);
            if (path != NULL)
            {
                length += 3 /* space + 2 '"' */ + strlen(path);
                FreeVec(path);
            }
            UnLock(lock);
            CurrentDir(cd);
        }
    }

    /*-- Allocate space for command line string ----------------------------*/
    buffer = AllocVec(length, MEMF_ANY);
    D(bug("[IconX] buffer length: %d\n", length));

    if (buffer != NULL)
    {
        /*-- Build command line --------------------------------------------*/
        buffer[0] = '\0';
	/* Please read the long comment about C:Run and quotes above */
        strcat(buffer, "C:Run QUIET EXECUTE \"\"");

        for (i = 1 ; i < wbsstate->sm_NumArgs ; i++)
        {
            BPTR lock = Lock((STRPTR) wbsstate->sm_ArgList[i].wa_Name, ACCESS_READ);
            if (lock != NULL)
            {
                BPTR cd   = CurrentDir(lock);
                STRPTR path = AllocateNameFromLock(lock);
                if (path != NULL)
                {
                    strcat(buffer, " \"");
                    strcat(buffer, path);
                    strcat(buffer, "\"");
                    FreeVec(path);
                }
                UnLock(lock);
                CurrentDir(cd);
            }
        }
        strcat(buffer, "\n");
    }
    else
    {
        SetIoErr(ERROR_NO_FREE_STORE);
    }

    return buffer;
}
Beispiel #23
0
void IOFS_SendPkt(struct DosPacket *dp, struct MsgPort *replyport, struct DosLibrary *DOSBase)
{
    /*
     * Trying to emulate the packet system by rewriting the
     * packets to IO Requests. Sometimes there are too many
     * parameters in the packet but thats fine. If there are
     * not enough parameters or the wrong type etc. then
     * it is more difficult to translate the packet.
     *
     */

    struct IOFileSys  *iofs = AllocMem(sizeof(struct IOFileSys), MEMF_CLEAR);
    struct FileHandle *fh;
    BPTR               oldCurDir;
    LONG               result; 
     
    if (iofs != NULL)
    {
	/*
	 * Also attach the packet to the io request.
	 * Will remain untouched by the driver.
	 */

	iofs->io_PacketEmulation = dp;
    
	/*
	 * In case the packet is to be aborted 
	 * I know which IORequest to use. The user will
	 * use the packet itself to abort the operation.
	 */
	dp->dp_Arg7 = (IPTR)iofs;


	iofs->IOFS.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
	iofs->IOFS.io_Message.mn_ReplyPort = replyport;
	iofs->IOFS.io_Message.mn_Length = sizeof(struct IOFileSys);
	iofs->IOFS.io_Flags = 0;

        /*
         * Have to rewrite this packet...
         */

        switch (dp->dp_Type)
	{
	case ACTION_NIL:
	case ACTION_READ_RETURN:
	case ACTION_WRITE_RETURN:
	case ACTION_TIMER:
	    kprintf("This packet is a reserved one and should not be sent"
		    " by you!\n");
	    // Alert();
	    return;
	    
	    // case ACTION_GET_BLOCK:
	case ACTION_DISK_CHANGE:
	case ACTION_DISK_TYPE:
	case ACTION_EVENT:
	case ACTION_SET_MAP:
	    
	    kprintf("This packet is obsolete. (ACTION type %d)\n",
		    dp->dp_Type);
	    return;


	case ACTION_FINDINPUT:      // Open() MODE_OLDFILE [*]
	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    
	    iofs->IOFS.io_Command = FSA_OPEN_FILE;
	    iofs->io_Union.io_OPEN_FILE.io_FileMode = FMF_WRITE | FMF_READ;
	    
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg2);
	    result = DoNameAsynch(iofs, BStrtoCStr((BSTR)dp->dp_Arg3),
				  DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		kprintf("Error: Didn't find file\n");
		return;
	    }
	    
	    kprintf("Returned from DoNameAsynch()\n");

	    break;
	    
	case ACTION_FINDOUTPUT:     // Open() MODE_NEWFILE [*]
	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    
	    iofs->IOFS.io_Command = FSA_OPEN_FILE;
	    iofs->io_Union.io_OPEN_FILE.io_FileMode = FMF_LOCK |
		FMF_CREATE | FMF_CLEAR | FMF_WRITE | FMF_READ;
	    
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg2);
	    result = DoNameAsynch(iofs, BStrtoCStr((BSTR)dp->dp_Arg3),
				  DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		return;
	    }
	    	    
	    break;
	    

	case ACTION_FINDUPDATE:     // Open() MODE_READWRITE [*]
	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    
	    iofs->IOFS.io_Command = FSA_OPEN_FILE;
	    iofs->io_Union.io_OPEN_FILE.io_FileMode = FMF_CREATE |
		FMF_WRITE | FMF_READ;
	    
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg2);
	    result = DoNameAsynch(iofs, BStrtoCStr((BSTR)dp->dp_Arg3),
				  DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		return;
	    }
	    	    
	    break;

	case ACTION_READ:           // Read() [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_READ;
	    iofs->io_Union.io_READ_WRITE.io_Buffer = (APTR)dp->dp_Arg2;
	    iofs->io_Union.io_READ_WRITE.io_Length = (LONG)dp->dp_Arg3;
	    
	    break;


	case ACTION_WRITE:          // Write() [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_WRITE;
	    iofs->io_Union.io_READ_WRITE.io_Buffer = (APTR)dp->dp_Arg2;
	    iofs->io_Union.io_READ_WRITE.io_Length = (LONG)dp->dp_Arg3;

	    break;

	case ACTION_SEEK:           // Seek()      [*] CH
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;

	    /* If the file is in write mode flush it. This is done
	       synchronously as otherwise the seek may be served before
	       the flush. (TODO: What are a reasonable semantics here?) */
	    if (fh->fh_Flags & FHF_WRITE)
	    {
		Flush(MKBADDR(fh));
	    }
	    else
	    {
		/* Read mode. Just reinit the buffers. We can't call
		   Flush() in this case as that would end up in recursion. */
		fh->fh_Pos = fh->fh_End = fh->fh_Buf;
	    }
	    
	    iofs->IOFS.io_Command = FSA_SEEK;
	    iofs->io_Union.io_SEEK.io_Offset = (QUAD)dp->dp_Arg2;
	    iofs->io_Union.io_SEEK.io_SeekMode = dp->dp_Arg3;
	    
	    break;
	    
	case ACTION_SET_FILE_SIZE:  // SetFileSize()        [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_SET_FILE_SIZE;
	    iofs->io_Union.io_SET_FILE_SIZE.io_Offset   = (QUAD)dp->dp_Arg2;
	    iofs->io_Union.io_SET_FILE_SIZE.io_SeekMode = dp->dp_Arg3;
	    break;

	case ACTION_EXAMINE_FH:     // ExamineFH()
	case ACTION_EXAMINE_OBJECT: // Examine() [*]  --  the same thing
	                            //                    in AROS
	    {
		UBYTE *buffer = AllocVec(sizeof(struct ExAllData), 
					 MEMF_PUBLIC | MEMF_CLEAR);

		if (buffer == NULL)
		{
		    dp->dp_Res1 = DOSFALSE;
		    dp->dp_Res2 = ERROR_NO_FREE_STORE;

		    return;
		}
		
		fh = (struct FileHandle *)dp->dp_Arg1;
		
		iofs->IOFS.io_Device = fh->fh_Device;
		iofs->IOFS.io_Unit   = fh->fh_Unit;
		
		iofs->IOFS.io_Command = FSA_EXAMINE;
		iofs->io_Union.io_EXAMINE.io_ead = (struct ExAllData *)buffer;
		iofs->io_Union.io_EXAMINE.io_Size = sizeof(struct ExAllData);
		iofs->io_Union.io_EXAMINE.io_Mode = ED_OWNER;

		/* A supplied FileInfoBlock (is a BPTR) is in dp_Arg2 */
		
		break;
	    }
	    
	case ACTION_EXAMINE_NEXT:   // ExNext() [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_EXAMINE_NEXT;
	    iofs->io_Union.io_EXAMINE_NEXT.io_fib = (BPTR)dp->dp_Arg2;
	    
	    break;	    

	case ACTION_CREATE_DIR:     // CreateDir() [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_CREATE_DIR;
	    iofs->io_Union.io_CREATE_DIR.io_Filename = BStrtoCStr((BSTR)dp->dp_Arg2);
	    iofs->io_Union.io_CREATE_DIR.io_Protection = 0;
	    
	    break;

	    
	case ACTION_DELETE_OBJECT:  // DeleteFile()     [*]
	    // ARG1:   LOCK    Lock to which ARG2 is relative
	    // ARG2:   BSTR    Name of object to delete (relative to ARG1)
	    
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    /* IFS_DELETE_OBJECT just consists of a STRPTR so we have to
	       use NameFromLock() here -- TODO */
	    // iofs->io_Union.io_DELETE_OBJECT.io_Filename = BStrtoCStr((BSTR)dp->dp_Arg2);
	    iofs->IOFS.io_Command = FSA_DELETE_OBJECT;
	    
	    break;

	case ACTION_RENAME_OBJECT:  // Rename()
	    /* TODO */
	    break;

	case ACTION_LOCK_RECORD:    // LockRecord()
	    fh = (struct FileHandle *)BADDR(dp->dp_Arg1);

	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit = fh->fh_Unit;

	    iofs->io_Union.io_RECORD.io_Offset = (QUAD)dp->dp_Arg2;
	    iofs->io_Union.io_RECORD.io_Size = (LONG)dp->dp_Arg3;
	    iofs->io_Union.io_RECORD.io_RecordMode = (LONG)dp->dp_Arg4;
	    iofs->io_Union.io_RECORD.io_Timeout = (LONG)dp->dp_Arg5;
	    break;
	    
	case ACTION_FREE_RECORD:    // UnlockRecord()
	    fh = (struct FileHandle *)BADDR(dp->dp_Arg1);
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit = fh->fh_Unit;

	    iofs->io_Union.io_RECORD.io_Offset = (QUAD)dp->dp_Arg2;
	    iofs->io_Union.io_RECORD.io_Size = (LONG)dp->dp_Arg3;
	    iofs->io_Union.io_RECORD.io_RecordMode = (LONG)dp->dp_Arg4;
	    break; 

	case ACTION_PARENT:         // ParentDir()     [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_OPEN;
	    iofs->io_Union.io_OPEN.io_FileMode = FMF_READ; // Shared lock
	    
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg1);
	    result = DoNameAsynch(iofs, "/", DOSBase);
	    CurrentDir(oldCurDir);
	    
	    if (result != 0)
	    {
		return;
	    }

	    return;

	case ACTION_SET_PROTECT:    // SetProtection()    [*]
	    // STRPTR io_Filename;   /* The file to change. */
	    // ULONG  io_Protection; /* The new protection bits. */

	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    	
	    iofs->IOFS.io_Command = FSA_SET_PROTECT;
	    iofs->io_Union.io_SET_PROTECT.io_Protection = dp->dp_Arg4;
	    iofs->io_Union.io_SET_PROTECT.io_Filename = BStrtoCStr(dp->dp_Arg3);
		
	    break;
	    
	case ACTION_SET_COMMENT:    // SetComment()       [*]
	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_SET_COMMENT;
	    iofs->io_Union.io_SET_COMMENT.io_Filename = BStrtoCStr((BSTR)dp->dp_Arg3);
	    iofs->io_Union.io_SET_COMMENT.io_Comment = BStrtoCStr(dp->dp_Arg4);
	    
	    break;

	case ACTION_LOCATE_OBJECT:  // Lock()         [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_OPEN;
	    
	    switch (dp->dp_Arg3)
	    {
	    case EXCLUSIVE_LOCK:
		iofs->io_Union.io_OPEN.io_FileMode = FMF_LOCK | FMF_READ;
		break;
		
	    case SHARED_LOCK:
		iofs->io_Union.io_OPEN.io_FileMode = FMF_READ;
		break;
		
	    default:
		iofs->io_Union.io_OPEN.io_FileMode = dp->dp_Arg3;
		break;
	    }
	    
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg1);
	    result = DoNameAsynch(iofs, BStrtoCStr((BSTR)dp->dp_Arg2),
				  DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		return;
	    }
	    	    
	    dp->dp_Arg6 = (IPTR)AllocDosObject(DOS_FILEHANDLE, NULL);

	    if (dp->dp_Arg6 == (IPTR)NULL)
	    {
		return;
	    }

	    break;

	case ACTION_COPY_DIR:       // DupLock()
	case ACTION_COPY_DIR_FH:    // DupLockFromFH() -- the same thing
	                            //                    in AROS
	    fh = (struct FileHandle *)BADDR(dp->dp_Arg1);
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_OPEN;
	    
	    /* Create a shared lock */
	    iofs->io_Union.io_OPEN.io_FileMode = FMF_READ;
		
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg1);
	    result = DoNameAsynch(iofs, "", DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		return;
	    }
	    
	    dp->dp_Arg6 = (IPTR)AllocDosObject(DOS_FILEHANDLE, NULL);

	    if (dp->dp_Arg6 == (IPTR)NULL)
	    {
		return;
	    }

	    break;

	case ACTION_END:            // Close() [*]
	case ACTION_FREE_LOCK:      // UnLock() -- the same thing in AROS
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    /* If the filehandle has a pending write on it Flush() the buffer.
	       This is made synchronously... */
	    if (fh->fh_Flags & FHF_WRITE)
	    {
		Flush(MKBADDR(fh));
	    }

	    iofs->IOFS.io_Command = FSA_CLOSE;

	    break;

	case ACTION_SET_DATE:       // SetFileDate() [*]
	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_SET_DATE;
	    memcpy(&iofs->io_Union.io_SET_DATE.io_Date, (APTR)dp->dp_Arg4,
		   sizeof(struct DateStamp));

	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg2);
	    result = DoNameAsynch(iofs, BStrtoCStr((BSTR)dp->dp_Arg3),
				  DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		return;
	    }
	    	    
	    break;

	case ACTION_SAME_LOCK:      // SameLock() [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_SAME_LOCK;
	    
	    iofs->io_Union.io_SAME_LOCK.io_Lock[0] = BADDR((BPTR)dp->dp_Arg1);
	    iofs->io_Union.io_SAME_LOCK.io_Lock[1] = BADDR((BPTR)dp->dp_Arg2);
	    
	    break;
	    
	case ACTION_MAKE_LINK:      // MakeLink()
	    {
		STRPTR name = BStrtoCStr(dp->dp_Arg2);
	    
		if (dp->dp_Arg4 == LINK_SOFT)
		{
		    /* We want a soft-link. */
		    iofs->IOFS.io_Command = FSA_CREATE_SOFTLINK;
		    iofs->io_Union.io_CREATE_SOFTLINK.io_Reference = (STRPTR)dp->dp_Arg3;
		}
		else
		{
		    /* We want a hard-link. */
		    struct FileHandle *fh = (struct FileHandle *)BADDR((BPTR)dp->dp_Arg3);
                    struct DevProc *dvp;

		    /* We check, if name and dest are on the same device. */
                    if ((dvp = GetDeviceProc(name, NULL)) == NULL)
		    {
			/* TODO: Simulate packet return */
			return;
		    }
		    
		    if (dvp->dvp_Port != (struct MsgPort *)fh->fh_Device)
		    {
                        FreeDeviceProc(dvp);
			SetIoErr(ERROR_RENAME_ACROSS_DEVICES);
			
			/* TODO: Simulate packet return */
			return;
		    }

                    FreeDeviceProc(dvp);
		    
		    iofs->IOFS.io_Command = FSA_CREATE_HARDLINK;
		    iofs->io_Union.io_CREATE_HARDLINK.io_OldFile = fh->fh_Unit;
		}
		
		oldCurDir = CurrentDir((BPTR)dp->dp_Arg1);
		DoNameAsynch(iofs, name, DOSBase);
		CurrentDir(oldCurDir);
	    }
	    
	    break;
	    
	case ACTION_READ_LINK:      // ReadLink()
	    /* TODO */
	    break;
	    
	case ACTION_EXAMINE_ALL:    // ExAll()
	    /* TODO */
	    break;
	    
	case ACTION_ADD_NOTIFY:     // StartNotify()
	    {
		struct NotifyRequest *notify = (struct NotifyRequest *)BADDR(dp->dp_Arg1);
	        struct FileHandle *dir;

		iofs->IOFS.io_Command = FSA_ADD_NOTIFY;
		iofs->io_Union.io_NOTIFY.io_NotificationRequest = notify;

		notify->nr_MsgCount = 0;

		if (strchr(notify->nr_Name, ':') != NULL)
		{
		    DoNameAsynch(iofs, notify->nr_Name, DOSBase);
		}
		else
		{
		    dir = BADDR(CurrentDir(NULL));
		    CurrentDir(MKBADDR(dir));	/* Set back the current dir */
		    
		    if (dir == NULL)
		    {
			return;
		    }
		    
		    iofs->IOFS.io_Device = dir->fh_Device;
		    iofs->IOFS.io_Unit = dir->fh_Unit;
		    
		    /* Save device for EndNotify() purposes */
		    notify->nr_Handler = (struct MsgPort *) dir->fh_Device;
	
		    if (iofs->IOFS.io_Device == NULL)
		    {
			return;
		    }
		}
	    }

	    break;
	    
	case ACTION_REMOVE_NOTIFY:  // EndNotify()
	    {
		struct NotifyRequest *notify = (struct NotifyRequest *)BADDR(dp->dp_Arg1);

		iofs->IOFS.io_Command = FSA_REMOVE_NOTIFY;
		iofs->io_Union.io_NOTIFY.io_NotificationRequest = notify;
		
		if (strchr(notify->nr_Name, ':'))
		{
		    DoNameAsynch(iofs, notify->nr_Name, DOSBase);
		}
		else
		{
		    iofs->IOFS.io_Device = (struct Device *)notify->nr_Handler;
		    
		    if (iofs->IOFS.io_Device == NULL)
		    {
			return;
		    }
		}
	    }

	    break;
	    

	    /* The following five packets are only relative to the
	       message port of the file system to send to. Therefore, 
	       we fill in only partial information in the IOFileSys and
	       hope for the best... Specifically, the device cannot
	       use iofs->io_Device. TODO */
	case ACTION_RENAME_DISK:    // Relabel()
	    /* TODO */
	    break;

	case ACTION_FORMAT:         // Format()
	    /* TODO */
	    break;
	    
	case ACTION_MORE_CACHE:     // AddBuffers()
	    /* TODO */
	    break;
	    
	case ACTION_INHIBIT:        // Inhibit()
	    /* TODO */
	    break;

	case ACTION_IS_FILESYSTEM:  // IsFileSystem()
	    /* TODO */
	    break;

	case ACTION_DISK_INFO:      // Info()
	    /* TODO */
	    break;

	case ACTION_INFO:           // No associated function
	    /* TODO */
	    break;

	case ACTION_CURRENT_VOLUME: // No associated function
	    /* TODO */
	    break;

	case ACTION_PARENT_FH:      // ParentOfFH()
	    /* TODO -- Should be the same as ACTION_PARENT? For some reason
	               ParentDir() and ParentOfFH() is implemented differently
	               in AROS. Have to investigate this further. */
	    break;
	    
	case ACTION_FH_FROM_LOCK:   // OpenFromLock()
	    /* TODO: Have so simulate ReplyMsg() here */
	    return;

	case ACTION_SET_OWNER:      // SetOwner()
	    // Unfortunately, I have no info regardning this packet.
	    
	    // iofs->IOFS.io_Command = FSA_SET_OWNER;
	    // iofs->io_Union.io_SET_OWNER.io_UID = owner_info >> 16;
	    // iofs->io_Union.io_SET_OWNER.io_GID = owner_info & 0xffff;
	    
	    break;

	case ACTION_CHANGE_MODE:    // ChangeMode()
	    /* TODO */
	    break;

	    /* I haven't looked into the following packets in detail */
	case ACTION_DIE:            // No associated function
	    break;
	    
	case ACTION_WRITE_PROTECT:  // No associated function
	    break;
	    
	case ACTION_FLUSH:          // No associated function
	    break;
	    
	case ACTION_SERIALIZE_DISK: // No associated function
	    break;
	    

	    // ---  Console only packets  ------------------------------
	    /* I think these should not be implemented as packets except
	       for ACTION_WAIT_CHAR which is not really a console only
	       packet. Instead functions should be added to console.device */

	case ACTION_SCREEN_MODE:    // SetMode()
	    /* TODO*/
	    break;
	    
	case ACTION_CHANGE_SIGNAL:  // No associated function
	    {
	    	struct MsgPort *msgport;
		struct Task    *task;
		
		fh = (struct FileHandle *)dp->dp_Arg1;
    	    	msgport = (struct MsgPort *)dp->dp_Arg2;
		task = msgport ? msgport->mp_SigTask : NULL;
		
		iofs->IOFS.io_Device = fh->fh_Device;
		iofs->IOFS.io_Unit   = fh->fh_Unit;

		iofs->IOFS.io_Command = FSA_CHANGE_SIGNAL;
		iofs->io_Union.io_CHANGE_SIGNAL.io_Task = task;
	    }
	    break;
	    
	case ACTION_WAIT_CHAR:      // WaitForChar()	
	    /* TODO */
	    break;

	default:
	    D(kprintf("Unknown packet type %d found in SendPkt()\n", dp->dp_Type));
            dp->dp_Res1 = DOSFALSE;
            dp->dp_Res2 = ERROR_ACTION_NOT_KNOWN;
            PutMsg(replyport, dp->dp_Link);
	    return;
	}

	D(kprintf("Calling SendIO() with command %u\n", iofs->IOFS.io_Command));
	
	SendIO((struct IORequest *)iofs);
    }        
 
}
Beispiel #24
0
static int check_header(struct elfheader *eh, struct DosLibrary *DOSBase)
{
    if
    (
        eh->ident[0] != 0x7f ||
        eh->ident[1] != 'E'  ||
        eh->ident[2] != 'L'  ||
        eh->ident[3] != 'F'
    )
    {
        D(bug("[ELF Loader] Not an elf object\n"));
        SetIoErr(ERROR_NOT_EXECUTABLE);
        return 0;
    }

    if
    (
        eh->ident[EI_CLASS]      != (ELFCLASS32 || ELFCLASS64)    ||
        eh->ident[EI_VERSION]    != EV_CURRENT    ||
        eh->ident[EI_OSABI]      != ELFOSABI_AROS ||
        eh->ident[EI_ABIVERSION] != 0             ||
        eh->type                 != ET_EXEC       ||

        #if defined(__i386__)

            eh->ident[EI_DATA] != ELFDATA2LSB ||
            eh->machine        != EM_386

        #elif defined(__x86_64__)

            eh->ident[EI_DATA] != ELFDATA2LSB ||
            eh->machine        != EM_X86_64

        #elif defined(__mc68000__)

            eh->ident[EI_DATA] != ELFDATA2MSB ||
            eh->machine        != EM_68K

        #elif defined(__ppc__) || defined(__powerpc__)
            eh->ident[EI_DATA] != ELFDATA2MSB ||
            eh->machine        != EM_PPC

        #elif defined(__arm__)
            
            eh->ident[EI_DATA] != ELFDATA2LSB ||
            eh->machine        != EM_ARM

        #else
        #    error Your architecture is not supported
        #endif
    )
    {
        D(bug("[ELF Loader] Object is of wrong type\n"));
        D(bug("[ELF Loader] EI_CLASS   is %d - should be %d\n", eh->ident[EI_CLASS],   ELFCLASS32));
        D(bug("[ELF Loader] EI_VERSION is %d - should be %d\n", eh->ident[EI_VERSION], EV_CURRENT));
        D(bug("[ELF Loader] type       is %d - should be %d\n", eh->type,              ET_REL));

#if defined (__i386__)
        D(bug("[ELF Loader] EI_DATA    is %d - should be %d\n", eh->ident[EI_DATA], ELFDATA2LSB));
#elif defined(__mc68000__)
        D(bug("[ELF Loader] EI_DATA    is %d - should be %d\n", eh->ident[EI_DATA], ELFDATA2MSB));
#elif defined(__ppc__) || defined(__powerpc__)
        D(bug("[ELF Loader] EI_DATA    is %d - should be %d\n", eh->ident[EI_DATA],ELFDATA2MSB));
#elif defined(__arm__)
        D(bug("[ELF Loader] EI_DATA    is %d - should be %d\n", eh->ident[EI_DATA], ELFDATA2MSB));
#endif

#if defined (__i386__)
        D(bug("[ELF Loader] machine    is %d - should be %d\n", eh->machine, EM_386));
#elif defined(__mc68000__)
        D(bug("[ELF Loader] machine    is %d - should be %d\n", eh->machine, EM_68K));
#elif defined(__ppc__) || defined(__powerpc__)
        D(bug("[ELF Loader] machine    is %d - should be %d\n", eh->machine, EM_PPC));
#elif defined(__arm__)
        D(bug("[ELF Loader] machine    is %d - should be %d\n", eh->machine, EM_ARM));
#endif

        SetIoErr(ERROR_OBJECT_WRONG_TYPE);
        return 0;
    }

    return 1;
}
Beispiel #25
0
ULONG
LoadModeFile( UBYTE*          name,
              struct AHIBase* AHIBase )
{
  ULONG rc=FALSE;
  struct FileInfoBlock  *fib;
  BPTR  lock,thisdir;

  if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_HIGH)
  {
    Debug_LoadModeFile(name);
  }

  SetIoErr(NULL);

  fib = AllocDosObject(DOS_FIB, TAG_DONE);

  if(fib != NULL)
  {
    lock = Lock(name, ACCESS_READ);

    if(lock != NULL)
    {
      if(Examine(lock,fib))
      {
        if(fib->fib_DirEntryType>0) // Directory?
        {
          thisdir = CurrentDir(lock);

          while(ExNext(lock, fib))
          {
            if(fib->fib_DirEntryType>0)
            {
              continue;     // AHI_LoadModeFile(fib->fib_FileName); for recursion
            }
            else
            {
              rc = AddModeFile(fib->fib_FileName);

              if(!rc)
              {
                break;
              }
            }
          }
          if(IoErr() == ERROR_NO_MORE_ENTRIES)
          {
            SetIoErr(NULL);
          }

          CurrentDir(thisdir);
        }
        else  // Plain file
        {
          rc = AddModeFile(name);
        }
      }

      UnLock(lock);
    }

    FreeDosObject(DOS_FIB,fib);
  }

  if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_HIGH)
  {
    KPrintF("=>%ld\n",rc);
  }

  return rc;
}
Beispiel #26
0
LONG SmartReadArgs(struct WBStartup * wb_startup, struct SmartArgs * args)
{
   LONG error;

   args->sa_Flags = 0;

   D(bug("UtilityBase = 0x%lx\n", (ULONG) UtilityBase));
   D(bug("IconBase    = 0x%lx\n", (ULONG) IconBase));
   D(bug("WBStartup   = 0x%lx\n", (ULONG) wb_startup));

   if (wb_startup != NULL)
   {
      struct WBArg *wbarg = wb_startup->sm_ArgList;
      LONG arg_counter = 0;

      D(bug("  numArgs   = %ld\n", wb_startup->sm_NumArgs));
      while (arg_counter < wb_startup->sm_NumArgs)
      {
         D(bug("  name[%ld] = \"%s\"\n", arg_counter, wbarg->wa_Name));
         wbarg += 1;
         arg_counter += 1;
      }
   }

   if (wb_startup != NULL)
   {
      if (!(args->sa_RDArgs = AllocDosObject(DOS_RDARGS, NULL)))
      {
         return (ERROR_NO_FREE_STORE);
      }
      else
      {
         args->sa_Flags |= SAF_ALLOCRDARGS;

         if (!args->sa_Buffer)
         {
            args->sa_BufferSize = MAX(SA_MINIMUM_BUFFER_SIZE, args->sa_BufferSize);
            args->sa_Buffer = AllocMem(args->sa_BufferSize, MEMF_ANY);
            args->sa_Flags |= SAF_ALLOCBUFFER;
         }

         if (!args->sa_Buffer)
            return (ERROR_NO_FREE_STORE);
         else
         {
            struct DiskObject *dobj;

            args->sa_ActualPtr = args->sa_Buffer;
            args->sa_EndPtr = args->sa_Buffer + args->sa_BufferSize - 1;

            if (!(dobj = smart_get_icon(args, wb_startup)))
            {
               return (ERROR_OBJECT_NOT_FOUND);
            }
            else
            {
               struct WBArg *wbarg = args->sa_WBArg;
               ULONG num = args->sa_NumArgs;

               STRPTR *tooltypes = (STRPTR *) dobj->do_ToolTypes;
               STRPTR name;
               STRPTR temp;
               STRPTR ptr;

               if (num > 1 && args->sa_FileParameter >= 0 && (temp = AllocMem(TEMPSIZE, MEMF_ANY)))
               {
                  ULONG modes = 0;

                  get_arg_name(args, temp, TEMPSIZE, &modes);
                  fstrcpy(args, temp);
                  fstrcpy(args, " ");

                  /* no "/M" specifier in the ReadArgs() template, thus use only the first file */
                  if (modes != MODE_MULTI)
                     num = 2;

                  while (num > 1)
                  {
                     get_wbarg_name(wbarg, temp, TEMPSIZE);
                     fstrcpy(args, "\"");
                     fstrcpy(args, temp);
                     fstrcpy(args, "\" ");
                     num--;
                     wbarg++;
                  }

                  FreeMem(temp, TEMPSIZE);
               }

               D(bug("tooltypes=%lx\n", (ULONG) tooltypes));
               if (tooltypes)
               {
                  while (*tooltypes)
                  {
                     ptr = *tooltypes;
                     name = ptr;

                     /* check if this tooltype enabled and part of the
                      * template */
                     if ((*ptr != '(')
                         && is_in_template(name, args->sa_Template))
                     {
                        while (*ptr != '=' && *ptr != EOS)
                           ptr++;

                        if (*ptr == '=')
                        {
                           *ptr = EOS;

                           if (!Stricmp(name, "WINDOW"))
                           {
                              STRPTR win;
                              if ((win = AllocVec(strlen(ptr + 1) + 1, MEMF_ANY)))
                              {
                                 strcpy(win, ptr + 1);
                                 args->sa_Window = win;
                                 args->sa_Flags |= SAF_ALLOCWINDOW;
                              }

                           }
                           else
                           {
                              fstrcpy(args, name);

                              /* enclose the argument in "" */
                              if (*(ptr + 1) == '"')
                              {
                                 fstrcpy(args, "=");
                                 fstrcpy(args, ptr + 1);
                              }
                              else
                              {
                                 fstrcpy(args, "=\"");
                                 fstrcpy(args, ptr + 1);
                                 fstrcpy(args, "\"");
                              }

                              *ptr = '=';
                           }
                        }
                        else
                           fstrcpy(args, name);

                        fstrcpy(args, " ");
                     }
                     tooltypes++;
                  }             /* while (*tooltypes) */
               }                /* if (tooltypes) */
               fstrcpy(args, "\n");

               D(bug("final wb command line : \"%s\"\n", args->sa_Buffer));
            }
         }
      }

      args->sa_RDArgs->RDA_Source.CS_Buffer = args->sa_Buffer;
      args->sa_RDArgs->RDA_Source.CS_Length = strlen(args->sa_Buffer);

      args->sa_Flags |= SAF_WORKBENCH;
   }

   args->sa_FreeArgs = ReadArgs(args->sa_Template, args->sa_Parameter, args->sa_RDArgs);

   if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
   {
      SetIoErr(ERROR_BREAK);
   }

   if ((error = IoErr()) == 0 && (wb_startup != NULL))
   {
      if (args->sa_Window)
      {
         args->sa_WindowFH = Open(args->sa_Window, MODE_NEWFILE);
         if (args->sa_WindowFH)
         {
            args->sa_OldOutput = SelectOutput(args->sa_WindowFH);
            args->sa_OldInput = SelectInput(args->sa_WindowFH);
         }
      }
   }

   return (error);
}
Beispiel #27
0
int main(int argc, char *argv[])
{
  BYTE *p1=buffer1,*p2=buffer2;
  void *tmp;
  ULONG signals,length;
  struct AHIRequest *link = NULL;
  LONG priority = 0;
  BYTE pri;

  if(argc == 2)
  {
    StrToLong(argv[1], &priority);
  }
  pri = priority;
  Printf("Sound priority: %ld\n", pri);

  if((AHImp=CreateMsgPort()) != NULL) {
    if((AHIio=(struct AHIRequest *)CreateIORequest(AHImp,sizeof(struct AHIRequest))) != NULL) {
      AHIio->ahir_Version = 4;
      AHIDevice=OpenDevice(AHINAME,0,(struct IORequest *)AHIio,0);
    }
  }

  if(AHIDevice) {
    Printf("Unable to open %s/0 version 4\n",AHINAME);
    cleanup(RETURN_FAIL);
  }

// Make a copy of the request (for double buffering)
  AHIiocopy = AllocMem(sizeof(struct AHIRequest), MEMF_ANY);
  if(! AHIiocopy) {
    cleanup(RETURN_FAIL);
  }
  CopyMem(AHIio, AHIiocopy, sizeof(struct AHIRequest));
  AHIios[0]=AHIio;
  AHIios[1]=AHIiocopy;

  SetIoErr(0);

  for(;;) {

// Fill buffer
    length = Read(Input(),p1,BUFFERSIZE);

// Play buffer
    AHIios[0]->ahir_Std.io_Message.mn_Node.ln_Pri = pri;
    AHIios[0]->ahir_Std.io_Command  = CMD_WRITE;
    AHIios[0]->ahir_Std.io_Data     = p1;
    AHIios[0]->ahir_Std.io_Length   = length;
    AHIios[0]->ahir_Std.io_Offset   = 0;
    AHIios[0]->ahir_Frequency       = FREQUENCY;
    AHIios[0]->ahir_Type            = TYPE;
    AHIios[0]->ahir_Volume          = 0x10000;          // Full volume
    AHIios[0]->ahir_Position        = 0x8000;           // Centered
    AHIios[0]->ahir_Link            = link;
    SendIO((struct IORequest *) AHIios[0]);

    if(link) {

// Wait until the last buffer is finished (== the new buffer is started)
      signals=Wait(SIGBREAKF_CTRL_C | (1L << AHImp->mp_SigBit));

// Check for Ctrl-C and abort if pressed
      if(signals & SIGBREAKF_CTRL_C) {
        SetIoErr(ERROR_BREAK);
        break;
      }

// Remove the reply and abort on error
      if(WaitIO((struct IORequest *) link)) {
        SetIoErr(ERROR_WRITE_PROTECTED);
        break;
      }
    }

// Check for end-of-sound, and wait until it is finished before aborting
    if(length != BUFFERSIZE) {
      WaitIO((struct IORequest *) AHIios[0]);
      break;
    }

    link = AHIios[0];

// Swap buffer and request pointers, and restart
    tmp    = p1;
    p1     = p2;
    p2     = tmp;

    tmp    = AHIios[0];
    AHIios[0] = AHIios[1];
    AHIios[1] = tmp;
  }
  

// Abort any pending iorequests
  AbortIO((struct IORequest *) AHIios[0]);
  WaitIO((struct IORequest *) AHIios[0]);

  if(link) { // Only if the second request was started
    AbortIO((struct IORequest *) AHIios[1]);
    WaitIO((struct IORequest *) AHIios[1]);
  }

  if(IoErr()) {
    PrintFault(IoErr(), argv[0] );
    cleanup(RETURN_ERROR);
  }

  cleanup(RETURN_OK);
  return RETURN_OK; // Make compiler happy
}
Beispiel #28
0
void main(int argc, char *argv[])
{
  BYTE *p1=buffer1,*p2=buffer2,*tmp;
  ULONG signals;

  if(AHImp=CreateMsgPort()) {
    if(AHIio=(struct AHIRequest *)CreateIORequest(AHImp,sizeof(struct AHIRequest))) {
      AHIio->ahir_Version = 4;
      AHIDevice=OpenDevice(AHINAME,0,(struct IORequest *)AHIio,NULL);
    }
  }

  if(AHIDevice) {
    Printf("Unable to open %s/0 version 4\n",AHINAME);
    cleanup(RETURN_FAIL);
  }

// Initialize the first read
  AHIio->ahir_Std.io_Command=CMD_READ;
  AHIio->ahir_Std.io_Data=&buffer1;
  AHIio->ahir_Std.io_Length=BUFFERSIZE;
  AHIio->ahir_Std.io_Offset=0;
  AHIio->ahir_Frequency=FREQUENCY;
  AHIio->ahir_Type=TYPE;
  if(!DoIO((struct IORequest *) AHIio)) {

// The first buffer is now filled
    SetIoErr(NULL);

    for(;;) {
      ULONG length;
      
      length=AHIio->ahir_Std.io_Actual;

// Initialize the second read (note that io_Offset is not cleared!)
      AHIio->ahir_Std.io_Data=p2;
      AHIio->ahir_Std.io_Length=BUFFERSIZE;
      AHIio->ahir_Frequency=FREQUENCY;
      AHIio->ahir_Type=TYPE;
      SendIO((struct IORequest *) AHIio);

// While the second read is in progress, save the first buffer to stdout
      if(Write(Output(),p1,length) != length) {
        break;
      }

      signals=Wait(SIGBREAKF_CTRL_C | (1L << AHImp->mp_SigBit));

      if(signals & SIGBREAKF_CTRL_C) {
        SetIoErr(ERROR_BREAK);
        break;
      }

// Remove the reply 
      if(WaitIO((struct IORequest *) AHIio)) {
        SetIoErr(ERROR_READ_PROTECTED);
        break;
      }

// Swap buffer pointers and repeat
      tmp=p1;
      p1=p2;
      p2=tmp;
    }

// Abort any pending iorequests
    AbortIO((struct IORequest *) AHIio);
    WaitIO((struct IORequest *) AHIio);
  }

  if(IoErr())
  {
    PrintFault(IoErr(), argv[0] ); // Oh, common! It's not MY fault that this
                                   // routine prints to stdout instead of stderr!
    cleanup(RETURN_ERROR);
  }

  cleanup(RETURN_OK);
}
Beispiel #29
0
STATIC BOOL FOGadInit(struct LayoutData *ld, struct AslBase_intern *AslBase)
{    
    struct FOUserData 	*udata = ld->ld_UserData;
    struct IntFontReq 	*iforeq = (struct IntFontReq *)ld->ld_IntReq;
    STRPTR 		str[6];
#if USE_SHARED_COOLIMAGES
    struct ButtonInfo 	bi[NUMBUTS] =
    {
        { ID_BUTOK	, GetIR(iforeq)->ir_PositiveText , MSG_FONTREQ_POSITIVE_GAD, COOL_USEIMAGE_ID    , &udata->OKBut	  },
	{ ID_BUTCANCEL  , GetIR(iforeq)->ir_NegativeText , MSG_FONTREQ_NEGATIVE_GAD, COOL_CANCELIMAGE_ID , &udata->CancelBut  }
    };
#else
    struct ButtonInfo 	bi[NUMBUTS] =
    {
        { ID_BUTOK	, GetIR(iforeq)->ir_PositiveText , MSG_FONTREQ_POSITIVE_GAD, &cool_useimage    , &udata->OKBut	  },
	{ ID_BUTCANCEL  , GetIR(iforeq)->ir_NegativeText , MSG_FONTREQ_NEGATIVE_GAD, &cool_cancelimage , &udata->CancelBut  }
    };
#endif
    Object 		*gad;
    LONG		error;
    WORD 		gadrows, x, y, w, h, i, y2;
    WORD		sizelvwidth, labelwidth = 0, maxgadcolwidth = 0;
    
    NEWLIST(&udata->NameListviewList);

    udata->SizeListviewRenderHook.h_Entry      = (APTR)AROS_ASMSYMNAME(SizeListviewRenderFunc);
    udata->SizeListviewRenderHook.h_SubEntry   = NULL;
    udata->SizeListviewRenderHook.h_Data       = AslBase;

    udata->StringEditHook.h_Entry    = (APTR)AROS_ASMSYMNAME(StringEditFunc);
    udata->StringEditHook.h_SubEntry = NULL;
    udata->StringEditHook.h_Data     = AslBase;

    FOGetFonts(ld, AslBase);
    
    error = ERROR_NO_FREE_STORE;
    
    /* calc. min. size */

    w = 0;
    for(i = 0; i < NUMBUTS; i++)
    {
    	if(!bi[i].text) bi[i].text = GetString(bi[i].deftextid, GetIR(iforeq)->ir_Catalog, AslBase);

        x = TextLength(&ld->ld_DummyRP, bi[i].text, strlen(bi[i].text));

#if FOREQ_COOL_BUTTONS
#if USE_SHARED_COOLIMAGES
    	if (CoolImagesBase)
	{
	    bi[i].coolimage = (const struct CoolImage *)COOL_ObtainImageA(bi[i].coolid, NULL);
	}
	
	if (CoolImagesBase)
#endif
	if (ld->ld_TrueColor)
	{
	    x += IMAGEBUTTONEXTRAWIDTH + bi[i].coolimage->width;
	}
#endif

	if (x > w) w = x;	
    }
    
    udata->ButWidth = w + BUTTONEXTRAWIDTH;

    ld->ld_ButWidth = udata->ButWidth;
    ld->ld_NumButtons = 4;
    
#if FOREQ_COOL_BUTTONS

#if USE_SHARED_COOLIMAGES
    if (CoolImagesBase)
    {
#endif
	y  = BUTTONEXTRAHEIGHT + ld->ld_Font->tf_YSize;
	if (ld->ld_TrueColor)
	{
            y2 = IMAGEBUTTONEXTRAHEIGHT + DEF_COOLIMAGEHEIGHT;
	} else {
            y2 = 0;
	}
	udata->ButHeight = (y > y2) ? y : y2;
#if USE_SHARED_COOLIMAGES
    }
    else
    {
    	udata->ButHeight = BUTTONEXTRAHEIGHT + ld->ld_Font->tf_YSize;
    }
#endif

#else
    udata->ButHeight = BUTTONEXTRAHEIGHT + ld->ld_Font->tf_YSize;
#endif
    
    gadrows = 2; /* button row + string gadgets under listviews */
    if (iforeq->ifo_Flags & FOF_DODRAWMODE) gadrows++;
    if (iforeq->ifo_Flags & FOF_DOSTYLE) gadrows++;
    if (iforeq->ifo_Flags & (FOF_DOFRONTPEN | FOF_DOBACKPEN)) gadrows++;
    
    ld->ld_MinWidth =  OUTERSPACINGX * 2 +
		       GADGETSPACINGX * 1 +
		       udata->ButWidth * NUMBUTS;

    ld->ld_MinHeight = OUTERSPACINGY * 2 +
		       (GADGETSPACINGY + udata->ButHeight) * gadrows +
		       BORDERLVSPACINGY * 2 +
		       (ld->ld_Font->tf_YSize + BORDERLVITEMSPACINGY * 2) * FOREQ_MIN_VISIBLELINES +
		       FONTPREVIEWHEIGHT + GADGETSPACINGY -
		       GADGETSPACINGY; /* because the string gadgets are attached to listview gadgets */

    /* make listview gadgets */
    
    sizelvwidth = PROPSIZE +
    	    	  FOREQ_VISIBILE_SIZE_CHARS * ld->ld_Font->tf_XSize +
		  BORDERLVSPACINGX * 2 +
		  BORDERLVITEMSPACINGX * 2;
    
    x = ld->ld_WBorLeft + OUTERSPACINGX;
    y = ld->ld_WBorTop + OUTERSPACINGY;
    w = -ld->ld_WBorRight - ld->ld_WBorLeft - OUTERSPACINGX * 2 - PROPSIZE - GADGETSPACINGX - sizelvwidth;
    h = -ld->ld_WBorBottom - ld->ld_WBorTop - OUTERSPACINGY * 2 -
    	udata->ButHeight * gadrows -
	GADGETSPACINGY * gadrows -
	(FONTPREVIEWHEIGHT + GADGETSPACINGY) +
	GADGETSPACINGY; /* because the string gadgets are attached to listview gadgets */
    
    {
        struct TagItem lv_tags[] = 
	{
	    {GA_Left		, x						},
	    {GA_Top		, y						},
	    {GA_RelWidth	, w						},
	    {GA_RelHeight	, h						},
	    {GA_UserData	, (IPTR)ld					},
	    {GA_ID		, ID_NAMELISTVIEW				},
	    {GA_RelVerify	, TRUE						},
	    {ASLLV_Labels	, (IPTR)&udata->NameListviewList		},
	    {TAG_IGNORE    	, 0 	    	    	    	    	    	},
	    {TAG_IGNORE     	, (IPTR)&udata->SizeListviewRenderHook	    	},
	    {ASLLV_Font     	, (IPTR)ld->ld_Font 	    	    	    	},
	    {TAG_DONE								}
	};
	
	udata->NameListview = gad = NewObjectA(AslBase->asllistviewclass, NULL, lv_tags);
	if (!gad) goto failure;

    	lv_tags[0].ti_Tag  = GA_RelRight;
	lv_tags[0].ti_Data = -ld->ld_WBorRight - OUTERSPACINGX - sizelvwidth + 1;
	lv_tags[2].ti_Tag  = GA_Width;
	lv_tags[2].ti_Data = sizelvwidth - PROPSIZE;
	lv_tags[5].ti_Data = ID_SIZELISTVIEW;
	lv_tags[7].ti_Data = 0;
	lv_tags[8].ti_Tag  = GA_Previous;
	lv_tags[8].ti_Data = (IPTR)gad;
	lv_tags[9].ti_Tag  = ASLLV_CallBack;
	
	udata->SizeListview = gad = NewObjectA(AslBase->asllistviewclass, NULL, lv_tags);
	if (!gad) goto failure;
	
    }
    
    /* make scroller gadgets for listviews */
    		       
    x = -ld->ld_WBorRight - OUTERSPACINGX - PROPSIZE - sizelvwidth - GADGETSPACINGX + 1;
    y = ld->ld_WBorTop + OUTERSPACINGY;
    w = PROPSIZE;
    h = -ld->ld_WBorBottom - ld->ld_WBorTop - OUTERSPACINGY * 2 -
    	udata->ButHeight * gadrows -
	GADGETSPACINGY * gadrows -
	(FONTPREVIEWHEIGHT + GADGETSPACINGY) +
	GADGETSPACINGY;
    {
	struct TagItem scroller_tags[] =
	{
    	    {GA_RelRight	, x		    },
	    {GA_Top		, y		    },
	    {GA_Width		, w		    },
	    {GA_RelHeight	, h		    },
	    {GA_ID		, ID_NAMELISTVIEW   },
	    {PGA_NewLook	, TRUE		    },
	    {PGA_Borderless 	, TRUE		    },
	    {PGA_Freedom	, FREEVERT	    },
	    {PGA_Top		, 0		    },
	    {PGA_Total		, 20		    },
	    {PGA_Visible	, 1		    },
	    {GA_Previous	, (IPTR)gad	    },
	    {TAG_DONE				    }
	};

	if (!makescrollergadget(&udata->NameScrollGad, ld, scroller_tags, AslBase)) goto failure;
	gad = udata->NameScrollGad.arrow2;

    	scroller_tags[0].ti_Data  = x + sizelvwidth + GADGETSPACINGX;
	scroller_tags[1].ti_Data  = y;
	scroller_tags[2].ti_Data  = w;
	scroller_tags[3].ti_Data  = h;
	scroller_tags[4].ti_Data  = ID_SIZELISTVIEW;
	scroller_tags[11].ti_Data = (IPTR)gad;
	
	if (!makescrollergadget(&udata->SizeScrollGad, ld, scroller_tags, AslBase)) goto failure;
	gad = udata->SizeScrollGad.arrow2;
	
    }

    connectscrollerandlistview(&udata->NameScrollGad, udata->NameListview, AslBase);
    connectscrollerandlistview(&udata->SizeScrollGad, udata->SizeListview, AslBase);

    /* make preview gadget */

    x = ld->ld_WBorLeft + OUTERSPACINGX;
    y = -ld->ld_WBorBottom - OUTERSPACINGY - udata->ButHeight - 
    	GADGETSPACINGY - FONTPREVIEWHEIGHT;
    w = -ld->ld_WBorRight - ld->ld_WBorLeft - OUTERSPACINGX * 2;

    {
    	struct TagItem preview_tags[] =
	{
	    {GA_Left	    	, x 	    	    	    	    },
	    {GA_RelBottom   	, y 	    	    	    	    },
	    {GA_RelWidth    	, w 	    	    	    	    },
	    {GA_Height	    	, FONTPREVIEWHEIGHT  	    	    },
	    {GA_Previous    	, (IPTR)gad 	    	    	    },
	    {GA_ID  	    	, ID_PREVIEW     	    	    },
	    {ASLFP_SampleText	, (IPTR)iforeq->ifo_SampleText	    },
	    {ASLFP_APen     	, iforeq->ifo_FrontPen	    	    },
	    {ASLFP_BPen     	, iforeq->ifo_BackPen	    	    },
	    {TAG_DONE	    	    	    	    	    	    }
	};

	udata->Preview = gad = NewObjectA(AslBase->aslfontpreviewclass, NULL, preview_tags);
	if (!gad) goto failure;
    }
    
    /* make string gadgets */

    x = ld->ld_WBorLeft + OUTERSPACINGX;
    y = -ld->ld_WBorBottom - OUTERSPACINGY - udata->ButHeight - 
    	(udata->ButHeight + GADGETSPACINGY) * (gadrows - 1) -
	(FONTPREVIEWHEIGHT + GADGETSPACINGY) + 1;
		
    w = -ld->ld_WBorRight - ld->ld_WBorLeft - OUTERSPACINGX * 2 - GADGETSPACINGX - sizelvwidth;
    
    {
    	struct TagItem string_tags[] =
	{
	    {GA_Left	    	, x 	    	    	    	    },
	    {GA_RelBottom   	, y 	    	    	    	    },
	    {GA_RelWidth    	, w 	    	    	    	    },
	    {GA_Height	    	, udata->ButHeight  	    	    },
	    {GA_Previous    	, (IPTR)gad 	    	    	    },
	    {STRINGA_TextVal	, (IPTR)""     	    	    	    },
	    {STRINGA_MaxChars	, MAXFONTNAME 	    	    	    },
	    {STRINGA_EditHook	, (IPTR)&udata->StringEditHook	    },
	    {GA_ID  	    	, ID_NAMESTRING     	    	    },
	    {GA_RelVerify   	, TRUE	    	    	    	    },
	    {GA_UserData    	, (IPTR)ld  	    	    	    },
	    {GA_TabCycle    	, TRUE	    	    	    	    },
	    {STRINGA_Font   	, (IPTR)ld->ld_Font 	    	    },
	    {TAG_DONE	    	    	    	    	    	    }
	};

	udata->NameString = gad = NewObjectA(AslBase->aslstringclass, NULL, string_tags);
	if (!gad) goto failure;
	
   	string_tags[0].ti_Tag  = GA_RelRight;
	string_tags[0].ti_Data = -ld->ld_WBorRight - OUTERSPACINGX - sizelvwidth + 1;
	string_tags[2].ti_Tag  = GA_Width;
	string_tags[2].ti_Data = sizelvwidth;
	string_tags[4].ti_Data = (IPTR)gad;
	string_tags[5].ti_Tag  = STRINGA_LongVal;
	string_tags[5].ti_Data = iforeq->ifo_TextAttr.ta_YSize;
	string_tags[6].ti_Data = 6;
	string_tags[8].ti_Data = ID_SIZESTRING;

	udata->SizeString = gad = NewObjectA(AslBase->aslstringclass, NULL, string_tags);
	if (!gad) goto failure;
	
    }
    
    /* make button row */
    
    y = -ld->ld_WBorBottom - OUTERSPACINGY - udata->ButHeight + 1;
    
    {
        struct TagItem button_tags[] =
	{
	    {GA_Text		, 0			},
	    {GA_Previous	, 0			},
	    {GA_ID		, 0			},
#if FOREQ_COOL_BUTTONS
	    {ASLBT_CoolImage	, 0			},
#else
	    {TAG_IGNORE		, 0			},
#endif	    
	    {GA_UserData	, (IPTR)ld		},
	    {GA_Left		, 0			},
	    {GA_RelBottom	, y			},
	    {GA_Width		, udata->ButWidth	},
	    {GA_Height		, udata->ButHeight	},
	    {GA_RelVerify	, TRUE			},
	    {GA_Image		, 0			}, /* means we want a frame */
	    {TAG_DONE					}
	};

	for(i = 0; i < NUMBUTS; i++)
	{
	    button_tags[0].ti_Data = (IPTR)bi[i].text;
	    button_tags[1].ti_Data = (IPTR)gad;
	    button_tags[2].ti_Data = bi[i].gadid;
	#if USE_SHARED_COOLIMAGES
	    if (CoolImagesBase == NULL) button_tags[3].ti_Tag = TAG_IGNORE;
	#endif
	    button_tags[3].ti_Data = (IPTR)bi[i].coolimage;

	    *(bi[i].objvar) = gad = NewObjectA(AslBase->aslbuttonclass, NULL, button_tags);
	    if (!gad) goto failure;
	}
	 	 
    }	 
    
    /* make labels */
        
    i = 0;

    x = ld->ld_WBorLeft + OUTERSPACINGX;
    y = -ld->ld_WBorBottom - OUTERSPACINGY - udata->ButHeight - 
    	(udata->ButHeight + GADGETSPACINGY) * (gadrows - 2) -
	(FONTPREVIEWHEIGHT + GADGETSPACINGY) + 1;

    if (iforeq->ifo_Flags & (FOF_DODRAWMODE | FOF_DOSTYLE | FOF_DOFRONTPEN | FOF_DOBACKPEN))
    {
        #define FSET(x) ((iforeq->ifo_Flags & x) ? TRUE : FALSE)
	
        struct LabelInfo
	{
	    BOOL doit;
	    char *text;
	    Object **objvar;
	} li [] =
	{
	    {FSET(FOF_DOSTYLE)	    , (STRPTR)MSG_FONTREQ_STYLE_LABEL 	, &udata->StyleLabel     },
	    {FALSE  	    	    , (STRPTR)MSG_FONTREQ_COLOR_LABEL_FG, &udata->ColorLabel	 },
	    {FSET(FOF_DODRAWMODE)   , (STRPTR)MSG_FONTREQ_MODE_LABEL  	, &udata->DrawModeLabel  }
	}; 

        #undef FSET
	
        struct TagItem label_tags[] =
	{
	    {GA_Left		, 0			},
	    {GA_RelBottom	, y			},
	    {GA_Width		, 0			},
	    {GA_Height		, udata->ButHeight	},
	    {GA_Text		, 0			},
	    {GA_Previous	, (IPTR)gad		},
	    {GA_UserData	, (IPTR)ld		},
	    {GA_Disabled	, TRUE			},
	    {TAG_DONE					}
	};
    	WORD i2;
	
	if (iforeq->ifo_Flags & (FOF_DOFRONTPEN | FOF_DOBACKPEN))
	{
	    li[1].doit = TRUE;
	    
	    switch(iforeq->ifo_Flags & (FOF_DOFRONTPEN | FOF_DOBACKPEN))
	    {
	    	case FOF_DOFRONTPEN:
		    break;
		    
		case FOF_DOBACKPEN:
		    li[1].text = (STRPTR)MSG_FONTREQ_COLOR_LABEL_BG;
		    break;
		    
		case FOF_DOFRONTPEN | FOF_DOBACKPEN:
		    li[1].text = (STRPTR)MSG_FONTREQ_COLOR_LABEL_FGBG;
		    break;
	    }
	    
	} /* if (iforeq->ifo_Flags & (FOF_DOFRONTPEN | FOF_DOBACKPEN)) */
    	for(i = 0, i2 = 0; i < 3; i++)
	{
	    if (li[i].doit)
	    {
	    	if ((i == 2) && (iforeq->ifo_ModeList))
		{
		    li[i].text = iforeq->ifo_ModeList[0];
		}
		else
		{
	    	    li[i].text = GetString((LONG)li[i].text, GetIR(iforeq)->ir_Catalog, AslBase);
		}
		str[i2++] = li[i].text;
	    }
	}
		
	w = labelwidth = BiggestTextLength(str, i2, &(ld->ld_DummyRP), AslBase);
            
	for(i = 0; i < 3;i++)
	{
	    if (!li[i].doit) continue;
	    
	    label_tags[2].ti_Data = TextLength(&ld->ld_DummyRP, li[i].text, strlen(li[i].text));
	    label_tags[0].ti_Data = x + w - label_tags[2].ti_Data;
	    label_tags[4].ti_Data = (IPTR)li[i].text;
	    label_tags[5].ti_Data = (IPTR)gad;
	    
	    *(li[i].objvar) = gad = NewObjectA(AslBase->aslbuttonclass, NULL, label_tags);
	    if (!gad) goto failure;
	    
	    y += udata->ButHeight + GADGETSPACINGY;
	    label_tags[1].ti_Data = y;
	}	

    	y = -ld->ld_WBorBottom - OUTERSPACINGY - udata->ButHeight - 
    	    (udata->ButHeight + GADGETSPACINGY) * (gadrows - 2) -
	    (FONTPREVIEWHEIGHT + GADGETSPACINGY) + 1;
	    
	x = ld->ld_WBorLeft + OUTERSPACINGX + w + LABELSPACINGX;

    	/* Make Style gadget */
	
	if (iforeq->ifo_Flags & FOF_DOSTYLE)
	{
	    STRPTR stylestrings[3];
	    
	    struct TagItem style_tags[] =
	    {
	        {GA_Previous		, (IPTR)gad			  },
		{GA_Left		, x				  },
		{GA_RelBottom		, y				  },
		{GA_Width		, 0				  },
		{GA_Height		, udata->ButHeight		  },
		{GA_RelVerify		, TRUE				  },
		{GA_UserData		, (IPTR)ld			  },
		{GA_ID			, ID_STYLE			  },
		{ASLFS_LabelArray    	, (IPTR)stylestrings	    	  },
		{ASLFS_Style		, iforeq->ifo_TextAttr.ta_Style	  },
		{TAG_DONE						  }
	    };

    	    stylestrings[0] = GetString(MSG_FONTREQ_STYLE_BOLD, GetIR(iforeq)->ir_Catalog, AslBase);
    	    stylestrings[1] = GetString(MSG_FONTREQ_STYLE_ITALIC, GetIR(iforeq)->ir_Catalog, AslBase);
    	    stylestrings[2] = GetString(MSG_FONTREQ_STYLE_UNDERLINED, GetIR(iforeq)->ir_Catalog, AslBase);
	    
	    w = BiggestTextLength(stylestrings, 3, &(ld->ld_DummyRP), AslBase);
	    w *= 2;
	    w *= 3;
	    
	    style_tags[3].ti_Data = w;
	    
	    if (w > maxgadcolwidth) maxgadcolwidth = w;
	    
	    udata->StyleGadget = gad = NewObjectA(AslBase->aslfontstyleclass, NULL, style_tags);
	    if (!gad) goto failure;
	    
	    y += udata->ButHeight + GADGETSPACINGY;
	    
	}
	
	w = udata->ButHeight * 12 / 10 + 19; /* CYCLEIMAGEWIDTH = 19 */
	
	/* Make FrontPen gadget */
	
	if (iforeq->ifo_Flags & FOF_DOFRONTPEN)
	{
	    struct TagItem cp_tags[] =
	    {
	        {GA_Previous		, (IPTR)gad			  },
		{GA_Left		, x				  },
		{GA_RelBottom		, y				  },
		{GA_Width		, w				  },
		{GA_Height		, udata->ButHeight		  },
		{GA_RelVerify		, TRUE				  },
		{GA_UserData		, (IPTR)ld			  },
		{GA_ID			, ID_FRONTPEN			  },
		{ASLCP_Color	    	, iforeq->ifo_FrontPen	    	  },
		{ASLCP_ColorTable   	, (IPTR)iforeq->ifo_FrontPens     },
		{ASLCP_NumColors    	, iforeq->ifo_MaxFrontPen   	  },
		{TAG_DONE						  }
		
	    };
	    
	    udata->FGColorGadget = gad = NewObjectA(AslBase->aslcolorpickerclass, NULL, cp_tags);
	    if (!gad) goto failure;
	    
	    x += w + GADGETSPACINGX;
	}

    	/* Make BackPen gadget */
	
	if (iforeq->ifo_Flags & FOF_DOBACKPEN)
	{
	    struct TagItem cp_tags[] =
	    {
	        {GA_Previous		, (IPTR)gad			  },
		{GA_Left		, x				  },
		{GA_RelBottom		, y				  },
		{GA_Width		, w				  },
		{GA_Height		, udata->ButHeight		  },
		{GA_RelVerify		, TRUE				  },
		{GA_UserData		, (IPTR)ld			  },
		{GA_ID			, ID_BACKPEN			  },
		{ASLCP_Color	    	, iforeq->ifo_BackPen	    	  },
		{ASLCP_ColorTable   	, (IPTR)iforeq->ifo_BackPens      },
		{ASLCP_NumColors    	, iforeq->ifo_MaxBackPen   	  },
		{TAG_DONE						  }
		
	    };
	    
	    udata->BGColorGadget = gad = NewObjectA(AslBase->aslcolorpickerclass, NULL, cp_tags);
	    if (!gad) goto failure;
	    
	}

    	if (iforeq->ifo_Flags & (FOF_DOFRONTPEN | FOF_DOBACKPEN))
	{
	    if ((iforeq->ifo_Flags & (FOF_DOFRONTPEN | FOF_DOBACKPEN)) == (FOF_DOFRONTPEN | FOF_DOBACKPEN))
	    {
	    	w += GADGETSPACINGX + w;
	    }
	    
	    if (w > maxgadcolwidth) maxgadcolwidth = w;
	    
	    y += udata->ButHeight + GADGETSPACINGY;
	}
	
	
    	/* Make DrawMode gadget */

	x = ld->ld_WBorLeft + OUTERSPACINGX + labelwidth + LABELSPACINGX;

	w = -ld->ld_WBorLeft - ld->ld_WBorRight - OUTERSPACINGX * 2 -
            labelwidth - LABELSPACINGX;

	
	if (iforeq->ifo_Flags & FOF_DODRAWMODE)
	{
	    struct TagItem cycle_tags[] =
	    {
	        {GA_Previous		, (IPTR)gad			  },
		{GA_Left		, x				  },
		{GA_RelBottom		, y				  },
		{GA_RelWidth		, w				  },
		{GA_Height		, udata->ButHeight		  },
		{GA_RelVerify		, TRUE				  },
		{GA_UserData		, (IPTR)ld			  },
		{GA_ID			, ID_DRAWMODE			  },
		{ASLCY_Labels		, 0 	    	    	    	  },
		{ASLCY_Active		, iforeq->ifo_DrawMode	    	  },
		{ASLCY_Font 	    	, (IPTR)ld->ld_Font 	    	  },
		{TAG_DONE						  }
		
	    };
	    static LONG labelids[] =
	    {
		MSG_FONTREQ_MODE_TEXT,
		MSG_FONTREQ_MODE_TEXTANDFIELD,
		MSG_FONTREQ_MODE_COMPLEMENT,
	    };
	    STRPTR *labels;
	    
	    
	    if (iforeq->ifo_ModeList)
	    {
	    	labels = &iforeq->ifo_ModeList[1];
	    }
	    else
	    {
    	    	labels = (STRPTR *)&iforeq->ifo_DrawModeJAM1Text;
	    	
    		for(i = 0; i < 3; i++)
		{
	    	    labels[i] = GetString(labelids[i], GetIR(iforeq)->ir_Catalog, AslBase);
		}
	    }
	    
	    cycle_tags[8].ti_Data = (IPTR)labels;
	    
	    i = CYCLEEXTRAWIDTH +  BiggestTextLength(labels,
	    					     0x7FFF,
						     &(ld->ld_DummyRP),
						     AslBase);						     
	    if (i > maxgadcolwidth) maxgadcolwidth = i;
	    
	    udata->DrawModeGadget = gad = NewObjectA(AslBase->aslcycleclass, NULL, cycle_tags);
	    if (!gad) goto failure;
	    
	    y += udata->ButHeight + GADGETSPACINGY;
	    
	} /* if (iforeq->ifo_Flags & FOF_DODRAWMODE) */
		
    } /* if (iforeq->ifo_Flags & (FOF_DODRAWMODE | FOF_DOSTYLE | FOF_DOFRONTPEN | FOF_DOBACKPEN)) */

#if AVOID_FLICKER
    {
    	struct TagItem eraser_tags[] =
	{
	    {GA_Previous, (IPTR)gad},
	    {TAG_DONE}
	};
	
	udata->EraserGadget = gad = NewObjectA(AslBase->asleraserclass, NULL, eraser_tags);
	/* Doesn't matter if this failed */
    }
#endif
    
    w = OUTERSPACINGX + labelwidth + LABELSPACINGX + maxgadcolwidth + OUTERSPACINGX;
    if (w > ld->ld_MinWidth) ld->ld_MinWidth = w;
    
    ld->ld_GList = (struct Gadget *)udata->NameListview;							 
    
    /* Menus */
    {
        struct NewMenu nm[] =
	{
	    {NM_TITLE, (STRPTR)MSG_FONTREQ_MEN_CONTROL							},
	     {NM_ITEM, (STRPTR)MSG_FONTREQ_MEN_CONTROL_LASTFONT , 0, 0, 0, (APTR)FOMEN_LASTFONT		},
	     {NM_ITEM, (STRPTR)MSG_FONTREQ_MEN_CONTROL_NEXTFONT , 0, 0, 0, (APTR)FOMEN_NEXTFONT 	},
	     {NM_ITEM, NM_BARLABEL									},
	     {NM_ITEM, (STRPTR)MSG_FONTREQ_MEN_CONTROL_RESTORE	, 0, 0, 0, (APTR)FOMEN_RESTORE 		},
	     {NM_ITEM, (STRPTR)MSG_FONTREQ_MEN_CONTROL_RESCAN	, 0, 0, 0, (APTR)FOMEN_RESCAN		},
	     {NM_ITEM, NM_BARLABEL									},
	     {NM_ITEM, (STRPTR)MSG_FONTREQ_MEN_CONTROL_OK   	, 0, 0, 0, (APTR)FOMEN_OK		},
	     {NM_ITEM, (STRPTR)MSG_FONTREQ_MEN_CONTROL_CANCEL	, 0, 0, 0, (APTR)FOMEN_CANCEL		},
	    {NM_END																}
	};

	struct TagItem menu_tags[] =
	{
	    {GTMN_NewLookMenus  , TRUE  	    	    	    },
	    {GTMN_TextAttr	, (IPTR)GetIR(iforeq)->ir_TextAttr  },
	    {TAG_DONE   	    	    	    	    	    }
	};
	
	if (menu_tags[1].ti_Data == 0) menu_tags[1].ti_Tag = TAG_IGNORE;

	LocalizeMenus(nm, GetIR(iforeq)->ir_Catalog, AslBase);

	/* Don't fail, if menus cannot be created/layouted, because a requester
	   without menus is still better than no requester at all */
	   
	if ((ld->ld_Menu = CreateMenusA(nm, NULL)))
	{
	    if (!LayoutMenusA(ld->ld_Menu, ld->ld_VisualInfo, menu_tags))
	    {
	        FreeMenus(ld->ld_Menu);ld->ld_Menu = NULL;
	    }
	}
    }
    
    FORestore(ld, iforeq->ifo_TextAttr.ta_Name, iforeq->ifo_TextAttr.ta_YSize,  AslBase);
    
    SetIoErr(0);
    ReturnBool ("FOGadInit", TRUE);
    
failure:
    SetIoErr(error);
    
    D(bug("failure\n"));

    FOGadCleanup(ld, ASLB(AslBase));

    ReturnBool ("FOGadInit", FALSE);

}