home *** CD-ROM | disk | FTP | other *** search
- /*
- * This source file is Copyright 1995 by Evan Scott.
- * All rights reserved.
- * Permission is granted to distribute this file provided no
- * fees beyond distribution costs are levied.
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <exec/alerts.h>
-
- #include <dos/dos.h>
- #include <dos/dosextens.h>
- #include <dos/dostags.h>
-
- #include <intuition/intuition.h>
-
- #include <libraries/commodities.h>
-
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/commodities.h>
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "evtypes.h"
- #include "verify.h"
- #include "tcp.h"
-
- #include "site.h"
- #include "ftp.h"
- #include "split.h"
- #include "request.h"
-
- #include "globals.h"
-
- struct DosPacket *fh_listen(void)
- {
- struct DosPacket *dp;
- struct MsgPort *reply;
- struct Message *msg;
- struct InfoData *id;
- struct FileHandle *fh;
- file_info *fi;
- b32 signals;
- split sd, sd2;
- lock *my_lock, *lock2;
- site *my_site;
- status_message *sm;
- b8 *s, *name;
-
- b32 pass_key = 0;
- boolean write_protect = false, disabled = false;
-
- signals = (1 << ftp_port->mp_SigBit) | (1 << status_control->mp_SigBit);
-
- while (1) {
- Wait(signals);
-
- while (sm = (status_message *)GetMsg(status_control)) {
- verify(sm, V_status_message);
-
- switch (sm->command) {
- case SM_KILL:
- ReplyMsg(&sm->header);
- return nil;
- case SM_SUSPEND:
- disabled = true;
-
- suspend_sites();
-
- break;
- case SM_RESUME:
- disabled = false;
- break;
- }
- ReplyMsg(&sm->header);
- }
-
- while (msg = GetMsg(ftp_port)) {
- dp = (struct DosPacket *)msg->mn_Node.ln_Name;
-
- reply = dp->dp_Port;
-
- truth(dp->dp_Link == msg);
-
- if (disabled && dp->dp_Type != action_IDLE) {
- dp->dp_Res1 = DOSFALSE;
- dp->dp_Res2 = ERROR_DEVICE_NOT_MOUNTED;
-
- dp->dp_Port = ftp_port;
- PutMsg(reply, dp->dp_Link);
- continue;
- }
-
- switch (dp->dp_Type) {
- case ACTION_NIL:
- dp->dp_Res1 = DOSTRUE;
- dp->dp_Res2 = 0;
- break;
- case ACTION_DIE:
- return dp;
- case ACTION_LOCATE_OBJECT: /* Lock() */
- if (dp->dp_Arg3 != SHARED_LOCK && dp->dp_Arg3 != EXCLUSIVE_LOCK) {
- dp->dp_Res1 = 0;
- dp->dp_Res2 = ERROR_BAD_NUMBER;
- break;
- }
-
- if (!split_data((lock *)(dp->dp_Arg1 << 2),
- (b8 *)(dp->dp_Arg2 << 2), &sd)) {
- /* might be ERROR_NO_FREE_STORE, but hey */
- dp->dp_Res1 = 0;
- dp->dp_Res2 = ERROR_INVALID_COMPONENT_NAME;
- break;
- }
-
- PutMsg(sd.port, dp->dp_Link);
-
- end_split(&sd);
-
- continue;
- case ACTION_RENAME_DISK: /* Relabel() */
- name = (b8 *)(dp->dp_Arg1 << 2);
- s = (b8 *)allocate(name[0] + 2, V_bstr);
- if (!s) {
- dp->dp_Res1 = DOSFALSE;
- dp->dp_Res2 = ERROR_NO_FREE_STORE;
- break;
- }
-
- s[0] = name[0];
- memcpy(&s[1], &name[1], s[0]);
- s[1 + s[0]] = 0;
-
- /* perhaps should do some mutual exclusion here ... */
- ftp_volume->dol_Name = (b32)s >> 2;
-
- deallocate(volume_name, V_bstr);
- volume_name = s;
-
- dp->dp_Res1 = DOSTRUE;
- dp->dp_Res2 = 0;
-
- break;
- case ACTION_FREE_LOCK: /* UnLock() */
- case ACTION_COPY_DIR: /* DupLock() */
- case ACTION_EXAMINE_OBJECT: /* Examine() */
- case ACTION_EXAMINE_NEXT: /* ExNext() */
- case ACTION_PARENT: /* ParentDir() */
- case ACTION_SET_DATE: /* SetFileDate() */
- my_lock = (lock *)(dp->dp_Arg1 << 2);
-
- if (!my_lock) {
- dp->dp_Res1 = DOSFALSE;
- dp->dp_Res2 = ERROR_INVALID_LOCK;
- break;
- }
-
- verify(my_lock, V_lock);
-
- PutMsg(my_lock->port, dp->dp_Link);
- continue;
- case ACTION_SET_PROTECT:
- case ACTION_SET_COMMENT:
- if (!split_data((lock *)(dp->dp_Arg2 << 2),
- (b8 *)(dp->dp_Arg3 << 2), &sd)) {
- dp->dp_Res1 = DOSFALSE;
- dp->dp_Res2 = ERROR_INVALID_COMPONENT_NAME;
- break;
- }
-
- PutMsg(sd.port, dp->dp_Link);
-
- end_split(&sd);
-
- continue;
- case ACTION_RENAME_OBJECT:
- if (!split_data((lock *)(dp->dp_Arg1 << 2),
- (b8 *)(dp->dp_Arg2 << 2), &sd)) {
- dp->dp_Res1 = DOSFALSE;
- dp->dp_Res2 = ERROR_INVALID_COMPONENT_NAME;
- break;
- }
-
- if (!split_data((lock *)(dp->dp_Arg3 << 2),
- (b8 *)(dp->dp_Arg4 << 2), &sd2)) {
- dp->dp_Res1 = DOSFALSE;
- dp->dp_Res2 = ERROR_INVALID_COMPONENT_NAME;
-
- end_split(&sd);
- break;
- }
-
- if (sd.port == local_port &&
- !sd2.path) { /* special case */
-
- PutMsg(local_port, dp->dp_Link);
-
- end_split(&sd);
- end_split(&sd2);
- continue;
- }
-
- if (sd.port != sd2.port) {
- dp->dp_Res1 = DOSFALSE;
- dp->dp_Res2 = ERROR_RENAME_ACROSS_DEVICES;
-
- end_split(&sd);
- end_split(&sd2);
- break;
- }
-
- PutMsg(sd.port, dp->dp_Link);
-
- end_split(&sd);
- end_split(&sd2);
-
- continue;
- case ACTION_DELETE_OBJECT:
- case ACTION_CREATE_DIR:
- if (!split_data((lock *)(dp->dp_Arg1 << 2),
- (b8 *)(dp->dp_Arg2 << 2), &sd)) {
- dp->dp_Res1 = DOSFALSE;
- dp->dp_Res2 = ERROR_INVALID_COMPONENT_NAME;
- break;
- }
-
- PutMsg(sd.port, dp->dp_Link);
-
- end_split(&sd);
-
- continue;
- case ACTION_DISK_INFO:
- id = (struct InfoData *)(dp->dp_Arg1 << 2);
- truth(id != nil);
-
- id->id_NumSoftErrors = 0;
- id->id_UnitNumber = 0;
- if (write_protect)
- id->id_DiskState = ID_WRITE_PROTECTED;
- else
- id->id_DiskState = ID_VALIDATED;
- id->id_NumBlocks = 1;
- id->id_NumBlocksUsed = 1;
- id->id_BytesPerBlock = 1024;
- id->id_DiskType = ID_DOS_DISK;
- id->id_VolumeNode = (b32)ftp_volume >> 2;
- id->id_InUse = 0;
-
- dp->dp_Res1 = DOSTRUE;
- dp->dp_Res2 = 0;
-
- break;
- case ACTION_INFO:
- id = (struct InfoData *)(dp->dp_Arg2 << 2);
- truth(id != nil);
-
- id->id_NumSoftErrors = 0;
- id->id_UnitNumber = 0;
- if (write_protect)
- id->id_DiskState = ID_WRITE_PROTECTED;
- else
- id->id_DiskState = ID_VALIDATED;
- id->id_NumBlocks = 1;
- id->id_NumBlocksUsed = 1;
- id->id_BytesPerBlock = 1024;
- id->id_DiskType = ID_DOS_DISK;
- id->id_VolumeNode = (b32)ftp_volume >> 2;
- id->id_InUse = 0;
-
- dp->dp_Res1 = DOSTRUE;
- dp->dp_Res2 = 0;
-
- break;
- case ACTION_SAME_LOCK:
- my_lock = (lock *)(dp->dp_Arg1 << 2);
- lock2 = (lock *)(dp->dp_Arg2 << 2);
-
- verify(my_lock, V_lock);
- verify(lock2, V_lock);
-
- #ifdef SLDFKJ
- if (my_lock->port == local_port) {
- if (my_lock->rfsl == ftphosts_lock)
- { show_string("lock 1 is ROOT"); }
- else
- { show_string("lock 1 is local lock"); }
- } else {
- show_string(my_lock->fname);
- }
-
- if (lock2->port == local_port) {
- if (lock2->rfsl == ftphosts_lock)
- { show_string("lock 2 is ROOT"); }
- else
- { show_string("lock 2 is local lock"); }
- } else {
- show_string(lock2->fname);
- }
- #endif
-
- if (my_lock->port != lock2->port) {
- dp->dp_Res1 = DOSFALSE;
- dp->dp_Res2 = ERROR_INVALID_LOCK;
- break;
- }
-
- PutMsg(my_lock->port, dp->dp_Link);
- continue;
- case ACTION_READ:
- case ACTION_WRITE:
- fi = (file_info *)dp->dp_Arg1;
-
- verify(fi, V_file_info);
-
- PutMsg(fi->port, dp->dp_Link);
-
- continue;
- case ACTION_FINDUPDATE:
- case ACTION_FINDINPUT:
- case ACTION_FINDOUTPUT:
- if (!split_data((lock *)(dp->dp_Arg2 << 2),
- (b8 *)(dp->dp_Arg3 << 2), &sd)) {
- /* might be ERROR_NO_FREE_STORE, but hey */
- dp->dp_Res1 = DOSFALSE;
- dp->dp_Res2 = ERROR_INVALID_COMPONENT_NAME;
- break;
- }
-
- PutMsg(sd.port, dp->dp_Link);
-
- end_split(&sd);
-
- continue;
- case ACTION_END:
- fi = (file_info *)dp->dp_Arg1;
-
- verify(fi, V_file_info);
-
- PutMsg(fi->port, dp->dp_Link);
-
- continue;
- case ACTION_SEEK:
- fi = (file_info *)dp->dp_Arg1;
-
- verify(fi, V_file_info);
-
- PutMsg(fi->port, dp->dp_Link);
-
- continue;
- case ACTION_WRITE_PROTECT:
- if (write_protect && dp->dp_Arg1) {
- dp->dp_Res1 = DOSFALSE;
- dp->dp_Res2 = ERROR_DISK_WRITE_PROTECTED;
- break;
- } else if (!write_protect && !dp->dp_Arg1) {
- dp->dp_Res1 = DOSTRUE;
- dp->dp_Res2 = 0;
- break;
- } else if (!write_protect && dp->dp_Arg1) {
- dp->dp_Res1 = DOSTRUE;
- dp->dp_Res2 = 0;
- write_protect = 1;
- pass_key = dp->dp_Arg2;
- break;
- } else {
- if (pass_key == 0 || pass_key == dp->dp_Arg2) {
- dp->dp_Res1 = DOSTRUE;
- dp->dp_Res2 = 0;
- write_protect = 0;
- pass_key = 0;
- break;
- } else {
- dp->dp_Res1 = DOSFALSE;
- dp->dp_Res2 = ERROR_DISK_WRITE_PROTECTED;
- break;
- }
- }
- break;
- case ACTION_FH_FROM_LOCK:
- my_lock = (lock *)(dp->dp_Arg2 << 2);
-
- if (!my_lock) {
- dp->dp_Res1 = DOSFALSE;
- dp->dp_Res2 = ERROR_INVALID_LOCK;
- break;
- }
-
- verify(my_lock, V_lock);
-
- PutMsg(my_lock->port, dp->dp_Link);
- continue;
- case ACTION_IS_FILESYSTEM:
- dp->dp_Res1 = DOSTRUE;
- dp->dp_Res2 = 0;
- break;
- case ACTION_COPY_DIR_FH:
- case ACTION_PARENT_FH:
- case ACTION_EXAMINE_FH:
- fh = (struct FileHandle *)(dp->dp_Arg1 << 2);
-
- fi = (file_info *)fh->fh_Args;
- verify(fi, V_file_info);
-
- PutMsg(fi->port, dp->dp_Link);
-
- continue;
- case ACTION_EXAMINE_ALL:
- my_lock = (lock *)(dp->dp_Arg1 << 2);
-
- if (!my_lock) {
- dp->dp_Res1 = DOSFALSE;
- dp->dp_Res2 = ERROR_INVALID_LOCK;
- break;
- }
-
- verify(my_lock, V_lock);
-
- PutMsg(my_lock->port, dp->dp_Link);
- continue;
- case action_IDLE:
- my_site = (site *)dp->dp_Arg1;
-
- dp->dp_Port = ftp_port;
- PutMsg(reply, dp->dp_Link); /* send the IDLE back */
-
- dp = &my_site->death_packet->sp_Pkt;
- dp->dp_Type = action_IDLE_DEATH;
-
- dp->dp_Port = startup_sync;
- PutMsg(my_site->port, dp->dp_Link);
- WaitPort(startup_sync); GetMsg(startup_sync);
-
- if (dp->dp_Res1) {
- my_lock = (lock *)dp->dp_Res2;
- while (my_lock) {
- adopt(my_lock, V_lock);
- my_lock = my_lock->next;
- }
-
- remove_site((site *)my_site);
- }
-
- continue;
- default:
- show_int(dp->dp_Type);
- dp->dp_Res1 = DOSFALSE;
- dp->dp_Res2 = ERROR_ACTION_NOT_KNOWN;
- break;
- }
-
- dp->dp_Port = ftp_port;
-
- PutMsg(reply, dp->dp_Link);
- }
- }
- }
-
- void fh_ignore(void)
- /* sits on our message port and cancels all actions */
- {
- struct Message *msg;
- struct MsgPort *reply;
- struct DosPacket *dp;
- b32 signals;
- lock *l;
-
- signals = (1 << ftp_port->mp_SigBit);
-
- while (1) {
- Wait(signals);
-
- while (msg = GetMsg(ftp_port)) {
- dp = (struct DosPacket *)msg->mn_Node.ln_Name;
-
- if (dp->dp_Type == ACTION_FREE_LOCK) {
- l = (lock *)(dp->dp_Arg1 << 2);
- verify(l, V_lock);
-
- deallocate(l, V_lock);
-
- dp->dp_Res1 = DOSTRUE;
- dp->dp_Res2 = 0;
- } else {
- dp->dp_Res1 = DOSFALSE;
- dp->dp_Res2 = ERROR_ACTION_NOT_KNOWN;
- }
-
- reply = dp->dp_Port;
- dp->dp_Port = ftp_port;
-
- PutMsg(reply, dp->dp_Link);
- }
- }
- }
-
-