home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / fm2000 / fmdos.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-04  |  14.4 KB  |  639 lines

  1. /*
  2.      Filemaster - Multitasking directory utility.
  3.      Copyright (C) 2000  Toni Wilen
  4.      
  5.      This program is free software; you can redistribute it and/or
  6.      modify it under the terms of the GNU General Public License
  7.      as published by the Free Software Foundation; either version 2
  8.      of the License, or (at your option) any later version.
  9.      
  10.      This program is distributed in the hope that it will be useful,
  11.      but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.      GNU General Public License for more details.
  14.      
  15.      You should have received a copy of the GNU General Public License
  16.      along with this program; if not, write to the Free Software
  17.      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19.  
  20.  
  21. #include <exec/types.h>
  22. #include <exec/memory.h>
  23. #include <dos/dosextens.h>
  24. #include <proto/all.h>
  25. #include <proto/xfdmaster.h>
  26. #include <libraries/xfdmaster.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include "fmdos.h"
  30. #include "fmnode.h"
  31. #include "fmlocale.h"
  32.  
  33. extern struct FMConfig *fmconfig;
  34. extern UBYTE nformatstring[];
  35. extern struct FMMain fmmain;
  36. extern UBYTE pplib[];
  37.  
  38. WORD xfddecrunch(struct FMHandle *h,struct xfdBufferInfo *xfdbi)
  39. {
  40. UBYTE *obuf;
  41.  
  42. obuf=xfdbi->xfdbi_SourceBuffer;
  43. if(xfdbi->xfdbi_SourceBuffer=allocvec(h->owner,h->size,0)) {
  44.     CopyMem(obuf,xfdbi->xfdbi_SourceBuffer,xfdbi->xfdbi_SourceBufLen);
  45.     freemem(obuf);
  46.     if(readbufferfile(h,(UBYTE*)xfdbi->xfdbi_SourceBuffer+xfdbi->xfdbi_SourceBufLen,h->size-xfdbi->xfdbi_SourceBufLen)==h->size-xfdbi->xfdbi_SourceBufLen) {
  47.         xfdbi->xfdbi_SourceBufLen=h->size;
  48.         xfdbi->xfdbi_TargetBufMemType=MEMF_PUBLIC;
  49.         sformat(h->owner->fmmessage1,getstring(MSG_FMDOS_DECRUNCHING),xfdbi->xfdbi_PackerName,h->filename);
  50.         h->owner->fmmessage2[0]=0;
  51.         fmmessage(h->owner);
  52.         if(xfdRecogBuffer(xfdbi)) {
  53.             if(xfdDecrunchBuffer(xfdbi)) {
  54.                 h->owner->fmmessage1[0]=0;
  55.                 h->owner->fmmessage2[0]=0;
  56.                 fmmessage(h->owner);
  57.                 h->flags|=OFDECRUNCH;
  58.                 h->decbuffer=xfdbi->xfdbi_TargetBuffer;
  59.                 h->decbufsize=xfdbi->xfdbi_TargetBufLen;
  60.                 h->size=xfdbi->xfdbi_TargetBufSaveLen;
  61.                 h->position=0;
  62.                 freemem(xfdbi->xfdbi_SourceBuffer);
  63.                 xfdFreeObject(xfdbi);
  64.                 return(1);
  65.             }
  66.         }
  67.     }
  68. }
  69. if(xfdbi->xfdbi_SourceBuffer) freemem(xfdbi->xfdbi_SourceBuffer);
  70. xfdFreeObject(xfdbi);
  71. return(0);
  72. }
  73.  
  74. struct xfdBufferInfo *xfdtest(struct FMHandle *h)
  75. {
  76. struct xfdBufferInfo *xfdbi;
  77. UBYTE *recbuf;
  78. LONG recbuflen;
  79. WORD ret=0;
  80.  
  81. xfdbi=xfdAllocObject(XFDOBJ_BUFFERINFO);
  82. if(xfdbi) {
  83.     recbuflen=xfdMasterBase->xfdm_MinBufferSize;
  84.     if(h->size<recbuflen) recbuflen=h->size;
  85.     xfdbi->xfdbi_SourceBufLen=recbuflen;
  86.     recbuf=allocvec(h->owner,recbuflen,0);
  87.     xfdbi->xfdbi_SourceBuffer=recbuf;
  88.     xfdbi->xfdbi_Flags|=XFDPFF_EXTERN;
  89.     if(xfdbi->xfdbi_SourceBuffer) {
  90.         if(readbufferfile(h,recbuf,recbuflen)==recbuflen) {
  91.             if(xfdRecogBuffer(xfdbi)) ret=1;
  92.         }
  93.     }
  94.     if(!ret) {
  95.         if(xfdbi->xfdbi_SourceBuffer) freemem(xfdbi->xfdbi_SourceBuffer);
  96.         xfdFreeObject(xfdbi);
  97.         xfdbi=0;
  98.     }
  99. }
  100. if(!xfdbi) seek(h,0,OFFSET_BEGINNING);
  101. return(xfdbi);
  102. }
  103.  
  104.  
  105. LONG fmread(struct FMHandle *h,void *buffer,LONG size)
  106. {
  107. return(Read(h->handle,buffer,size));
  108. }
  109.  
  110. LONG seek(struct FMHandle *h,LONG p,LONG mode)
  111. {
  112. LONG ret,ret2;
  113.  
  114. if (h->flags&OFDECRUNCH) {
  115.     ret=h->position;
  116.     switch(mode)
  117.     {
  118.         case OFFSET_CURRENT:
  119.         h->position+=p;
  120.         break;
  121.         case OFFSET_BEGINNING:
  122.         h->position=p;
  123.         break;
  124.         case OFFSET_END:
  125.         h->position=h->size+p;
  126.         break;
  127.     }
  128.     if (h->position<0||h->position>h->size) ret=-1;
  129. } else {
  130.     ret=Seek(h->handle,p,mode);
  131.     if(ret>=0) ret2=Seek(h->handle,0,OFFSET_CURRENT);
  132.     if (ret<0||ret2<0) {
  133.         dosrequestmsg(h->owner,0,MSG_FMDOS_SEEKERR,h->filename);
  134.     } else {
  135.         h->position=ret2;
  136.     }
  137. }
  138. return(ret);
  139. }
  140.  
  141.  
  142. LONG readbufferfile(struct FMHandle *handle,void *buffer,LONG len)
  143. {
  144. LONG ret=-1;
  145. LONG len2;
  146. LONG oldseek;
  147. UBYTE *src,*dst;
  148.  
  149. oldseek=handle->position;
  150. rretry:
  151. if(handle->size-handle->position>=len) {
  152.     if (handle->flags&OFDECRUNCH) {
  153.         src=handle->decbuffer+handle->position;
  154.         dst=(UBYTE*)buffer;
  155.         len2=len; ret=0;
  156.         while(len2&&handle->position<handle->size) {
  157.             *dst++=*src++;
  158.             len2--;
  159.             ret++;
  160.         }
  161.         handle->position+=ret;
  162.     } else {
  163.         ret=fmread(handle,buffer,len);
  164.         if (ret==-1) {
  165.             if(dosrequestmsg(handle->owner,1,MSG_FMDOS_READERR,handle->filename)) {
  166.                 if(seek(handle,oldseek,OFFSET_BEGINNING)>=0) goto rretry;
  167.             }
  168.             return(ret);
  169.         } else {
  170.             handle->position+=ret;
  171.         }
  172.     }
  173. }
  174. if (ret!=len) {
  175.     requestmsg(handle->owner->workname,0,MSG_OK,MSG_FMDOS_UEOF,handle->filename);
  176.     ret=0;
  177. }
  178. return(ret);
  179. }
  180.  
  181. LONG readfile(struct FMHandle *handle)
  182. {
  183. LONG ret;
  184. LONG oldseek;
  185.  
  186. oldseek=handle->position;
  187. rretry:
  188. ret=fmread(handle,handle->buffer,handle->bufsize);
  189. if (ret==-1) {
  190.     if(dosrequestmsg(handle->owner,1,MSG_FMDOS_READERR,handle->filename)) {
  191.         if(seek(handle,oldseek,OFFSET_BEGINNING)>=0) goto rretry;
  192.     }
  193.     return(ret);
  194. }
  195. handle->position+=ret;
  196. return(ret);
  197. }
  198.  
  199. LONG writefile(struct FMHandle *handle,void *buffer,LONG size)
  200. {
  201. LONG ret;
  202. LONG oldseek;
  203.  
  204. oldseek=handle->position;
  205. wretry:
  206. if (handle->flags&OFDECRUNCH) {
  207.     ret=-1;
  208. } else {
  209.     ret=Write(handle->handle,buffer,size);
  210.     if (ret==-1||ret!=size) {
  211.         if(dosrequestmsg(handle->owner,1,MSG_FMDOS_WRITEERR,handle->filename)) {
  212.             if(seek(handle,oldseek,OFFSET_BEGINNING)>=0) goto wretry;
  213.         }
  214.     } else {
  215.         handle->position+=size;
  216.     }
  217. }
  218. return(ret);
  219. }
  220.  
  221. struct FMHandle* openfile(struct FMList *list,UBYTE *name,ULONG flags)
  222. {
  223. struct FMHandle *handle=0;
  224. struct FileInfoBlock *fib=0;
  225. struct xfdBufferInfo *xfdbi;
  226. ULONG bufsize;
  227. WORD retry;
  228.  
  229. if (!currentdir(list)) return(0);
  230.  
  231. oretry:
  232. retry=0;
  233. if (!(handle=(struct FMHandle*)AllocVec(sizeof(struct FMHandle),MEMF_CLEAR|MEMF_PUBLIC))) goto ofile1;
  234. handle->path=list->path;
  235. handle->owner=list;
  236. handle->filename=name;
  237. bufsize=fmconfig->dosbuffersize&0x00ffffff;
  238. if(flags&OFBUFFER) {
  239.     bufsize=flags&~OFBUFFER;
  240.     flags=OFBUFFER|OFRELAXED;
  241. }
  242. if (flags&OFWRITE) {
  243.     if (!(handle->handle=Open(name,1006))) {
  244.         retry=dosrequestmsg(list,1,MSG_FMDOS_OPENWERR,name);
  245.         goto ofile1;
  246.     }
  247. handle->flags|=OFWRITE;
  248. return(handle);
  249. }
  250. if (!(flags&OFFAKE)) {
  251.     if (!(handle->handle=Open(name,1005))) {
  252.         retry=dosrequestmsg(list,1,MSG_FMDOS_OPENRERR,name);
  253.         goto ofile1;
  254.     }
  255.     if (!(fib=AllocVec(sizeof(struct FileInfoBlock),MEMF_CLEAR))) goto ofile1;
  256.     if (!fmexaminefile(list,fib,name)) goto ofile1;
  257.     handle->size=fib->fib_Size;
  258.     handle->date=dstolong(&fib->fib_Date);
  259.     freemem(fib); fib=0;
  260. }
  261.  
  262. if (flags&OFNORMAL) {
  263.     handle->bufsize=bufsize;
  264.     handle->buffer=AllocVec(handle->bufsize,MEMF_CLEAR|MEMF_PUBLIC);
  265.     handle->flags|=OFNORMAL;
  266. } else if (flags&OFBUFFER) {
  267.     for(;;) {
  268.         if(bufsize<handle->size&&bufsize<4000) break;
  269.         handle->bufsize=bufsize;
  270.         if ((handle->buffer=AllocVec(bufsize,MEMF_CLEAR|MEMF_PUBLIC))) break;
  271.         bufsize/=2;
  272.     }
  273. }
  274. if (!handle->buffer) {
  275.     retry=requestmsg(list->workname,MSG_RETRY,MSG_CANCEL,MSG_FMDOS_NOBUFMEM);
  276.     goto ofile1;
  277. }
  278. if(!(flags&OFFAKE)) {
  279.     if (handle->size==0&&!(flags&OFRELAXED)) {
  280.         requestmsg(list->workname,0,MSG_OK,MSG_FMDOS_ZEROSIZE,handle->filename);
  281.         goto ofile1;
  282.     }
  283.     if (flags&OFDECRUNCH&&handle->size&&xfdMasterBase) {
  284.         if(xfdbi=xfdtest(handle)) {
  285.             if(!xfddecrunch(handle,xfdbi)) goto ofile1;
  286.         }
  287.     }
  288. } else {
  289.     handle->flags|=OFDECRUNCH|OFFAKE;
  290. }
  291. return(handle);
  292. ofile1:
  293. freemem(fib);
  294. closefile(handle);
  295. if(retry) goto oretry;
  296. return(0);
  297. }
  298.  
  299. void closefile(struct FMHandle *handle)
  300. {
  301. if (!handle) return;
  302. if (handle->flags&OFDECRUNCH&&!(handle->flags&OFFAKE)) FreeMem(handle->decbuffer,handle->decbufsize);
  303. freemem(handle->buffer);
  304. if (handle->handle) Close(handle->handle);
  305. freemem(handle);
  306. }
  307.  
  308. WORD fmexaminefile(struct FMList *list,struct FileInfoBlock *fib,UBYTE *name)
  309. {
  310. BPTR lock;
  311. WORD ret;
  312.  
  313. if (!(lock=fmlock(list,name))) return(0);
  314. ret=fmexamine(list,lock,fib,name);
  315. UnLock(lock);
  316. return(ret);
  317. }
  318.  
  319. WORD fmexamine(struct FMList *list,BPTR lock,struct FileInfoBlock *fib,UBYTE *name)
  320. {
  321. do {
  322.     if (Examine(lock,fib)) return(1);
  323. } while(dosrequestmsg(list,1,MSG_FMDOS_EXAMINEERR,name));
  324. return(0);
  325. }
  326.  
  327. WORD fmexnext(struct FMList *list,BPTR lock,struct FileInfoBlock *fib)
  328. {
  329. struct FileInfoBlock vfib;
  330.  
  331. CopyMem(fib,&vfib,sizeof(struct FileInfoBlock));
  332. do {
  333.     CopyMem(&vfib,fib,sizeof(struct FileInfoBlock));
  334.     if (ExNext(lock,fib)) return(1);
  335.     if(checkdoserr()==232) return(0);
  336. } while(dosrequestmsg(list,1,MSG_FMDOS_EXNEXTERR));
  337. return(-1);
  338. }
  339. BPTR fmlock(struct FMList *list,UBYTE *name)
  340. {
  341. BPTR lock;
  342.  
  343. if(name!=list->path) if(!currentdir(list)) return(0);
  344. do {
  345.     if ((lock=Lock(name,SHARED_LOCK))) return(lock);
  346. } while(dosrequestmsg(list,1,MSG_FMDOS_LOCKERR,name));
  347. return(0);
  348. }
  349.  
  350. WORD currentdir(struct FMList *list)
  351. {
  352. BPTR lock;
  353. BPTR curri;
  354.  
  355. if (!(lock=Lock(list->path,SHARED_LOCK))) return(0);
  356. curri=CurrentDir(lock);
  357. if (list->pair) {
  358.     if (list->flags&LSUBPROC) {
  359.         if(list->oldcur==1) { list->oldcur=curri; curri=0; }
  360.         goto curend;
  361.     }
  362.     if (list->pair->flags&LSUBPROC) { 
  363.         if(list->pair->oldcur==1) { list->pair->oldcur=curri; curri=0; }
  364.         goto curend;
  365.     }
  366. }
  367. if (list->flags&LSUBPROC) {
  368.     if (list->oldcur==1) { list->oldcur=curri; curri=0; }
  369.     goto curend;
  370. }
  371. if (!(list->flags&LSUBPROC)) {
  372.     if (fmmain.oldcur==1) { fmmain.oldcur=curri; curri=0; }
  373. }
  374. curend:
  375. UnLock(curri);
  376. return(1);
  377. }
  378.  
  379. WORD fmsetrename(struct FMList *list,UBYTE *oldname,UBYTE *newname)
  380. {
  381. if(!currentdir(list)) return(0);
  382. do {
  383.     if(Rename(oldname,newname)) return(1);
  384. } while(dosrequestmsg(list,1,MSG_FMDOS_RENAMEERR,oldname));
  385. return(0);
  386. }
  387. WORD fmrename(struct FMList *list,struct FMNode *node,UBYTE *name)
  388. {
  389. if (strcmp(NDFILE(node),name)) {
  390.     if(fmsetrename(list,NDFILE(node),name)) {
  391.         siirran(NDFILE(node),name,fmmain.filelen);
  392.         return(1);
  393.     }
  394.     return(0);
  395. }
  396. return(1);
  397. }
  398.  
  399. WORD fmsetfiledate(struct FMList *list,UBYTE *name,struct DateStamp *ds)
  400. {
  401. if(!currentdir(list)) return(0);
  402. do {
  403.     if(SetFileDate(name,ds)) return(1);
  404. } while(dosrequestmsg(list,1,MSG_FMDOS_DATEERR,name));
  405. return(0);
  406. }
  407. WORD fmfiledate(struct FMList *list,struct FMNode *node,ULONG date)
  408. {
  409. struct DateStamp ds;
  410. UBYTE dstring[32];
  411.  
  412. if(date==0xffffffff) return(1);
  413. longtodatestring(dstring,node->numdate);
  414. if(datestringtolong(dstring)!=date) {
  415.     longtods(&ds,date);
  416.     if(fmsetfiledate(list,NDFILE(node),&ds)) {
  417.         node->numdate=date;
  418.         longtodatestring(NDDATE(node),date);
  419.         return(1);
  420.     }
  421.     return(0);
  422. }
  423. return(1);
  424. }
  425.  
  426. WORD fmsetcomment(struct FMList *list,UBYTE *name,UBYTE *comm)
  427. {
  428. if(!currentdir(list)) return(0);
  429. do {
  430.     if (SetComment(name,comm)) return(1);
  431. } while(dosrequestmsg(list,1,MSG_FMDOS_COMMENTERR,name));
  432. return(0);
  433. }
  434. WORD fmcomment(struct FMList *list,struct FMNode *node,UBYTE *comm)
  435. {
  436. if (strcmp(NDCOMM(node),comm)) {
  437.     if(fmsetcomment(list,NDFILE(node),comm)) {
  438.         siirran(NDCOMM(node),comm,fmmain.commlen);
  439.         return(1);
  440.     }
  441.     return(0);
  442. }
  443. return(1);
  444. }
  445.  
  446. WORD fmsetprotection(struct FMList *list,UBYTE *name,ULONG prot)
  447. {
  448. if(!currentdir(list)) return(0);
  449. do {
  450.     if(SetProtection(name,prot)) return(1);
  451. } while(dosrequestmsg(list,1,MSG_FMDOS_PROTERR,name));
  452. return(0);
  453. }
  454.  
  455. UBYTE hsparwed[]={"_H\0_S\0_P\0_A\0_R\0_W\0_E\0_D\0"};
  456.  
  457. WORD fmprotect(struct FMList *list,struct FMNode *node,ULONG prot)
  458. {
  459. WORD cnt,cnt2;
  460.  
  461. if (node->numprot!=prot) {
  462.     if(fmsetprotection(list,NDFILE(node),prot)) {
  463.         node->numprot=prot;
  464.         prot=prot^0x0f; cnt2=128;
  465.         for(cnt=0;cnt<8;cnt++) {
  466.             if(prot&cnt2) *(NDPROT(node)+cnt)=hsparwed[cnt*3+1]; else *(NDPROT(node)+cnt)='-';
  467.             cnt2=cnt2>>1;
  468.         }
  469.         return(1);
  470.     }
  471.     return(0);
  472. }
  473. return(1);
  474. }
  475.  
  476. struct FMNode* fmcreatedir(struct FMList *list,UBYTE *name)
  477. {
  478. BPTR lock;
  479. struct FMNode *node;
  480.  
  481. if (!(node=allocnode())) return(0);
  482. if (currentdir(list)) {
  483.     do {
  484.         if (lock=CreateDir(name)) {
  485.             UnLock(lock);
  486.             node->flags|=NDIRECTORY;
  487.             siirran(NDFILE(node),name,fmmain.filelen);
  488.             examinefile(list,node);
  489.             return(node);
  490.         }
  491.     } while(dosrequestmsg(list,1,MSG_FMDOS_MAKEDIRERR,name));
  492. }
  493. freevecpooled(node);
  494. return(0);
  495. }
  496.  
  497. WORD examinefile(struct FMList *list,struct FMNode *node)
  498. {
  499. BPTR lock;
  500. struct FileInfoBlock *fib;
  501. struct Process *proc;
  502. void *oldwinptr;
  503. ULONG protect;
  504. WORD cnt,cnt2;
  505.  
  506. if (!(fib=AllocVec(sizeof(struct FileInfoBlock),MEMF_CLEAR))) return(0);
  507. proc=(struct Process*)FindTask(0);
  508. oldwinptr=proc->pr_WindowPtr;
  509. proc->pr_WindowPtr=(APTR)-1;
  510. if (currentdir(list)) {
  511.     if (lock=fmlock(list,NDFILE(node))) {
  512.         if (fmexamine(list,lock,fib,NDFILE(node))) {
  513.             node->numdate=dstolong(&fib->fib_Date);
  514.             longtodatestring(NDDATE(node),node->numdate);
  515.             siirran(NDFILE(node),fib->fib_FileName,fmmain.filelen);
  516.             siirran(NDCOMM(node),fib->fib_Comment,fmmain.commlen);
  517.             node->numprot=fib->fib_Protection;
  518.             protect=fib->fib_Protection^0x0f; cnt2=128;
  519.             for(cnt=0;cnt<8;cnt++) {
  520.                 if(protect&cnt2) *(NDPROT(node)+cnt)=hsparwed[cnt*3+1]; else *(NDPROT(node)+cnt)='-';
  521.                 cnt2=cnt2>>1;
  522.             }
  523.             if(fib->fib_DirEntryType<0) {
  524.                 node->numlen=fib->fib_Size;
  525.                 node->flags|=NFILE;
  526.                 sformat(NDLENGTH(node),nformatstring,fib->fib_Size);
  527.             } else {
  528.                 node->flags|=NDIRECTORY;
  529.             }
  530.             UnLock(lock);
  531.             freemem(fib);
  532.             proc->pr_WindowPtr=oldwinptr;
  533.             return(1);
  534.         }
  535.         UnLock(lock);
  536.     }
  537. }
  538. proc->pr_WindowPtr=oldwinptr;
  539. freemem(fib);
  540. return(0);
  541. }
  542.  
  543. BPTR fminitdirread(struct FMList *list,struct FileInfoBlock *fib,UBYTE *name)
  544. {
  545. BPTR lock;
  546.  
  547. if (lock=fmlock(list,name)) {
  548.     if (fmexamine(list,lock,fib,name)) {
  549.         return(lock);
  550.     }
  551. UnLock(lock);
  552. }
  553. return(0);
  554. }
  555.  
  556. void *allocvecpooled(LONG a)
  557. {
  558. ULONG *ret;
  559.  
  560. if(fmmain.pool) {
  561.     ObtainSemaphore(&fmmain.poolsema);
  562.     a+=4;
  563.     if (ret=(ULONG*)AllocPooled(fmmain.pool,a)) *ret++=a;
  564.     ReleaseSemaphore(&fmmain.poolsema);
  565. } else {
  566.     ret=AllocVec(a,MEMF_PUBLIC|MEMF_CLEAR);
  567. }
  568. return((void*)ret);
  569. }
  570. void freevecpooled(void *a)
  571. {
  572. ULONG *b;
  573.  
  574. if(fmmain.pool) {
  575.     ObtainSemaphore(&fmmain.poolsema);
  576.     b=((ULONG*)a)-1;
  577.     FreePooled(fmmain.pool,b,*b);
  578.     ReleaseSemaphore(&fmmain.poolsema);
  579. } else {
  580.     freemem(a);
  581. }
  582. }
  583. void *allocmem(LONG size)
  584. {
  585. return(AllocVec(size,MEMF_CLEAR));
  586. }
  587. void freemem(void *ptr)
  588. {
  589. FreeVec(ptr);
  590. }
  591. void *allocvec(struct FMList *l,LONG a,LONG b)
  592. {
  593. void *ret;
  594. UBYTE *ptr;
  595.  
  596. do {
  597.     if(ret=AllocVec(a,b)) return((void*)ret);
  598.     if(!l) return(0);
  599.     if (b&MEMF_CHIP) ptr=getstring(MSG_FMDOS_CHIPMEM); else ptr=getstring(MSG_FMDOS_PUBLICMEM);
  600. } while(requestmsg(l->workname,MSG_RETRY,MSG_CANCEL,MSG_FMDOS_ALLOCATEERR,a,ptr));
  601. return(0);
  602. }
  603.  
  604. struct IORequest* opendevice(struct FMList *l,UBYTE *name,WORD unit,ULONG flags,WORD iolen)
  605. {
  606. struct MsgPort *mp;
  607. struct IORequest *io;
  608.  
  609. if (mp=CreateMsgPort()) {
  610.     if (io=CreateIORequest(mp,iolen)) {
  611.         if (!OpenDevice(name,unit,io,flags)) return(io);
  612.         DeleteIORequest(io);
  613.     }
  614.     DeleteMsgPort(mp);
  615. }
  616. requestmsg(l->workname,0,MSG_OK,MSG_FMDOS_OPENERR,name);
  617. return(0);
  618. }
  619.  
  620. void closedevice(struct IORequest *ioreq)
  621. {
  622. struct MsgPort *mp;
  623.  
  624. if(!ioreq) return;
  625. CloseDevice(ioreq);
  626. mp=ioreq->io_Message.mn_ReplyPort;
  627. DeleteIORequest(ioreq);
  628. DeleteMsgPort(mp);
  629. }
  630.  
  631. WORD checkdoserr(void)
  632. {
  633. LONG error;
  634.  
  635. error=IoErr();
  636. SetIoErr(error);
  637. return((WORD)error);
  638. }
  639.