home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga Shareware Floppies / ma64.dms / ma64.adf / FTPMount-1.0 / Source / local.c < prev    next >
C/C++ Source or Header  |  1995-09-06  |  18KB  |  901 lines

  1. /*
  2.  * This source file is Copyright 1995 by Evan Scott.
  3.  * All rights reserved.
  4.  * Permission is granted to distribute this file provided no
  5.  * fees beyond distribution costs are levied.
  6.  */
  7.  
  8. #include <exec/types.h>
  9. #include <exec/memory.h>
  10. #include <exec/alerts.h>
  11.  
  12. #include <dos/dos.h>
  13. #include <dos/dosextens.h>
  14. #include <dos/dostags.h>
  15.  
  16. #include <proto/exec.h>
  17. #include <proto/dos.h>
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22.  
  23. #include "evtypes.h"
  24. #include "verify.h"
  25. #include "tcp.h"
  26.  
  27. #include "site.h"
  28. #include "ftp.h"
  29. #include "split.h"
  30. #include "local.h"
  31.  
  32. #include "globals.h"
  33.  
  34. #define DOSBase _local_DOSBase
  35.  
  36. struct DosLibrary *DOSBase;
  37.  
  38. BSTR ctobstr(b8 *s)
  39. {
  40.     b8 *z;
  41.     int len;
  42.     
  43.     len = strlen(s);
  44.     
  45.     z = (b8 *)allocate(len + 1, V_bstr);
  46.     if (!z) return 0;
  47.     
  48.     z[0] = len;
  49.  
  50.     if (len > 0) {
  51.         memcpy(&z[1], s, len);
  52.     }
  53.  
  54.     return (BSTR)((b32)z >> 2);
  55. }
  56.  
  57. void free_bstr(BSTR b)
  58. {
  59.     deallocate((void *)(b << 2), V_bstr);
  60. }
  61.  
  62. void lock_message(BPTR l, struct DosPacket *dp)
  63. {
  64.     struct FileLock *fl;
  65.     
  66.     fl = (struct FileLock *)(l << 2);
  67.     
  68.     PutMsg(fl->fl_Task, dp->dp_Link);
  69. }
  70.  
  71. void __saveds local_handler(void)
  72. {
  73.     struct Process *me;
  74.     struct Message *msg;
  75.     struct DosPacket *dp;
  76.     struct MsgPort *local, *reply, *sync;
  77.     b32 signals;
  78.     split sd, sd2;
  79.     lock *locks, **slock, *new_lock, *nlock;
  80.     b32 rfsl;    /* real file system lock */
  81.     struct FileInfoBlock *fib;
  82.     struct FileHandle *fh;
  83.     file_info *fi;
  84.     b32 o1, o2, o3, o4;        /* stores for original dp->dp_Arg1 etc */
  85.     BSTR b, b2;
  86.     
  87.     locks = 0;
  88.     
  89.     mem_tracking_on();
  90.     
  91.     me = (struct Process *)FindTask(0l);
  92.     
  93.     local = &me->pr_MsgPort;
  94.     
  95.     WaitPort(local);
  96.     msg = GetMsg(local);
  97.     dp = (struct DosPacket *)msg->mn_Node.ln_Name;
  98.     reply = dp->dp_Port;
  99.     
  100.     dp->dp_Port = local;
  101.     
  102.     sync = CreatePort(0, 0);
  103.     if (!sync) {
  104.         dp->dp_Res1 = DOSFALSE;
  105.         dp->dp_Res2 = ERROR_NO_FREE_STORE;
  106.         
  107.         PutMsg(reply, dp->dp_Link);
  108.         
  109.         return;
  110.     }
  111.  
  112. /* do I really need DOSBase open now that I'm packeting? */
  113.  
  114.     DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 36);
  115.     if (!DOSBase) {
  116.         DeletePort(sync);
  117.  
  118.         dp->dp_Res1 = DOSFALSE;
  119.         dp->dp_Res2 = ERROR_INVALID_RESIDENT_LIBRARY;
  120.         
  121.         PutMsg(reply, dp->dp_Link);
  122.         
  123.         return;
  124.     } else {
  125.         dp->dp_Res1 = DOSTRUE;
  126.     }
  127.     dp->dp_Res2 = 0;
  128.     
  129.     PutMsg(reply, dp->dp_Link);
  130.  
  131.     signals = (1 << local->mp_SigBit);
  132.     
  133.     while (1) {
  134.         Wait(signals);
  135.         
  136.         while (msg = GetMsg(local)) {
  137.             dp = (struct DosPacket *)msg->mn_Node.ln_Name;
  138.             reply = dp->dp_Port;
  139.             
  140.             truth(dp->dp_Link == msg);
  141.             
  142.             switch (dp->dp_Type) {
  143.             case ACTION_DIE:
  144.                 /* close all locks */
  145.                 nlock = locks;
  146.                 while (nlock) {
  147.                     new_lock = nlock->next;
  148.                     
  149.                     if (nlock->rfsl != ftphosts_lock) 
  150.                         UnLock(nlock->rfsl);
  151.                     
  152.                     disown(nlock, V_lock);
  153.                     nlock = new_lock;
  154.                 }
  155.                 
  156.                 CloseLibrary((struct Library *)DOSBase);
  157.                 DeletePort(sync);
  158.                 
  159.                 Forbid();
  160.                 dp->dp_Res1 = DOSTRUE;
  161.                 dp->dp_Res2 = (b32)locks;    /* so they can adopt them */
  162.                 
  163.                 PutMsg(reply, dp->dp_Link);
  164.                 
  165.                 check_memory();
  166.                 
  167.                 return;
  168.             case ACTION_LOCATE_OBJECT:
  169.                 if (!split_data((lock *)(dp->dp_Arg1 << 2),
  170.                     (b8 *)(dp->dp_Arg2 << 2), &sd)) {
  171.                     dp->dp_Res1 = 0;
  172.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  173.                     break;
  174.                 }
  175.                 
  176.                 new_lock = (lock *)allocate(sizeof(*new_lock), V_lock);
  177.                 if (!new_lock) {
  178.                     show_string("XX2");
  179.                     dp->dp_Res1 = 0;
  180.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  181.  
  182.                     end_split(&sd);
  183.                     break;
  184.                 }
  185.                 
  186.                 if (!sd.path) {    /* they want the root */
  187.                     if (dp->dp_Arg3 == EXCLUSIVE_LOCK) {
  188.                         deallocate(new_lock, V_lock);
  189.                         
  190.                         end_split(&sd);
  191.                         
  192.                         dp->dp_Res1 = 0;
  193.                         dp->dp_Res2 = ERROR_OBJECT_IN_USE;
  194.                         break;
  195.                     }
  196.                     
  197.                     rfsl = ftphosts_lock;
  198.                 } else {
  199.                     o1 = dp->dp_Arg1;
  200.                     o2 = dp->dp_Arg2;
  201.                     
  202.                     dp->dp_Arg1 = ftphosts_lock;
  203.                     b = ctobstr(sd.path);
  204.                     if (!b) {
  205.                         deallocate(new_lock, V_lock);
  206.                         
  207.                         end_split(&sd);
  208.                         
  209.                         dp->dp_Res1 = 0;
  210.                         dp->dp_Res2 = ERROR_NO_FREE_STORE;
  211.                         break;
  212.                     }
  213.                     
  214.                     dp->dp_Arg2 = b;
  215.                     dp->dp_Port = sync;
  216.                     
  217.                     lock_message(ftphosts_lock, dp);
  218.                     WaitPort(sync); GetMsg(sync);
  219.                     
  220.                     dp->dp_Arg1 = o1;
  221.                     dp->dp_Arg2 = o2;
  222.                     
  223.                     free_bstr(b);
  224.                     
  225.                     rfsl = dp->dp_Res1;
  226.                 }
  227.  
  228.                 if (!rfsl) {
  229.                     deallocate(new_lock, V_lock);
  230.  
  231.                     end_split(&sd);
  232.                     break;
  233.                 }
  234.                 
  235.                 ensure(new_lock, V_lock);
  236.                 
  237.                 new_lock->port = local;
  238.                 
  239.                 new_lock->next = locks;
  240.                 locks = new_lock;
  241.                 
  242.                 new_lock->rfsl = rfsl;
  243.                 new_lock->fl.fl_Access = dp->dp_Arg3;
  244.                 new_lock->fl.fl_Task = ftp_port;
  245.                 new_lock->fl.fl_Volume = (b32)ftp_volume >> 2;
  246.                 
  247.                 end_split(&sd);
  248.                 
  249.                 dp->dp_Res1 = (b32)new_lock >> 2;
  250.                 dp->dp_Res2 = 0;
  251.                 
  252.                 break;
  253.             case ACTION_FREE_LOCK:
  254.                 slock = &locks;
  255.                 
  256.                 new_lock = (lock *)(dp->dp_Arg1 << 2);
  257.                 
  258.                 while (*slock && *slock != new_lock) {
  259.                     slock = &(*slock)->next;
  260.                 }
  261.                 if (!*slock) {
  262.                     show_string("Free lock failed");
  263.                     dp->dp_Res1 = DOSFALSE;
  264.                     dp->dp_Res2 = ERROR_INVALID_LOCK;
  265.                     break;
  266.                 }
  267.  
  268.                 verify(new_lock, V_lock);
  269.                 
  270.                 *slock = new_lock->next;
  271.                 
  272.                 if (new_lock->rfsl != ftphosts_lock) {
  273.                     dp->dp_Port = sync;
  274.                 
  275.                     o1 = dp->dp_Arg1;
  276.                     dp->dp_Arg1 = new_lock->rfsl;
  277.                 
  278.                     lock_message(new_lock->rfsl, dp);
  279.                     WaitPort(sync); GetMsg(sync);
  280.                 
  281.                     dp->dp_Arg1 = o1;
  282.                 }
  283.                 
  284.                 deallocate(new_lock, V_lock);
  285.                 
  286.                 dp->dp_Res1 = DOSTRUE;
  287.                 dp->dp_Res2 = 0;
  288.                 
  289.                 break;
  290.             case ACTION_DELETE_OBJECT:
  291.                 if (!split_data((lock *)(dp->dp_Arg1 << 2),
  292.                     (b8 *)(dp->dp_Arg2 << 2), &sd)) {
  293.                     dp->dp_Res1 = DOSFALSE;
  294.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  295.                     break;
  296.                 }
  297.                 
  298.                 o1 = dp->dp_Arg1;
  299.                 o2 = dp->dp_Arg2;
  300.                 
  301.                 dp->dp_Arg1 = ftphosts_lock;
  302.                 b = ctobstr(sd.path);
  303.                 if (!b) {
  304.                     end_split(&sd);
  305.                     dp->dp_Res1 = DOSFALSE;
  306.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  307.                     break;
  308.                 }
  309.                 dp->dp_Arg2 = b;
  310.                 
  311.                 dp->dp_Port = sync;
  312.                 
  313.                 lock_message(ftphosts_lock, dp);
  314.                 WaitPort(sync); GetMsg(sync);
  315.                 
  316.                 dp->dp_Arg1 = o1;
  317.                 dp->dp_Arg2 = o2;
  318.                 
  319.                 free_bstr(b);
  320.                 
  321.                 end_split(&sd);
  322.                 
  323.                 break;
  324.             case ACTION_RENAME_OBJECT:
  325.                 if (!split_data((lock *)(dp->dp_Arg1 << 2),
  326.                     (b8 *)(dp->dp_Arg2 << 2), &sd)) {
  327.                     dp->dp_Res1 = DOSFALSE;
  328.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  329.                     break;
  330.                 }
  331.                 
  332.                 if (!split_data((lock *)(dp->dp_Arg3 << 2),
  333.                     (b8 *)(dp->dp_Arg4 << 2), &sd2)) {
  334.                     end_split(&sd);
  335.                     dp->dp_Res1 = DOSFALSE;
  336.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  337.                     break;
  338.                 }
  339.                 
  340.                 o1 = dp->dp_Arg1;
  341.                 o2 = dp->dp_Arg2;
  342.                 o3 = dp->dp_Arg3;
  343.                 o4 = dp->dp_Arg4;
  344.                 
  345.                 if (!sd2.path) {    /* this is rename Unnamed1 to "ucc.gu.uwa..." */
  346.                     if (sd2.work) deallocate(sd2.work, V_cstr);
  347.                     sd2.work = (b8 *)allocate(strlen(sd2.port->mp_Node.ln_Name) + 1, V_cstr);
  348.                     if (!sd2.work) {
  349.                         dp->dp_Res1 = DOSFALSE;
  350.                         dp->dp_Res2 = ERROR_NO_FREE_STORE;
  351.                         
  352.                         end_split(&sd);
  353.                         end_split(&sd2);
  354.                         break;
  355.                     }
  356.                     strcpy(sd2.work, sd2.port->mp_Node.ln_Name);
  357.                     sd2.path = sd2.work;
  358.                 }
  359.                 
  360.                 b = ctobstr(sd.path);
  361.                 b2 = ctobstr(sd2.path);
  362.                 
  363.                 if (!b || !b2) {
  364.                     if (b) free_bstr(b);
  365.                     if (b2) free_bstr(b2);
  366.                     
  367.                     end_split(&sd);
  368.                     end_split(&sd2);
  369.                     
  370.                     dp->dp_Res1 = DOSFALSE;
  371.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  372.                     
  373.                     break;
  374.                 }
  375.  
  376.                 dp->dp_Arg1 = ftphosts_lock;
  377.                 dp->dp_Arg2 = b;
  378.                 dp->dp_Arg3 = ftphosts_lock;
  379.                 dp->dp_Arg4 = b2;
  380.                 
  381.                 dp->dp_Port = sync;
  382.                 
  383.                 lock_message(ftphosts_lock, dp);
  384.                 WaitPort(sync); GetMsg(sync);
  385.                 
  386.                 dp->dp_Arg1 = o1;
  387.                 dp->dp_Arg2 = o2;
  388.                 dp->dp_Arg3 = o3;
  389.                 dp->dp_Arg4 = o4;
  390.                 
  391.                 free_bstr(b);
  392.                 free_bstr(b2);
  393.                 
  394.                 end_split(&sd);
  395.                 end_split(&sd2);
  396.                 
  397.                 break;
  398.             case ACTION_COPY_DIR:
  399.                 new_lock = (lock *)(dp->dp_Arg1 << 2);
  400.                 verify(new_lock, V_lock);
  401.                 
  402.                 rfsl = new_lock->rfsl;
  403.  
  404.                 new_lock = (lock *)allocate(sizeof(*new_lock), V_lock);
  405.                 if (!new_lock) {
  406.                     dp->dp_Res1 = DOSFALSE;
  407.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  408.                     show_string("DupLock failed 1");
  409.                     break;
  410.                 }
  411.                 
  412.                 if (rfsl != ftphosts_lock) {
  413.                     o1 = dp->dp_Arg1;
  414.                     dp->dp_Arg1 = rfsl;
  415.  
  416.                     dp->dp_Port = sync;
  417.                 
  418.                     lock_message(rfsl, dp);
  419.                     WaitPort(sync); GetMsg(sync);
  420.                 
  421.                     rfsl = dp->dp_Res1;
  422.                     dp->dp_Arg1 = o1;
  423.                 }
  424.                 
  425.                 if (!rfsl) {
  426.                     deallocate(new_lock, V_lock);
  427.                     show_string("DupLock failed 2");
  428.                     break;
  429.                 }
  430.                 
  431.                 ensure(new_lock, V_lock);
  432.                 
  433.                 new_lock->port = local;
  434.                 new_lock->next = locks;
  435.                 locks = new_lock;
  436.                 
  437.                 new_lock->rfsl = rfsl;
  438.                 new_lock->fl.fl_Access = SHARED_LOCK;
  439.                 new_lock->fl.fl_Task = ftp_port;
  440.                 new_lock->fl.fl_Volume = (b32)ftp_volume >> 2;
  441.                 
  442.                 dp->dp_Res1 = (b32)new_lock >> 2;
  443.                 dp->dp_Res2 = 0;
  444.                 
  445.                 break;
  446.             case ACTION_SET_PROTECT:
  447.                 if (!split_data((lock *)(dp->dp_Arg2 << 2),
  448.                     (b8 *)(dp->dp_Arg3 << 2), &sd)) {
  449.                     dp->dp_Res1 = DOSFALSE;
  450.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  451.                     break;
  452.                 }
  453.                 
  454.                 o2 = dp->dp_Arg2;
  455.                 o3 = dp->dp_Arg3;
  456.                 
  457.                 dp->dp_Arg2 = ftphosts_lock;
  458.                 b = ctobstr(sd.path);
  459.                 if (!b) {
  460.                     end_split(&sd);
  461.                     
  462.                     dp->dp_Res1 = DOSFALSE;
  463.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  464.                     break;
  465.                 }
  466.                 
  467.                 dp->dp_Arg3 = b;
  468.                 dp->dp_Port = sync;
  469.                 
  470.                 lock_message(ftphosts_lock, dp);
  471.                 WaitPort(sync); GetMsg(sync);
  472.                 
  473.                 dp->dp_Arg2 = o2;
  474.                 dp->dp_Arg3 = o3;
  475.                 
  476.                 free_bstr(b);
  477.                 
  478.                 end_split(&sd);
  479.                 
  480.                 break;
  481.             case ACTION_CREATE_DIR:
  482.                 if (!split_data((lock *)(dp->dp_Arg1 << 2),
  483.                     (b8 *)(dp->dp_Arg2 << 2), &sd)) {
  484.                     dp->dp_Res1 = DOSFALSE;
  485.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  486.                     break;
  487.                 }
  488.                 
  489.                 o1 = dp->dp_Arg1;
  490.                 o2 = dp->dp_Arg2;
  491.                 
  492.                 dp->dp_Arg1 = ftphosts_lock;
  493.                 b = ctobstr(sd.path);
  494.                 if (!b) {
  495.                     end_split(&sd);
  496.                     
  497.                     dp->dp_Res1 = DOSFALSE;
  498.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  499.                     break;
  500.                 }
  501.                 
  502.                 dp->dp_Arg2 = b;
  503.                 
  504.                 dp->dp_Port = sync;
  505.                 
  506.                 lock_message(ftphosts_lock, dp);
  507.                 WaitPort(sync); GetMsg(sync);
  508.                 
  509.                 dp->dp_Arg1 = o1;
  510.                 dp->dp_Arg2 = o2;
  511.                 
  512.                 free_bstr(b);
  513.                 
  514.                 end_split(&sd);
  515.                 
  516.                 break;
  517.             case ACTION_EXAMINE_OBJECT:
  518.                 new_lock = (lock *)(dp->dp_Arg1 << 2);
  519.                 fib = (struct FileInfoBlock *)(dp->dp_Arg2 << 2);
  520.                 
  521.                 verify(new_lock, V_lock);
  522.                 truth(fib != nil);
  523.                 
  524.                 o1 = dp->dp_Arg1;
  525.                 dp->dp_Arg1 = new_lock->rfsl;
  526.                 dp->dp_Port = sync;
  527.                 
  528.                 lock_message(new_lock->rfsl, dp);
  529.                 WaitPort(sync); GetMsg(sync);
  530.                 
  531.                 dp->dp_Arg1 = o1;
  532.                 
  533.                 if (!dp->dp_Res1) break;
  534.                 
  535.                 if (new_lock->rfsl == ftphosts_lock) {
  536.                     strcpy(fib->fib_FileName, volume_name);
  537.                 }
  538.                 
  539.                 break;
  540.             case ACTION_EXAMINE_NEXT:
  541.                 new_lock = (lock *)(dp->dp_Arg1 << 2);
  542.                 fib = (struct FileInfoBlock *)(dp->dp_Arg2 << 2);
  543.                 
  544.                 verify(new_lock, V_lock);
  545.                 truth(fib != nil);
  546.                 
  547.                 o1 = dp->dp_Arg1;
  548.                 dp->dp_Arg1 = new_lock->rfsl;
  549.                 dp->dp_Port = sync;
  550.                 
  551.                 lock_message(new_lock->rfsl, dp);
  552.                 WaitPort(sync); GetMsg(sync);
  553.                 
  554.                 dp->dp_Arg1 = o1;
  555.                 
  556.                 break;
  557.             case ACTION_SET_COMMENT:
  558.                 if (!split_data((lock *)(dp->dp_Arg2 << 2),
  559.                     (b8 *)(dp->dp_Arg3 << 2), &sd)) {
  560.                     dp->dp_Res1 = DOSFALSE;
  561.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  562.                     break;
  563.                 }
  564.                 
  565.                 o2 = dp->dp_Arg2;
  566.                 o3 = dp->dp_Arg3;
  567.                 
  568.                 dp->dp_Arg2 = ftphosts_lock;
  569.                 b = ctobstr(sd.path);
  570.                 if (!b) {
  571.                     end_split(&sd);
  572.                     
  573.                     dp->dp_Res1 = DOSFALSE;
  574.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  575.                     break;
  576.                 }
  577.                 
  578.                 dp->dp_Arg3 = b;
  579.                 dp->dp_Port = sync;
  580.                 
  581.                 lock_message(ftphosts_lock, dp);
  582.                 WaitPort(sync); GetMsg(sync);
  583.                 
  584.                 dp->dp_Arg2 = o2;
  585.                 dp->dp_Arg3 = o3;
  586.                 
  587.                 free_bstr(b);
  588.                 
  589.                 end_split(&sd);
  590.                 
  591.                 break;
  592.             case ACTION_PARENT:
  593.                 new_lock = (lock *)(dp->dp_Arg1 << 2);
  594.                 
  595.                 verify(new_lock, V_lock);
  596.                 
  597.                 if (new_lock->rfsl == ftphosts_lock) {
  598.                     dp->dp_Res1 = 0;
  599.                     dp->dp_Res2 = 0;
  600.                     break;
  601.                 }
  602.                 /* fall through */
  603.             case ACTION_PARENT_FH:
  604.                 new_lock = (lock *)allocate(sizeof(*new_lock), V_lock);
  605.                 if (!new_lock) {
  606.                     dp->dp_Res1 = 0;
  607.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  608.  
  609.                     break;
  610.                 }
  611.                 
  612.                 ensure(new_lock, V_lock);
  613.                 
  614.                 new_lock->port = local;
  615.                 
  616.                 new_lock->next = locks;
  617.                 locks = new_lock;
  618.                 
  619.                 new_lock->rfsl = ftphosts_lock;
  620.                 new_lock->fl.fl_Access = SHARED_LOCK;
  621.                 new_lock->fl.fl_Task = ftp_port;
  622.                 new_lock->fl.fl_Volume = (b32)ftp_volume >> 2;
  623.                 
  624.                 dp->dp_Res1 = (b32)new_lock >> 2;
  625.                 dp->dp_Res2 = 0;
  626.                 
  627.                 break;
  628.             case ACTION_SET_DATE:
  629.                 new_lock = (lock *)(dp->dp_Arg1 << 2);
  630.                 
  631.                 verify(new_lock, V_lock);
  632.                 
  633.                 o1 = dp->dp_Arg1;
  634.                 dp->dp_Arg1 = new_lock->rfsl;
  635.                 
  636.                 dp->dp_Port = sync;
  637.                 lock_message(new_lock->rfsl, dp);
  638.                 WaitPort(sync); GetMsg(sync);
  639.                 
  640.                 dp->dp_Arg1 = o1;
  641.                 
  642.                 break;
  643.             case ACTION_SAME_LOCK:
  644.                 new_lock = (lock *)(dp->dp_Arg1 << 2);
  645.                 
  646.                 verify(new_lock, V_lock);
  647.                 
  648.                 if (new_lock->rfsl == ftphosts_lock) {
  649.                     new_lock = (lock *)(dp->dp_Arg2 << 2);
  650.                     
  651.                     verify(new_lock, V_lock);
  652.                     
  653.                     if (new_lock->rfsl == ftphosts_lock) {
  654.                         dp->dp_Res1 = DOSTRUE;
  655.                     } else {
  656.                         dp->dp_Res1 = DOSFALSE;
  657.                     }
  658.                     dp->dp_Res2 = 0;
  659.                     break;
  660.                 }
  661.                 
  662.                 rfsl = new_lock->rfsl;
  663.                 
  664.                 new_lock = (lock *)(dp->dp_Arg2 << 2);
  665.                 
  666.                 verify(new_lock, V_lock);
  667.                 
  668.                 o1 = dp->dp_Arg1;
  669.                 o2 = dp->dp_Arg2;
  670.                 
  671.                 dp->dp_Arg1 = rfsl;
  672.                 dp->dp_Arg2 = new_lock->rfsl;
  673.                 
  674.                 dp->dp_Port = sync;
  675.                 lock_message(rfsl, dp);
  676.                 WaitPort(sync); GetMsg(sync);
  677.                 
  678.                 dp->dp_Arg1 = o1;
  679.                 dp->dp_Arg2 = o2;
  680.                 
  681.                 break;
  682.             case ACTION_READ:
  683.             case ACTION_WRITE:
  684.                 fi = (file_info *)dp->dp_Arg1;
  685.                 verify(fi, V_file_info);
  686.                 
  687.                 o1 = dp->dp_Arg1;
  688.                 dp->dp_Arg1 = fi->rfarg;
  689.                 dp->dp_Port = sync;
  690.                 
  691.                 lock_message(ftphosts_lock, dp);
  692.                 WaitPort(sync); GetMsg(sync);
  693.                 
  694.                 dp->dp_Arg1 = o1;
  695.                 
  696.                 break;
  697.             case ACTION_FINDUPDATE:
  698.             case ACTION_FINDINPUT:
  699.             case ACTION_FINDOUTPUT:
  700.                 if (!split_data((lock *)(dp->dp_Arg2 << 2),
  701.                     (b8 *)(dp->dp_Arg3 << 2), &sd)) {
  702.                     dp->dp_Res1 = DOSFALSE;
  703.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  704.                     break;
  705.                 }
  706.                 
  707.                 fi = (file_info *)allocate(sizeof(*fi), V_file_info);
  708.                 if (!fi) {
  709.                     end_split(&sd);
  710.                     
  711.                     dp->dp_Res1 = DOSFALSE;
  712.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  713.                     break;
  714.                 }
  715.                 
  716.                 ensure(fi, V_file_info);
  717.                 
  718.                 fh = (struct FileHandle *)(dp->dp_Arg1 << 2);
  719.                 
  720.                 truth(fh != nil);
  721.                 
  722.                 o2 = dp->dp_Arg2;
  723.                 o3 = dp->dp_Arg3;
  724.                 
  725.                 dp->dp_Arg2 = ftphosts_lock;
  726.                 b = ctobstr(sd.path);
  727.                 if (!b) {
  728.                     deallocate(fi, V_file_info);
  729.                     end_split(&sd);
  730.                     
  731.                     dp->dp_Res1 = DOSFALSE;
  732.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  733.                     break;
  734.                 }
  735.                 dp->dp_Arg3 = b;
  736.                 
  737.                 dp->dp_Port = sync;
  738.                 
  739.                 lock_message(ftphosts_lock, dp);
  740.                 WaitPort(sync); GetMsg(sync);
  741.                 
  742.                 dp->dp_Arg2 = o2;
  743.                 dp->dp_Arg3 = o3;
  744.                 
  745.                 free_bstr(b);
  746.                 
  747.                 if (dp->dp_Res1) {
  748.                     fh->fh_Type = ftp_port;
  749.                     fi->rfarg = fh->fh_Args;
  750.                     fh->fh_Args = (b32)fi;
  751.                     fi->port = local;
  752.                     fi->type = dp->dp_Type;
  753.                 } else {
  754.                     deallocate(fi, V_file_info);
  755.                 }
  756.                 
  757.                 end_split(&sd);
  758.                 
  759.                 break;
  760.             case ACTION_END:
  761.                 fi = (file_info *)dp->dp_Arg1;
  762.                 
  763.                 verify(fi, V_file_info);
  764.                 
  765.                 o1 = dp->dp_Arg1;
  766.                 dp->dp_Arg1 = fi->rfarg;
  767.                 
  768.                 dp->dp_Port = sync;
  769.                 lock_message(ftphosts_lock, dp);
  770.                 WaitPort(sync); GetMsg(sync);
  771.                 
  772.                 dp->dp_Arg1 = o1;
  773.                 
  774.                 deallocate(fi, V_file_info);
  775.                 
  776.                 break;
  777.             case ACTION_SEEK:
  778.                 fi = (file_info *)dp->dp_Arg1;
  779.                 
  780.                 verify(fi, V_file_info);
  781.                 
  782.                 o1 = dp->dp_Arg1;
  783.                 
  784.                 dp->dp_Arg1 = fi->rfarg;
  785.                 
  786.                 dp->dp_Port = sync;
  787.                 lock_message(ftphosts_lock, dp);
  788.                 WaitPort(sync); GetMsg(sync);
  789.                 
  790.                 dp->dp_Arg1 = o1;
  791.                 
  792.                 break;
  793.             case ACTION_FH_FROM_LOCK:
  794.                 fh = (struct FileHandle *)(dp->dp_Arg1 << 2);
  795.                 nlock = (lock *)(dp->dp_Arg2 << 2);
  796.                 
  797.                 verify(nlock, V_lock);
  798.                 truth(fh != nil);
  799.  
  800.                 fi = (file_info *)allocate(sizeof(*fi), V_file_info);
  801.                 if (!fi) {
  802.                     dp->dp_Res1 = DOSFALSE;
  803.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  804.                     break;
  805.                 }
  806.                 
  807.                 ensure(fi, V_file_info);
  808.                 
  809.                 o2 = dp->dp_Arg2;
  810.                 
  811.                 dp->dp_Arg2 = nlock->rfsl;
  812.                 
  813.                 dp->dp_Port = sync;
  814.                 lock_message(ftphosts_lock, dp);
  815.                 WaitPort(sync); GetMsg(sync);
  816.                 
  817.                 dp->dp_Arg2 = o2;
  818.                 
  819.                 if (dp->dp_Res1) {
  820.                     fh->fh_Type = ftp_port;
  821.                     fi->rfarg = fh->fh_Args;
  822.                     fh->fh_Args = (b32)fi;
  823.                     fi->port = local;
  824.                     fi->type = dp->dp_Type;
  825.                 } else {
  826.                     deallocate(fi, V_file_info);
  827.                 }
  828.                 
  829.                 break;
  830.             case ACTION_COPY_DIR_FH:
  831.                 fh = (struct FileHandle *)(dp->dp_Arg1 << 2);
  832.                 fi = (file_info *)fh->fh_Args;
  833.                 
  834.                 new_lock = (lock *)allocate(sizeof(*new_lock), V_lock);
  835.                 if (!new_lock) {
  836.                     dp->dp_Res1 = 0;
  837.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  838.  
  839.                     break;
  840.                 }
  841.                 
  842.                 ensure(new_lock, V_lock);
  843.                 
  844.                 new_lock->port = local;
  845.                 
  846.                 new_lock->fl.fl_Access = SHARED_LOCK;
  847.                 new_lock->fl.fl_Task = ftp_port;
  848.                 new_lock->fl.fl_Volume = (b32)ftp_volume >> 2;
  849.                 
  850.                 verify(fi, V_file_info);
  851.                 
  852.                 fh->fh_Args = fi->rfarg;
  853.                 
  854.                 dp->dp_Port = sync;
  855.                 lock_message(ftphosts_lock, dp);
  856.                 WaitPort(sync); GetMsg(sync);
  857.                 
  858.                 fh->fh_Args = (b32)fi;
  859.                 
  860.                 if (dp->dp_Res1) {
  861.                     new_lock->rfsl = dp->dp_Res1;
  862.  
  863.                     new_lock->next = locks;
  864.                     locks = new_lock;
  865.                 
  866.                     dp->dp_Res1 = (b32)new_lock >> 2;
  867.                     dp->dp_Res2 = 0;
  868.                 } else {
  869.                     deallocate(new_lock, V_lock);
  870.                 }
  871.                 
  872.                 break;
  873.             case ACTION_EXAMINE_FH:
  874.                 fh = (struct FileHandle *)(dp->dp_Arg1 << 2);
  875.                 
  876.                 fi = (file_info *)fh->fh_Args;
  877.                 
  878.                 verify(fi, V_file_info);
  879.                 
  880.                 fh->fh_Args = fi->rfarg;
  881.                 
  882.                 dp->dp_Port = sync;
  883.                 lock_message(ftphosts_lock, dp);
  884.                 WaitPort(sync); GetMsg(sync);
  885.                 
  886.                 fh->fh_Args = (b32)fi;
  887.                 
  888.                 break;
  889.             default:
  890.                 show_int(dp->dp_Type);
  891.                 dp->dp_Res1 = DOSFALSE;
  892.                 dp->dp_Res2 = ERROR_ACTION_NOT_KNOWN;
  893.                 break;
  894.             }
  895.             
  896.             dp->dp_Port = ftp_port;
  897.             PutMsg(reply, dp->dp_Link);
  898.         }
  899.     }
  900. }
  901.