home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga Shareware Floppies / ma64.dms / ma64.adf / FTPMount-1.0 / Source / listen.c < prev    next >
C/C++ Source or Header  |  1995-12-10  |  11KB  |  518 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 <intuition/intuition.h>
  17.  
  18. #include <libraries/commodities.h>
  19.  
  20. #include <proto/exec.h>
  21. #include <proto/dos.h>
  22. #include <proto/commodities.h>
  23.  
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27.  
  28. #include "evtypes.h"
  29. #include "verify.h"
  30. #include "tcp.h"
  31.  
  32. #include "site.h"
  33. #include "ftp.h"
  34. #include "split.h"
  35. #include "request.h"
  36.  
  37. #include "globals.h"
  38.  
  39. struct DosPacket *fh_listen(void)
  40. {
  41.     struct DosPacket *dp;
  42.     struct MsgPort *reply;
  43.     struct Message *msg;
  44.     struct InfoData *id;
  45.     struct FileHandle *fh;
  46.     file_info *fi;
  47.     b32 signals;
  48.     split sd, sd2;
  49.     lock *my_lock, *lock2;
  50.     site *my_site;
  51.     status_message *sm;
  52.     b8 *s, *name;
  53.     
  54.     b32 pass_key = 0;
  55.     boolean write_protect = false, disabled = false;
  56.     
  57.     signals = (1 << ftp_port->mp_SigBit) | (1 << status_control->mp_SigBit);
  58.     
  59.     while (1) {
  60.         Wait(signals);
  61.         
  62.         while (sm = (status_message *)GetMsg(status_control)) {
  63.             verify(sm, V_status_message);
  64.             
  65.             switch (sm->command) {
  66.             case SM_KILL:
  67.                 ReplyMsg(&sm->header);
  68.                 return nil;
  69.             case SM_SUSPEND:
  70.                 disabled = true;
  71.                 
  72.                 suspend_sites();
  73.                 
  74.                 break;
  75.             case SM_RESUME:
  76.                 disabled = false;
  77.                 break;
  78.             }
  79.             ReplyMsg(&sm->header);
  80.         }
  81.         
  82.         while (msg = GetMsg(ftp_port)) {
  83.             dp = (struct DosPacket *)msg->mn_Node.ln_Name;
  84.             
  85.             reply = dp->dp_Port;
  86.             
  87.             truth(dp->dp_Link == msg);
  88.             
  89.             if (disabled && dp->dp_Type != action_IDLE) {
  90.                 dp->dp_Res1 = DOSFALSE;
  91.                 dp->dp_Res2 = ERROR_DEVICE_NOT_MOUNTED;
  92.                 
  93.                 dp->dp_Port = ftp_port;
  94.                 PutMsg(reply, dp->dp_Link);
  95.                 continue;
  96.             }
  97.             
  98.             switch (dp->dp_Type) {
  99.             case ACTION_NIL:
  100.                 dp->dp_Res1 = DOSTRUE;
  101.                 dp->dp_Res2 = 0;
  102.                 break;
  103.             case ACTION_DIE:
  104.                 return dp;
  105.             case ACTION_LOCATE_OBJECT:    /* Lock() */
  106.                 if (dp->dp_Arg3 != SHARED_LOCK && dp->dp_Arg3 != EXCLUSIVE_LOCK) {
  107.                     dp->dp_Res1 = 0;
  108.                     dp->dp_Res2 = ERROR_BAD_NUMBER;
  109.                     break;
  110.                 }
  111.                 
  112.                 if (!split_data((lock *)(dp->dp_Arg1 << 2), 
  113.                             (b8 *)(dp->dp_Arg2 << 2), &sd)) {
  114.                     /* might be ERROR_NO_FREE_STORE, but hey */
  115.                     dp->dp_Res1 = 0;
  116.                     dp->dp_Res2 = ERROR_INVALID_COMPONENT_NAME;
  117.                     break;
  118.                 }
  119.                 
  120.                 PutMsg(sd.port, dp->dp_Link);
  121.                 
  122.                 end_split(&sd);
  123.  
  124.                 continue;
  125.             case ACTION_RENAME_DISK:    /* Relabel() */
  126.                 name = (b8 *)(dp->dp_Arg1 << 2);
  127.                 s = (b8 *)allocate(name[0] + 2, V_bstr);
  128.                 if (!s) {
  129.                     dp->dp_Res1 = DOSFALSE;
  130.                     dp->dp_Res2 = ERROR_NO_FREE_STORE;
  131.                     break;
  132.                 }
  133.                 
  134.                 s[0] = name[0];
  135.                 memcpy(&s[1], &name[1], s[0]);
  136.                 s[1 + s[0]] = 0;
  137.                 
  138.                 /* perhaps should do some mutual exclusion here ... */
  139.                 ftp_volume->dol_Name = (b32)s >> 2;
  140.                 
  141.                 deallocate(volume_name, V_bstr);
  142.                 volume_name = s;
  143.                 
  144.                 dp->dp_Res1 = DOSTRUE;
  145.                 dp->dp_Res2 = 0;
  146.                 
  147.                 break;
  148.             case ACTION_FREE_LOCK:        /* UnLock() */
  149.             case ACTION_COPY_DIR:        /* DupLock() */
  150.             case ACTION_EXAMINE_OBJECT:    /* Examine() */
  151.             case ACTION_EXAMINE_NEXT:    /* ExNext() */
  152.             case ACTION_PARENT:        /* ParentDir() */
  153.             case ACTION_SET_DATE:        /* SetFileDate() */
  154.                 my_lock = (lock *)(dp->dp_Arg1 << 2);
  155.                 
  156.                 if (!my_lock) {
  157.                     dp->dp_Res1 = DOSFALSE;
  158.                     dp->dp_Res2 = ERROR_INVALID_LOCK;
  159.                     break;
  160.                 }
  161.                 
  162.                 verify(my_lock, V_lock);
  163.                 
  164.                 PutMsg(my_lock->port, dp->dp_Link);
  165.                 continue;
  166.             case ACTION_SET_PROTECT:
  167.             case ACTION_SET_COMMENT:
  168.                 if (!split_data((lock *)(dp->dp_Arg2 << 2),
  169.                             (b8 *)(dp->dp_Arg3 << 2), &sd)) {
  170.                     dp->dp_Res1 = DOSFALSE;
  171.                     dp->dp_Res2 = ERROR_INVALID_COMPONENT_NAME;
  172.                     break;
  173.                 }
  174.                 
  175.                 PutMsg(sd.port, dp->dp_Link);
  176.                 
  177.                 end_split(&sd);
  178.                 
  179.                 continue;
  180.             case ACTION_RENAME_OBJECT:
  181.                 if (!split_data((lock *)(dp->dp_Arg1 << 2),
  182.                             (b8 *)(dp->dp_Arg2 << 2), &sd)) {
  183.                     dp->dp_Res1 = DOSFALSE;
  184.                     dp->dp_Res2 = ERROR_INVALID_COMPONENT_NAME;
  185.                     break;
  186.                 }
  187.                 
  188.                 if (!split_data((lock *)(dp->dp_Arg3 << 2),
  189.                             (b8 *)(dp->dp_Arg4 << 2), &sd2)) {
  190.                     dp->dp_Res1 = DOSFALSE;
  191.                     dp->dp_Res2 = ERROR_INVALID_COMPONENT_NAME;
  192.                     
  193.                     end_split(&sd);
  194.                     break;
  195.                 }
  196.                 
  197.                 if (sd.port == local_port &&
  198.                     !sd2.path) {    /* special case */
  199.                     
  200.                     PutMsg(local_port, dp->dp_Link);
  201.                     
  202.                     end_split(&sd);
  203.                     end_split(&sd2);
  204.                     continue;
  205.                 }
  206.                 
  207.                 if (sd.port != sd2.port) {
  208.                     dp->dp_Res1 = DOSFALSE;
  209.                     dp->dp_Res2 = ERROR_RENAME_ACROSS_DEVICES;
  210.                     
  211.                     end_split(&sd);
  212.                     end_split(&sd2);
  213.                     break;
  214.                 }
  215.                 
  216.                 PutMsg(sd.port, dp->dp_Link);
  217.                 
  218.                 end_split(&sd);
  219.                 end_split(&sd2);
  220.                 
  221.                 continue;
  222.             case ACTION_DELETE_OBJECT:
  223.                 if (!split_data((lock *)(dp->dp_Arg1 << 2),
  224.                             (b8 *)(dp->dp_Arg2 << 2), &sd)) {
  225.                     dp->dp_Res1 = DOSFALSE;
  226.                     dp->dp_Res2 = ERROR_INVALID_COMPONENT_NAME;
  227.                     break;
  228.                 }
  229.                 
  230.                 PutMsg(sd.port, dp->dp_Link);
  231.                 
  232.                 end_split(&sd);
  233.                 
  234.                 continue;
  235.             case ACTION_CREATE_DIR:
  236.                 if (!split_data((lock *)(dp->dp_Arg1 << 2),
  237.                             (b8 *)(dp->dp_Arg2 << 2), &sd)) {
  238.                     dp->dp_Res1 = DOSFALSE;
  239.                     dp->dp_Res2 = ERROR_INVALID_COMPONENT_NAME;
  240.                     break;
  241.                 }
  242.                 
  243.                 if (!sd.path)
  244.                 {
  245.                     PutMsg(local_port, dp->dp_Link);
  246.                 }
  247.                 else
  248.                 {
  249.                     PutMsg(sd.port, dp->dp_Link);
  250.                 }
  251.                 
  252.                 end_split(&sd);
  253.                 
  254.                 continue;
  255.             case ACTION_DISK_INFO:
  256.                 id = (struct InfoData *)(dp->dp_Arg1 << 2);
  257.                 truth(id != nil);
  258.  
  259.                 id->id_NumSoftErrors = 0;
  260.                 id->id_UnitNumber = 0;
  261.                 if (write_protect)
  262.                     id->id_DiskState = ID_WRITE_PROTECTED;
  263.                 else
  264.                     id->id_DiskState = ID_VALIDATED;
  265.                 id->id_NumBlocks = 1;
  266.                 id->id_NumBlocksUsed = 1;
  267.                 id->id_BytesPerBlock = 1024;
  268.                 id->id_DiskType = ID_DOS_DISK;
  269.                 id->id_VolumeNode = (b32)ftp_volume >> 2;
  270.                 id->id_InUse = 0;
  271.                 
  272.                 dp->dp_Res1 = DOSTRUE;
  273.                 dp->dp_Res2 = 0;
  274.  
  275.                 break;
  276.             case ACTION_INFO:
  277.                 id = (struct InfoData *)(dp->dp_Arg2 << 2);
  278.                 truth(id != nil);
  279.  
  280.                 id->id_NumSoftErrors = 0;
  281.                 id->id_UnitNumber = 0;
  282.                 if (write_protect)
  283.                     id->id_DiskState = ID_WRITE_PROTECTED;
  284.                 else
  285.                     id->id_DiskState = ID_VALIDATED;
  286.                 id->id_NumBlocks = 1;
  287.                 id->id_NumBlocksUsed = 1;
  288.                 id->id_BytesPerBlock = 1024;
  289.                 id->id_DiskType = ID_DOS_DISK;
  290.                 id->id_VolumeNode = (b32)ftp_volume >> 2;
  291.                 id->id_InUse = 0;
  292.                 
  293.                 dp->dp_Res1 = DOSTRUE;
  294.                 dp->dp_Res2 = 0;
  295.  
  296.                 break;
  297.             case ACTION_SAME_LOCK:
  298.                 my_lock = (lock *)(dp->dp_Arg1 << 2);
  299.                 lock2 = (lock *)(dp->dp_Arg2 << 2);
  300.                 
  301.                 verify(my_lock, V_lock);
  302.                 verify(lock2, V_lock);
  303.                 
  304. #ifdef SLDFKJ
  305.                 if (my_lock->port == local_port) {
  306.                     if (my_lock->rfsl == ftphosts_lock)
  307.                         { show_string("lock 1 is ROOT"); }
  308.                     else
  309.                         { show_string("lock 1 is local lock"); }
  310.                 } else {
  311.                     show_string(my_lock->fname);
  312.                 }
  313.                 
  314.                 if (lock2->port == local_port) {
  315.                     if (lock2->rfsl == ftphosts_lock)
  316.                         { show_string("lock 2 is ROOT"); }
  317.                     else
  318.                         { show_string("lock 2 is local lock"); }
  319.                 } else {
  320.                     show_string(lock2->fname);
  321.                 }
  322. #endif
  323.                 
  324.                 if (my_lock->port != lock2->port) {
  325.                     dp->dp_Res1 = DOSFALSE;
  326.                     dp->dp_Res2 = ERROR_INVALID_LOCK;
  327.                     break;
  328.                 }
  329.                 
  330.                 PutMsg(my_lock->port, dp->dp_Link);
  331.                 continue;
  332.             case ACTION_READ:
  333.             case ACTION_WRITE:
  334.                 fi = (file_info *)dp->dp_Arg1;
  335.                 
  336.                 verify(fi, V_file_info);
  337.                 
  338.                 PutMsg(fi->port, dp->dp_Link);
  339.                 
  340.                 continue;
  341.             case ACTION_FINDUPDATE:
  342.             case ACTION_FINDINPUT:
  343.             case ACTION_FINDOUTPUT:
  344.                 if (!split_data((lock *)(dp->dp_Arg2 << 2), 
  345.                             (b8 *)(dp->dp_Arg3 << 2), &sd)) {
  346.                     /* might be ERROR_NO_FREE_STORE, but hey */
  347.                     dp->dp_Res1 = DOSFALSE;
  348.                     dp->dp_Res2 = ERROR_INVALID_COMPONENT_NAME;
  349.                     break;
  350.                 }
  351.                 
  352.                 PutMsg(sd.port, dp->dp_Link);
  353.                 
  354.                 end_split(&sd);
  355.  
  356.                 continue;
  357.             case ACTION_END:
  358.                 fi = (file_info *)dp->dp_Arg1;
  359.                 
  360.                 verify(fi, V_file_info);
  361.                 
  362.                 PutMsg(fi->port, dp->dp_Link);
  363.                 
  364.                 continue;
  365.             case ACTION_SEEK:
  366.                 fi = (file_info *)dp->dp_Arg1;
  367.                 
  368.                 verify(fi, V_file_info);
  369.                 
  370.                 PutMsg(fi->port, dp->dp_Link);
  371.                 
  372.                 continue;
  373.             case ACTION_WRITE_PROTECT:
  374.                 if (write_protect && dp->dp_Arg1) {
  375.                     dp->dp_Res1 = DOSFALSE;
  376.                     dp->dp_Res2 = ERROR_DISK_WRITE_PROTECTED;
  377.                     break;
  378.                 } else if (!write_protect && !dp->dp_Arg1) {
  379.                     dp->dp_Res1 = DOSTRUE;
  380.                     dp->dp_Res2 = 0;
  381.                     break;
  382.                 } else if (!write_protect && dp->dp_Arg1) {
  383.                     dp->dp_Res1 = DOSTRUE;
  384.                     dp->dp_Res2 = 0;
  385.                     write_protect = 1;
  386.                     pass_key = dp->dp_Arg2;
  387.                     break;
  388.                 } else {
  389.                     if (pass_key == 0 || pass_key == dp->dp_Arg2) {
  390.                         dp->dp_Res1 = DOSTRUE;
  391.                         dp->dp_Res2 = 0;
  392.                         write_protect = 0;
  393.                         pass_key = 0;
  394.                         break;
  395.                     } else {
  396.                         dp->dp_Res1 = DOSFALSE;
  397.                         dp->dp_Res2 = ERROR_DISK_WRITE_PROTECTED;
  398.                         break;
  399.                     }
  400.                 }
  401.                 break;
  402.             case ACTION_FH_FROM_LOCK:
  403.                 my_lock = (lock *)(dp->dp_Arg2 << 2);
  404.                 
  405.                 if (!my_lock) {
  406.                     dp->dp_Res1 = DOSFALSE;
  407.                     dp->dp_Res2 = ERROR_INVALID_LOCK;
  408.                     break;
  409.                 }
  410.                 
  411.                 verify(my_lock, V_lock);
  412.                 
  413.                 PutMsg(my_lock->port, dp->dp_Link);
  414.                 continue;
  415.             case ACTION_IS_FILESYSTEM:
  416.                 dp->dp_Res1 = DOSTRUE;
  417.                 dp->dp_Res2 = 0;
  418.                 break;
  419.             case ACTION_COPY_DIR_FH:
  420.             case ACTION_PARENT_FH:
  421. //            case ACTION_EXAMINE_FH:
  422.                 fh = (struct FileHandle *)(dp->dp_Arg1 << 2);
  423.                 
  424.                 fi = (file_info *)fh->fh_Args;
  425.                 verify(fi, V_file_info);
  426.                 
  427.                 PutMsg(fi->port, dp->dp_Link);
  428.                 
  429.                 continue;
  430.             case ACTION_EXAMINE_ALL:
  431.                 my_lock = (lock *)(dp->dp_Arg1 << 2);
  432.                 
  433.                 if (!my_lock) {
  434.                     dp->dp_Res1 = DOSFALSE;
  435.                     dp->dp_Res2 = ERROR_INVALID_LOCK;
  436.                     break;
  437.                 }
  438.                 
  439.                 verify(my_lock, V_lock);
  440.                 
  441.                 PutMsg(my_lock->port, dp->dp_Link);
  442.                 continue;
  443.             case action_IDLE:
  444.                 my_site = (site *)dp->dp_Arg1;
  445.                 
  446.                 dp->dp_Port = ftp_port;
  447.                 PutMsg(reply, dp->dp_Link);    /* send the IDLE back */
  448.                 
  449.                 dp = &my_site->death_packet->sp_Pkt;
  450.                 dp->dp_Type = action_IDLE_DEATH;
  451.                 
  452.                 dp->dp_Port = startup_sync;
  453.                 PutMsg(my_site->port, dp->dp_Link);
  454.                 WaitPort(startup_sync); GetMsg(startup_sync);
  455.                 
  456.                 if (dp->dp_Res1) {
  457.                     my_lock = (lock *)dp->dp_Res2;
  458.                     while (my_lock) {
  459.                         adopt(my_lock, V_lock);
  460.                         my_lock = my_lock->next;
  461.                     }
  462.                     
  463.                     remove_site((site *)my_site);
  464.                 }
  465.                 
  466.                 continue;
  467.             default:
  468.                 show_int(dp->dp_Type);
  469.                 dp->dp_Res1 = DOSFALSE;
  470.                 dp->dp_Res2 = ERROR_ACTION_NOT_KNOWN;
  471.                 break;
  472.             }
  473.             
  474.             dp->dp_Port = ftp_port;
  475.             
  476.             PutMsg(reply, dp->dp_Link);
  477.         }
  478.     }
  479. }
  480.  
  481. void fh_ignore(void)
  482. /* sits on our message port and cancels all actions */
  483. {
  484.     struct Message *msg;
  485.     struct MsgPort *reply;
  486.     struct DosPacket *dp;
  487.     b32 signals;
  488.     lock *l;
  489.     
  490.     signals = (1 << ftp_port->mp_SigBit);
  491.     
  492.     while (1) {
  493.         Wait(signals);
  494.         
  495.         while (msg = GetMsg(ftp_port)) {
  496.             dp = (struct DosPacket *)msg->mn_Node.ln_Name;
  497.             
  498.             if (dp->dp_Type == ACTION_FREE_LOCK) {
  499.                 l = (lock *)(dp->dp_Arg1 << 2);
  500.                 verify(l, V_lock);
  501.                 
  502.                 deallocate(l, V_lock);
  503.                 
  504.                 dp->dp_Res1 = DOSTRUE;
  505.                 dp->dp_Res2 = 0;
  506.             } else {
  507.                 dp->dp_Res1 = DOSFALSE;
  508.                 dp->dp_Res2 = ERROR_ACTION_NOT_KNOWN;
  509.             }
  510.             
  511.             reply = dp->dp_Port;
  512.             dp->dp_Port = ftp_port;
  513.             
  514.             PutMsg(reply, dp->dp_Link);
  515.         }
  516.     }
  517. }
  518.