home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magazyn Amiga Shareware Floppies
/
ma64.dms
/
ma64.adf
/
FTPMount-1.0
/
Source
/
local.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-06
|
18KB
|
901 lines
/*
* 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 <proto/exec.h>
#include <proto/dos.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 "local.h"
#include "globals.h"
#define DOSBase _local_DOSBase
struct DosLibrary *DOSBase;
BSTR ctobstr(b8 *s)
{
b8 *z;
int len;
len = strlen(s);
z = (b8 *)allocate(len + 1, V_bstr);
if (!z) return 0;
z[0] = len;
if (len > 0) {
memcpy(&z[1], s, len);
}
return (BSTR)((b32)z >> 2);
}
void free_bstr(BSTR b)
{
deallocate((void *)(b << 2), V_bstr);
}
void lock_message(BPTR l, struct DosPacket *dp)
{
struct FileLock *fl;
fl = (struct FileLock *)(l << 2);
PutMsg(fl->fl_Task, dp->dp_Link);
}
void __saveds local_handler(void)
{
struct Process *me;
struct Message *msg;
struct DosPacket *dp;
struct MsgPort *local, *reply, *sync;
b32 signals;
split sd, sd2;
lock *locks, **slock, *new_lock, *nlock;
b32 rfsl; /* real file system lock */
struct FileInfoBlock *fib;
struct FileHandle *fh;
file_info *fi;
b32 o1, o2, o3, o4; /* stores for original dp->dp_Arg1 etc */
BSTR b, b2;
locks = 0;
mem_tracking_on();
me = (struct Process *)FindTask(0l);
local = &me->pr_MsgPort;
WaitPort(local);
msg = GetMsg(local);
dp = (struct DosPacket *)msg->mn_Node.ln_Name;
reply = dp->dp_Port;
dp->dp_Port = local;
sync = CreatePort(0, 0);
if (!sync) {
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
PutMsg(reply, dp->dp_Link);
return;
}
/* do I really need DOSBase open now that I'm packeting? */
DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 36);
if (!DOSBase) {
DeletePort(sync);
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_INVALID_RESIDENT_LIBRARY;
PutMsg(reply, dp->dp_Link);
return;
} else {
dp->dp_Res1 = DOSTRUE;
}
dp->dp_Res2 = 0;
PutMsg(reply, dp->dp_Link);
signals = (1 << local->mp_SigBit);
while (1) {
Wait(signals);
while (msg = GetMsg(local)) {
dp = (struct DosPacket *)msg->mn_Node.ln_Name;
reply = dp->dp_Port;
truth(dp->dp_Link == msg);
switch (dp->dp_Type) {
case ACTION_DIE:
/* close all locks */
nlock = locks;
while (nlock) {
new_lock = nlock->next;
if (nlock->rfsl != ftphosts_lock)
UnLock(nlock->rfsl);
disown(nlock, V_lock);
nlock = new_lock;
}
CloseLibrary((struct Library *)DOSBase);
DeletePort(sync);
Forbid();
dp->dp_Res1 = DOSTRUE;
dp->dp_Res2 = (b32)locks; /* so they can adopt them */
PutMsg(reply, dp->dp_Link);
check_memory();
return;
case ACTION_LOCATE_OBJECT:
if (!split_data((lock *)(dp->dp_Arg1 << 2),
(b8 *)(dp->dp_Arg2 << 2), &sd)) {
dp->dp_Res1 = 0;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
break;
}
new_lock = (lock *)allocate(sizeof(*new_lock), V_lock);
if (!new_lock) {
show_string("XX2");
dp->dp_Res1 = 0;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
end_split(&sd);
break;
}
if (!sd.path) { /* they want the root */
if (dp->dp_Arg3 == EXCLUSIVE_LOCK) {
deallocate(new_lock, V_lock);
end_split(&sd);
dp->dp_Res1 = 0;
dp->dp_Res2 = ERROR_OBJECT_IN_USE;
break;
}
rfsl = ftphosts_lock;
} else {
o1 = dp->dp_Arg1;
o2 = dp->dp_Arg2;
dp->dp_Arg1 = ftphosts_lock;
b = ctobstr(sd.path);
if (!b) {
deallocate(new_lock, V_lock);
end_split(&sd);
dp->dp_Res1 = 0;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
break;
}
dp->dp_Arg2 = b;
dp->dp_Port = sync;
lock_message(ftphosts_lock, dp);
WaitPort(sync); GetMsg(sync);
dp->dp_Arg1 = o1;
dp->dp_Arg2 = o2;
free_bstr(b);
rfsl = dp->dp_Res1;
}
if (!rfsl) {
deallocate(new_lock, V_lock);
end_split(&sd);
break;
}
ensure(new_lock, V_lock);
new_lock->port = local;
new_lock->next = locks;
locks = new_lock;
new_lock->rfsl = rfsl;
new_lock->fl.fl_Access = dp->dp_Arg3;
new_lock->fl.fl_Task = ftp_port;
new_lock->fl.fl_Volume = (b32)ftp_volume >> 2;
end_split(&sd);
dp->dp_Res1 = (b32)new_lock >> 2;
dp->dp_Res2 = 0;
break;
case ACTION_FREE_LOCK:
slock = &locks;
new_lock = (lock *)(dp->dp_Arg1 << 2);
while (*slock && *slock != new_lock) {
slock = &(*slock)->next;
}
if (!*slock) {
show_string("Free lock failed");
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_INVALID_LOCK;
break;
}
verify(new_lock, V_lock);
*slock = new_lock->next;
if (new_lock->rfsl != ftphosts_lock) {
dp->dp_Port = sync;
o1 = dp->dp_Arg1;
dp->dp_Arg1 = new_lock->rfsl;
lock_message(new_lock->rfsl, dp);
WaitPort(sync); GetMsg(sync);
dp->dp_Arg1 = o1;
}
deallocate(new_lock, V_lock);
dp->dp_Res1 = DOSTRUE;
dp->dp_Res2 = 0;
break;
case ACTION_DELETE_OBJECT:
if (!split_data((lock *)(dp->dp_Arg1 << 2),
(b8 *)(dp->dp_Arg2 << 2), &sd)) {
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
break;
}
o1 = dp->dp_Arg1;
o2 = dp->dp_Arg2;
dp->dp_Arg1 = ftphosts_lock;
b = ctobstr(sd.path);
if (!b) {
end_split(&sd);
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
break;
}
dp->dp_Arg2 = b;
dp->dp_Port = sync;
lock_message(ftphosts_lock, dp);
WaitPort(sync); GetMsg(sync);
dp->dp_Arg1 = o1;
dp->dp_Arg2 = o2;
free_bstr(b);
end_split(&sd);
break;
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_NO_FREE_STORE;
break;
}
if (!split_data((lock *)(dp->dp_Arg3 << 2),
(b8 *)(dp->dp_Arg4 << 2), &sd2)) {
end_split(&sd);
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
break;
}
o1 = dp->dp_Arg1;
o2 = dp->dp_Arg2;
o3 = dp->dp_Arg3;
o4 = dp->dp_Arg4;
if (!sd2.path) { /* this is rename Unnamed1 to "ucc.gu.uwa..." */
if (sd2.work) deallocate(sd2.work, V_cstr);
sd2.work = (b8 *)allocate(strlen(sd2.port->mp_Node.ln_Name) + 1, V_cstr);
if (!sd2.work) {
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
end_split(&sd);
end_split(&sd2);
break;
}
strcpy(sd2.work, sd2.port->mp_Node.ln_Name);
sd2.path = sd2.work;
}
b = ctobstr(sd.path);
b2 = ctobstr(sd2.path);
if (!b || !b2) {
if (b) free_bstr(b);
if (b2) free_bstr(b2);
end_split(&sd);
end_split(&sd2);
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
break;
}
dp->dp_Arg1 = ftphosts_lock;
dp->dp_Arg2 = b;
dp->dp_Arg3 = ftphosts_lock;
dp->dp_Arg4 = b2;
dp->dp_Port = sync;
lock_message(ftphosts_lock, dp);
WaitPort(sync); GetMsg(sync);
dp->dp_Arg1 = o1;
dp->dp_Arg2 = o2;
dp->dp_Arg3 = o3;
dp->dp_Arg4 = o4;
free_bstr(b);
free_bstr(b2);
end_split(&sd);
end_split(&sd2);
break;
case ACTION_COPY_DIR:
new_lock = (lock *)(dp->dp_Arg1 << 2);
verify(new_lock, V_lock);
rfsl = new_lock->rfsl;
new_lock = (lock *)allocate(sizeof(*new_lock), V_lock);
if (!new_lock) {
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
show_string("DupLock failed 1");
break;
}
if (rfsl != ftphosts_lock) {
o1 = dp->dp_Arg1;
dp->dp_Arg1 = rfsl;
dp->dp_Port = sync;
lock_message(rfsl, dp);
WaitPort(sync); GetMsg(sync);
rfsl = dp->dp_Res1;
dp->dp_Arg1 = o1;
}
if (!rfsl) {
deallocate(new_lock, V_lock);
show_string("DupLock failed 2");
break;
}
ensure(new_lock, V_lock);
new_lock->port = local;
new_lock->next = locks;
locks = new_lock;
new_lock->rfsl = rfsl;
new_lock->fl.fl_Access = SHARED_LOCK;
new_lock->fl.fl_Task = ftp_port;
new_lock->fl.fl_Volume = (b32)ftp_volume >> 2;
dp->dp_Res1 = (b32)new_lock >> 2;
dp->dp_Res2 = 0;
break;
case ACTION_SET_PROTECT:
if (!split_data((lock *)(dp->dp_Arg2 << 2),
(b8 *)(dp->dp_Arg3 << 2), &sd)) {
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
break;
}
o2 = dp->dp_Arg2;
o3 = dp->dp_Arg3;
dp->dp_Arg2 = ftphosts_lock;
b = ctobstr(sd.path);
if (!b) {
end_split(&sd);
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
break;
}
dp->dp_Arg3 = b;
dp->dp_Port = sync;
lock_message(ftphosts_lock, dp);
WaitPort(sync); GetMsg(sync);
dp->dp_Arg2 = o2;
dp->dp_Arg3 = o3;
free_bstr(b);
end_split(&sd);
break;
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_NO_FREE_STORE;
break;
}
o1 = dp->dp_Arg1;
o2 = dp->dp_Arg2;
dp->dp_Arg1 = ftphosts_lock;
b = ctobstr(sd.path);
if (!b) {
end_split(&sd);
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
break;
}
dp->dp_Arg2 = b;
dp->dp_Port = sync;
lock_message(ftphosts_lock, dp);
WaitPort(sync); GetMsg(sync);
dp->dp_Arg1 = o1;
dp->dp_Arg2 = o2;
free_bstr(b);
end_split(&sd);
break;
case ACTION_EXAMINE_OBJECT:
new_lock = (lock *)(dp->dp_Arg1 << 2);
fib = (struct FileInfoBlock *)(dp->dp_Arg2 << 2);
verify(new_lock, V_lock);
truth(fib != nil);
o1 = dp->dp_Arg1;
dp->dp_Arg1 = new_lock->rfsl;
dp->dp_Port = sync;
lock_message(new_lock->rfsl, dp);
WaitPort(sync); GetMsg(sync);
dp->dp_Arg1 = o1;
if (!dp->dp_Res1) break;
if (new_lock->rfsl == ftphosts_lock) {
strcpy(fib->fib_FileName, volume_name);
}
break;
case ACTION_EXAMINE_NEXT:
new_lock = (lock *)(dp->dp_Arg1 << 2);
fib = (struct FileInfoBlock *)(dp->dp_Arg2 << 2);
verify(new_lock, V_lock);
truth(fib != nil);
o1 = dp->dp_Arg1;
dp->dp_Arg1 = new_lock->rfsl;
dp->dp_Port = sync;
lock_message(new_lock->rfsl, dp);
WaitPort(sync); GetMsg(sync);
dp->dp_Arg1 = o1;
break;
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_NO_FREE_STORE;
break;
}
o2 = dp->dp_Arg2;
o3 = dp->dp_Arg3;
dp->dp_Arg2 = ftphosts_lock;
b = ctobstr(sd.path);
if (!b) {
end_split(&sd);
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
break;
}
dp->dp_Arg3 = b;
dp->dp_Port = sync;
lock_message(ftphosts_lock, dp);
WaitPort(sync); GetMsg(sync);
dp->dp_Arg2 = o2;
dp->dp_Arg3 = o3;
free_bstr(b);
end_split(&sd);
break;
case ACTION_PARENT:
new_lock = (lock *)(dp->dp_Arg1 << 2);
verify(new_lock, V_lock);
if (new_lock->rfsl == ftphosts_lock) {
dp->dp_Res1 = 0;
dp->dp_Res2 = 0;
break;
}
/* fall through */
case ACTION_PARENT_FH:
new_lock = (lock *)allocate(sizeof(*new_lock), V_lock);
if (!new_lock) {
dp->dp_Res1 = 0;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
break;
}
ensure(new_lock, V_lock);
new_lock->port = local;
new_lock->next = locks;
locks = new_lock;
new_lock->rfsl = ftphosts_lock;
new_lock->fl.fl_Access = SHARED_LOCK;
new_lock->fl.fl_Task = ftp_port;
new_lock->fl.fl_Volume = (b32)ftp_volume >> 2;
dp->dp_Res1 = (b32)new_lock >> 2;
dp->dp_Res2 = 0;
break;
case ACTION_SET_DATE:
new_lock = (lock *)(dp->dp_Arg1 << 2);
verify(new_lock, V_lock);
o1 = dp->dp_Arg1;
dp->dp_Arg1 = new_lock->rfsl;
dp->dp_Port = sync;
lock_message(new_lock->rfsl, dp);
WaitPort(sync); GetMsg(sync);
dp->dp_Arg1 = o1;
break;
case ACTION_SAME_LOCK:
new_lock = (lock *)(dp->dp_Arg1 << 2);
verify(new_lock, V_lock);
if (new_lock->rfsl == ftphosts_lock) {
new_lock = (lock *)(dp->dp_Arg2 << 2);
verify(new_lock, V_lock);
if (new_lock->rfsl == ftphosts_lock) {
dp->dp_Res1 = DOSTRUE;
} else {
dp->dp_Res1 = DOSFALSE;
}
dp->dp_Res2 = 0;
break;
}
rfsl = new_lock->rfsl;
new_lock = (lock *)(dp->dp_Arg2 << 2);
verify(new_lock, V_lock);
o1 = dp->dp_Arg1;
o2 = dp->dp_Arg2;
dp->dp_Arg1 = rfsl;
dp->dp_Arg2 = new_lock->rfsl;
dp->dp_Port = sync;
lock_message(rfsl, dp);
WaitPort(sync); GetMsg(sync);
dp->dp_Arg1 = o1;
dp->dp_Arg2 = o2;
break;
case ACTION_READ:
case ACTION_WRITE:
fi = (file_info *)dp->dp_Arg1;
verify(fi, V_file_info);
o1 = dp->dp_Arg1;
dp->dp_Arg1 = fi->rfarg;
dp->dp_Port = sync;
lock_message(ftphosts_lock, dp);
WaitPort(sync); GetMsg(sync);
dp->dp_Arg1 = o1;
break;
case ACTION_FINDUPDATE:
case ACTION_FINDINPUT:
case ACTION_FINDOUTPUT:
if (!split_data((lock *)(dp->dp_Arg2 << 2),
(b8 *)(dp->dp_Arg3 << 2), &sd)) {
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
break;
}
fi = (file_info *)allocate(sizeof(*fi), V_file_info);
if (!fi) {
end_split(&sd);
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
break;
}
ensure(fi, V_file_info);
fh = (struct FileHandle *)(dp->dp_Arg1 << 2);
truth(fh != nil);
o2 = dp->dp_Arg2;
o3 = dp->dp_Arg3;
dp->dp_Arg2 = ftphosts_lock;
b = ctobstr(sd.path);
if (!b) {
deallocate(fi, V_file_info);
end_split(&sd);
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
break;
}
dp->dp_Arg3 = b;
dp->dp_Port = sync;
lock_message(ftphosts_lock, dp);
WaitPort(sync); GetMsg(sync);
dp->dp_Arg2 = o2;
dp->dp_Arg3 = o3;
free_bstr(b);
if (dp->dp_Res1) {
fh->fh_Type = ftp_port;
fi->rfarg = fh->fh_Args;
fh->fh_Args = (b32)fi;
fi->port = local;
fi->type = dp->dp_Type;
} else {
deallocate(fi, V_file_info);
}
end_split(&sd);
break;
case ACTION_END:
fi = (file_info *)dp->dp_Arg1;
verify(fi, V_file_info);
o1 = dp->dp_Arg1;
dp->dp_Arg1 = fi->rfarg;
dp->dp_Port = sync;
lock_message(ftphosts_lock, dp);
WaitPort(sync); GetMsg(sync);
dp->dp_Arg1 = o1;
deallocate(fi, V_file_info);
break;
case ACTION_SEEK:
fi = (file_info *)dp->dp_Arg1;
verify(fi, V_file_info);
o1 = dp->dp_Arg1;
dp->dp_Arg1 = fi->rfarg;
dp->dp_Port = sync;
lock_message(ftphosts_lock, dp);
WaitPort(sync); GetMsg(sync);
dp->dp_Arg1 = o1;
break;
case ACTION_FH_FROM_LOCK:
fh = (struct FileHandle *)(dp->dp_Arg1 << 2);
nlock = (lock *)(dp->dp_Arg2 << 2);
verify(nlock, V_lock);
truth(fh != nil);
fi = (file_info *)allocate(sizeof(*fi), V_file_info);
if (!fi) {
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
break;
}
ensure(fi, V_file_info);
o2 = dp->dp_Arg2;
dp->dp_Arg2 = nlock->rfsl;
dp->dp_Port = sync;
lock_message(ftphosts_lock, dp);
WaitPort(sync); GetMsg(sync);
dp->dp_Arg2 = o2;
if (dp->dp_Res1) {
fh->fh_Type = ftp_port;
fi->rfarg = fh->fh_Args;
fh->fh_Args = (b32)fi;
fi->port = local;
fi->type = dp->dp_Type;
} else {
deallocate(fi, V_file_info);
}
break;
case ACTION_COPY_DIR_FH:
fh = (struct FileHandle *)(dp->dp_Arg1 << 2);
fi = (file_info *)fh->fh_Args;
new_lock = (lock *)allocate(sizeof(*new_lock), V_lock);
if (!new_lock) {
dp->dp_Res1 = 0;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
break;
}
ensure(new_lock, V_lock);
new_lock->port = local;
new_lock->fl.fl_Access = SHARED_LOCK;
new_lock->fl.fl_Task = ftp_port;
new_lock->fl.fl_Volume = (b32)ftp_volume >> 2;
verify(fi, V_file_info);
fh->fh_Args = fi->rfarg;
dp->dp_Port = sync;
lock_message(ftphosts_lock, dp);
WaitPort(sync); GetMsg(sync);
fh->fh_Args = (b32)fi;
if (dp->dp_Res1) {
new_lock->rfsl = dp->dp_Res1;
new_lock->next = locks;
locks = new_lock;
dp->dp_Res1 = (b32)new_lock >> 2;
dp->dp_Res2 = 0;
} else {
deallocate(new_lock, V_lock);
}
break;
case ACTION_EXAMINE_FH:
fh = (struct FileHandle *)(dp->dp_Arg1 << 2);
fi = (file_info *)fh->fh_Args;
verify(fi, V_file_info);
fh->fh_Args = fi->rfarg;
dp->dp_Port = sync;
lock_message(ftphosts_lock, dp);
WaitPort(sync); GetMsg(sync);
fh->fh_Args = (b32)fi;
break;
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);
}
}
}