home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / FTPMOUNT.LZX / FTPMount-0.7 / Source / listen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-06  |  10.7 KB  |  500 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.             case ACTION_CREATE_DIR:
  224.                 if (!split_data((lock *)(dp->dp_Arg1 << 2),
  225.                             (b8 *)(dp->dp_Arg2 << 2), &sd)) {
  226.                     dp->dp_Res1 = DOSFALSE;
  227.                     dp->dp_Res2 = ERROR_INVALID_COMPONENT_NAME;
  228.                     break;
  229.                 }
  230.                 
  231.                 PutMsg(sd.port, dp->dp_Link);
  232.                 
  233.                 end_split(&sd);
  234.                 
  235.                 continue;
  236.             case ACTION_DISK_INFO:
  237.                 id = (struct InfoData *)(dp->dp_Arg1 << 2);
  238.                 truth(id != nil);
  239.  
  240.                 id->id_NumSoftErrors = 0;
  241.                 id->id_UnitNumber = 0;
  242.                 if (write_protect)
  243.                     id->id_DiskState = ID_WRITE_PROTECTED;
  244.                 else
  245.                     id->id_DiskState = ID_VALIDATED;
  246.                 id->id_NumBlocks = 1;
  247.                 id->id_NumBlocksUsed = 1;
  248.                 id->id_BytesPerBlock = 1024;
  249.                 id->id_DiskType = ID_DOS_DISK;
  250.                 id->id_VolumeNode = (b32)ftp_volume >> 2;
  251.                 id->id_InUse = 0;
  252.                 
  253.                 dp->dp_Res1 = DOSTRUE;
  254.                 dp->dp_Res2 = 0;
  255.  
  256.                 break;
  257.             case ACTION_INFO:
  258.                 id = (struct InfoData *)(dp->dp_Arg2 << 2);
  259.                 truth(id != nil);
  260.  
  261.                 id->id_NumSoftErrors = 0;
  262.                 id->id_UnitNumber = 0;
  263.                 if (write_protect)
  264.                     id->id_DiskState = ID_WRITE_PROTECTED;
  265.                 else
  266.                     id->id_DiskState = ID_VALIDATED;
  267.                 id->id_NumBlocks = 1;
  268.                 id->id_NumBlocksUsed = 1;
  269.                 id->id_BytesPerBlock = 1024;
  270.                 id->id_DiskType = ID_DOS_DISK;
  271.                 id->id_VolumeNode = (b32)ftp_volume >> 2;
  272.                 id->id_InUse = 0;
  273.                 
  274.                 dp->dp_Res1 = DOSTRUE;
  275.                 dp->dp_Res2 = 0;
  276.  
  277.                 break;
  278.             case ACTION_SAME_LOCK:
  279.                 my_lock = (lock *)(dp->dp_Arg1 << 2);
  280.                 lock2 = (lock *)(dp->dp_Arg2 << 2);
  281.                 
  282.                 verify(my_lock, V_lock);
  283.                 verify(lock2, V_lock);
  284.                 
  285. #ifdef SLDFKJ
  286.                 if (my_lock->port == local_port) {
  287.                     if (my_lock->rfsl == ftphosts_lock)
  288.                         { show_string("lock 1 is ROOT"); }
  289.                     else
  290.                         { show_string("lock 1 is local lock"); }
  291.                 } else {
  292.                     show_string(my_lock->fname);
  293.                 }
  294.                 
  295.                 if (lock2->port == local_port) {
  296.                     if (lock2->rfsl == ftphosts_lock)
  297.                         { show_string("lock 2 is ROOT"); }
  298.                     else
  299.                         { show_string("lock 2 is local lock"); }
  300.                 } else {
  301.                     show_string(lock2->fname);
  302.                 }
  303. #endif
  304.                 
  305.                 if (my_lock->port != lock2->port) {
  306.                     dp->dp_Res1 = DOSFALSE;
  307.                     dp->dp_Res2 = ERROR_INVALID_LOCK;
  308.                     break;
  309.                 }
  310.                 
  311.                 PutMsg(my_lock->port, dp->dp_Link);
  312.                 continue;
  313.             case ACTION_READ:
  314.             case ACTION_WRITE:
  315.                 fi = (file_info *)dp->dp_Arg1;
  316.                 
  317.                 verify(fi, V_file_info);
  318.                 
  319.                 PutMsg(fi->port, dp->dp_Link);
  320.                 
  321.                 continue;
  322.             case ACTION_FINDUPDATE:
  323.             case ACTION_FINDINPUT:
  324.             case ACTION_FINDOUTPUT:
  325.                 if (!split_data((lock *)(dp->dp_Arg2 << 2), 
  326.                             (b8 *)(dp->dp_Arg3 << 2), &sd)) {
  327.                     /* might be ERROR_NO_FREE_STORE, but hey */
  328.                     dp->dp_Res1 = DOSFALSE;
  329.                     dp->dp_Res2 = ERROR_INVALID_COMPONENT_NAME;
  330.                     break;
  331.                 }
  332.                 
  333.                 PutMsg(sd.port, dp->dp_Link);
  334.                 
  335.                 end_split(&sd);
  336.  
  337.                 continue;
  338.             case ACTION_END:
  339.                 fi = (file_info *)dp->dp_Arg1;
  340.                 
  341.                 verify(fi, V_file_info);
  342.                 
  343.                 PutMsg(fi->port, dp->dp_Link);
  344.                 
  345.                 continue;
  346.             case ACTION_SEEK:
  347.                 fi = (file_info *)dp->dp_Arg1;
  348.                 
  349.                 verify(fi, V_file_info);
  350.                 
  351.                 PutMsg(fi->port, dp->dp_Link);
  352.                 
  353.                 continue;
  354.             case ACTION_WRITE_PROTECT:
  355.                 if (write_protect && dp->dp_Arg1) {
  356.                     dp->dp_Res1 = DOSFALSE;
  357.                     dp->dp_Res2 = ERROR_DISK_WRITE_PROTECTED;
  358.                     break;
  359.                 } else if (!write_protect && !dp->dp_Arg1) {
  360.                     dp->dp_Res1 = DOSTRUE;
  361.                     dp->dp_Res2 = 0;
  362.                     break;
  363.                 } else if (!write_protect && dp->dp_Arg1) {
  364.                     dp->dp_Res1 = DOSTRUE;
  365.                     dp->dp_Res2 = 0;
  366.                     write_protect = 1;
  367.                     pass_key = dp->dp_Arg2;
  368.                     break;
  369.                 } else {
  370.                     if (pass_key == 0 || pass_key == dp->dp_Arg2) {
  371.                         dp->dp_Res1 = DOSTRUE;
  372.                         dp->dp_Res2 = 0;
  373.                         write_protect = 0;
  374.                         pass_key = 0;
  375.                         break;
  376.                     } else {
  377.                         dp->dp_Res1 = DOSFALSE;
  378.                         dp->dp_Res2 = ERROR_DISK_WRITE_PROTECTED;
  379.                         break;
  380.                     }
  381.                 }
  382.                 break;
  383.             case ACTION_FH_FROM_LOCK:
  384.                 my_lock = (lock *)(dp->dp_Arg2 << 2);
  385.                 
  386.                 if (!my_lock) {
  387.                     dp->dp_Res1 = DOSFALSE;
  388.                     dp->dp_Res2 = ERROR_INVALID_LOCK;
  389.                     break;
  390.                 }
  391.                 
  392.                 verify(my_lock, V_lock);
  393.                 
  394.                 PutMsg(my_lock->port, dp->dp_Link);
  395.                 continue;
  396.             case ACTION_IS_FILESYSTEM:
  397.                 dp->dp_Res1 = DOSTRUE;
  398.                 dp->dp_Res2 = 0;
  399.                 break;
  400.             case ACTION_COPY_DIR_FH:
  401.             case ACTION_PARENT_FH:
  402.             case ACTION_EXAMINE_FH:
  403.                 fh = (struct FileHandle *)(dp->dp_Arg1 << 2);
  404.                 
  405.                 fi = (file_info *)fh->fh_Args;
  406.                 verify(fi, V_file_info);
  407.                 
  408.                 PutMsg(fi->port, dp->dp_Link);
  409.                 
  410.                 continue;
  411.             case ACTION_EXAMINE_ALL:
  412.                 my_lock = (lock *)(dp->dp_Arg1 << 2);
  413.                 
  414.                 if (!my_lock) {
  415.                     dp->dp_Res1 = DOSFALSE;
  416.                     dp->dp_Res2 = ERROR_INVALID_LOCK;
  417.                     break;
  418.                 }
  419.                 
  420.                 verify(my_lock, V_lock);
  421.                 
  422.                 PutMsg(my_lock->port, dp->dp_Link);
  423.                 continue;
  424.             case action_IDLE:
  425.                 my_site = (site *)dp->dp_Arg1;
  426.                 
  427.                 dp->dp_Port = ftp_port;
  428.                 PutMsg(reply, dp->dp_Link);    /* send the IDLE back */
  429.                 
  430.                 dp = &my_site->death_packet->sp_Pkt;
  431.                 dp->dp_Type = action_IDLE_DEATH;
  432.                 
  433.                 dp->dp_Port = startup_sync;
  434.                 PutMsg(my_site->port, dp->dp_Link);
  435.                 WaitPort(startup_sync); GetMsg(startup_sync);
  436.                 
  437.                 if (dp->dp_Res1) {
  438.                     my_lock = (lock *)dp->dp_Res2;
  439.                     while (my_lock) {
  440.                         adopt(my_lock, V_lock);
  441.                         my_lock = my_lock->next;
  442.                     }
  443.                     
  444.                     remove_site((site *)my_site);
  445.                 }
  446.                 
  447.                 continue;
  448.             default:
  449.                 show_int(dp->dp_Type);
  450.                 dp->dp_Res1 = DOSFALSE;
  451.                 dp->dp_Res2 = ERROR_ACTION_NOT_KNOWN;
  452.                 break;
  453.             }
  454.             
  455.             dp->dp_Port = ftp_port;
  456.             
  457.             PutMsg(reply, dp->dp_Link);
  458.         }
  459.     }
  460. }
  461.  
  462. void fh_ignore(void)
  463. /* sits on our message port and cancels all actions */
  464. {
  465.     struct Message *msg;
  466.     struct MsgPort *reply;
  467.     struct DosPacket *dp;
  468.     b32 signals;
  469.     lock *l;
  470.     
  471.     signals = (1 << ftp_port->mp_SigBit);
  472.     
  473.     while (1) {
  474.         Wait(signals);
  475.         
  476.         while (msg = GetMsg(ftp_port)) {
  477.             dp = (struct DosPacket *)msg->mn_Node.ln_Name;
  478.             
  479.             if (dp->dp_Type == ACTION_FREE_LOCK) {
  480.                 l = (lock *)(dp->dp_Arg1 << 2);
  481.                 verify(l, V_lock);
  482.                 
  483.                 deallocate(l, V_lock);
  484.                 
  485.                 dp->dp_Res1 = DOSTRUE;
  486.                 dp->dp_Res2 = 0;
  487.             } else {
  488.                 dp->dp_Res1 = DOSFALSE;
  489.                 dp->dp_Res2 = ERROR_ACTION_NOT_KNOWN;
  490.             }
  491.             
  492.             reply = dp->dp_Port;
  493.             dp->dp_Port = ftp_port;
  494.             
  495.             PutMsg(reply, dp->dp_Link);
  496.         }
  497.     }
  498. }
  499.  
  500.