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 <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/graphics.h>
- #include <proto/intuition.h>
- #include <proto/locale.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 "local.h"
- #include "request.h"
-
- #define DECLARE_GLOBALS_HERE 1
- #include "globals.h"
- #include "strings.h"
-
- struct DosPacket *fh_listen(void);
- void fh_ignore(void);
-
- boolean launch_tcp_handler(void);
- boolean launch_local(void);
- void shutdown_tcp_handler(void);
- void shutdown_local(void);
-
- boolean open_libraries(void);
- void close_libraries(void);
-
- boolean make_gims(void);
- void free_gims(void);
-
- void startup_error(b8 *s);
-
- boolean get_anon_login(void);
-
- boolean create_volume(void);
- void destroy_volume(void);
-
- boolean launch_status(void);
- void shutdown_status(void);
-
- void setup_strings(void);
- void cleanup_strings(void);
-
- void __saveds start(void)
- {
- struct Process *me;
- struct Message *msg;
- struct DosPacket *dp;
- struct MsgPort *reply;
- struct DateTime dtime;
- b8 temp[15];
-
- SysBase = *(struct ExecBase **)4;
-
- me = (struct Process *)FindTask(0l);
-
- ftp_port = &me->pr_MsgPort;
-
- WaitPort(ftp_port); /* wait for startup packet */
- msg = GetMsg(ftp_port);
-
- dp = (struct DosPacket *)msg->mn_Node.ln_Name;
- reply = dp->dp_Port;
- dp->dp_Port = ftp_port;
-
- ftp_device = (struct DosList *)(dp->dp_Arg3 << 2);
- ftp_device->dol_Task = ftp_port; /* fill in our message port */
-
- /* get down to initializing everything */
-
- sites = nil;
- orphaned_locks = nil;
-
- if (open_libraries()) {
- ftpdir_lock = Lock("FTPMountDir:", SHARED_LOCK);
- if (ftpdir_lock) {
- UnLock(CurrentDir(ftpdir_lock));
- UnLock(SetProgramDir(ftpdir_lock));
-
- /* setup PROGDIR: so we can open the catalog asap */
-
- setup_strings();
-
- mem_tracking_on();
-
- DateStamp(&dtime.dat_Stamp);
-
- dtime.dat_StrDate = temp;
- dtime.dat_StrDay = nil;
- dtime.dat_StrTime = nil;
- dtime.dat_Flags = 0;
- dtime.dat_Format = FORMAT_INT;
-
- DateToStr(&dtime);
-
- year = atoi(temp);
-
- if (year >= 78) year += 1900;
- else year += 2000;
-
- if (get_anon_login()) {
- if (make_gims()) {
- if (launch_tcp_handler()) {
- if (launch_local()) {
- ftphosts_lock = Lock(strings[MSG_HOSTS], SHARED_LOCK);
- if (ftphosts_lock) {
- if (launch_status()) {
- if (create_volume()) {
- /* initialization is complete */
- dp->dp_Res1 = DOSTRUE;
- dp->dp_Res2 = 0;
-
- PutMsg(reply, dp->dp_Link);
-
- dp = fh_listen();
-
- /* only comes back on a DIE */
-
- shutdown_sites();
-
- shutdown_status();
- shutdown_local();
- shutdown_tcp_handler();
-
- UnLock(ftphosts_lock);
- UnLock(ftpdir_lock);
-
- free_gims();
-
- if (anon_login)
- deallocate(anon_login, V_cstr);
-
- destroy_volume();
-
- check_memory();
-
- close_libraries();
-
- if (dp) {
- dp->dp_Res1 = DOSTRUE;
- dp->dp_Res2 = 0;
-
- reply = dp->dp_Port;
- dp->dp_Port = ftp_port;
-
- PutMsg(reply, dp->dp_Link);
- }
-
- fh_ignore(); /* never comes back */
- } else dp->dp_Res2 = ERROR_NO_FREE_STORE;
- shutdown_status();
- } else dp->dp_Res2 = ERROR_NO_FREE_STORE;
- UnLock(ftphosts_lock);
- } else {
- startup_error(strings[MSG_CANT_FIND_HOSTS]);
- dp->dp_Res2 = ERROR_DIR_NOT_FOUND;
- }
- shutdown_local();
- } else dp->dp_Res2 = ERROR_NO_FREE_STORE;
- shutdown_tcp_handler();
- } else dp->dp_Res2 = ERROR_NO_FREE_STORE;
- free_gims();
- } else dp->dp_Res2 = ERROR_NO_FREE_STORE;
- if (anon_login) deallocate(anon_login, V_cstr);
- } else dp->dp_Res2 = ERROR_REQUIRED_ARG_MISSING;
-
- check_memory();
-
- cleanup_strings();
-
- SetProgramDir(0);
- CurrentDir(0);
-
- UnLock(ftpdir_lock);
- } else dp->dp_Res2 = ERROR_DIR_NOT_FOUND;
- close_libraries();
- } else dp->dp_Res2 = ERROR_INVALID_RESIDENT_LIBRARY;
-
- ftp_device->dol_Task = 0;
-
- dp->dp_Res1 = DOSFALSE;
-
- Forbid(); /* this is so they can't unloadseg us until we have finished */
- PutMsg(reply, dp->dp_Link);
- return;
- }
-
- /* has to be after the startup function */
- #include "verify_code.h"
-
- void startup_error(b8 *s)
- {
- struct EasyStruct es;
-
- es.es_StructSize = sizeof(struct EasyStruct);
- es.es_Flags = 0;
- es.es_Title = strings[MSG_FTPM_STARTUP_ERROR];
- es.es_GadgetFormat = strings[MSG_OK];
- es.es_TextFormat = s;
-
- EasyRequest(nil, &es, nil);
- }
-
- boolean launch_tcp_handler(void)
- {
- struct Process *child;
- tcpmessage *tm;
-
- unique_name(FindTask(0), ": FTPMount", unique_buffer);
-
- startup_sync = CreatePort(unique_buffer, 0);
- if (startup_sync) {
- child = CreateNewProcTags(
- NP_Entry, tcp_handler,
- NP_Arguments, unique_buffer,
- NP_Name, strings[MSG_TCP_HANDLER],
- NP_StackSize, 6000,
- TAG_END, 0
- );
- if (child) {
- Wait(1 << startup_sync->mp_SigBit);
- tm = (tcpmessage *)GetMsg(startup_sync);
-
- if (tm) {
- verify(tm, V_tcpmessage);
-
- if (tm->result) {
- tcp = tm->data;
- ReplyMsg(&tm->header);
-
- WaitPort(startup_sync);
- prime = (tcpmessage *)GetMsg(startup_sync);
-
- /* ok! off we trundle */
-
- prime->command = TCP_SERVICE;
- prime->data = strings[MSG_SERVICE];
-
- PutMsg(tcp, &prime->header);
- WaitPort(startup_sync); GetMsg(startup_sync);
-
- if (prime->result) {
- ftp_port_number = prime->port.w;
- } else {
- ftp_port_number = 0; /* fill it in at connect time */
- }
-
- return true;
- }
- ReplyMsg(&tm->header);
-
- /* whether child is still alive here??? */
- }
- }
- DeletePort(startup_sync);
- }
-
- startup_error(strings[MSG_CANT_LAUNCH_TCP]);
-
- return false;
- }
-
- void shutdown_tcp_handler(void)
- {
- prime->command = TCP_DIE;
- prime->header.mn_ReplyPort = startup_sync;
-
- PutMsg(tcp, &prime->header);
-
- Wait(1 << startup_sync->mp_SigBit); /* Wait til the child signals it is dead */
-
- DeletePort(startup_sync);
- return;
- }
-
- boolean launch_local(void)
- {
- struct StandardPacket *sp;
- struct Process *child;
-
- sp = (struct StandardPacket *)allocate_flags(sizeof(*sp), MEMF_PUBLIC, V_StandardPacket);
- if (!sp) return false;
-
- local_msg = &sp->sp_Msg;
- local_msg->mn_Node.ln_Name = (char *)&sp->sp_Pkt;
- sp->sp_Pkt.dp_Link = local_msg;
-
- sp->sp_Pkt.dp_Type = ACTION_DIE; /* for startup it should ignore this :) */
-
- sp->sp_Pkt.dp_Port = startup_sync; /* this is bad programming ... increases linkage */
-
- child = CreateNewProcTags(
- NP_Entry, local_handler,
- NP_Name, strings[MSG_LOCAL_HANDLER],
- NP_StackSize, 6000,
- TAG_END, 0
- );
- if (child) {
- local_port = &child->pr_MsgPort;
-
- PutMsg(local_port, local_msg);
- WaitPort(startup_sync); GetMsg(startup_sync);
-
- if (sp->sp_Pkt.dp_Res1) {
- return true;
- }
- }
-
- deallocate(sp, V_StandardPacket);
-
- startup_error(strings[MSG_CANT_LAUNCH_LOCAL]);
-
- return false;
- }
-
- void shutdown_local(void)
- {
- struct StandardPacket *sp;
-
- sp = (struct StandardPacket *)local_msg;
-
- sp->sp_Pkt.dp_Port = startup_sync;
-
- PutMsg(local_port, local_msg);
- WaitPort(startup_sync); GetMsg(startup_sync);
-
- deallocate(sp, V_StandardPacket);
-
- return;
- }
-
- boolean open_libraries(void)
- {
- IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36);
- if (IntuitionBase) {
- DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 36);
- if (DOSBase) {
- GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0);
- if (GfxBase) {
- IconBase = OpenLibrary("icon.library", 0);
- LocaleBase = OpenLibrary("locale.library", 0);
-
- return true;
- } else startup_error("FTPMount cannot open graphics.library");
- CloseLibrary((struct Library *)DOSBase);
- } else startup_error("FTPMount requires V36 dos.library");
- CloseLibrary((struct Library *)IntuitionBase);
- }
-
- return false;
- }
-
- void close_libraries(void)
- {
- if (LocaleBase) CloseLibrary(LocaleBase);
- if (IconBase) CloseLibrary(IconBase);
- CloseLibrary((struct Library *)GfxBase);
- CloseLibrary((struct Library *)DOSBase);
- CloseLibrary((struct Library *)IntuitionBase);
- }
-
- boolean make_gims(void)
- {
- struct Screen *s;
- struct DrawInfo *drawinfo;
-
- s = LockPubScreen(nil);
- if (!s) return false;
-
- lightpen = 2;
- darkpen = 1;
- textpen = 1;
- fillpen = 3;
-
- drawinfo = GetScreenDrawInfo(s);
- if (drawinfo) {
- if (drawinfo->dri_NumPens > SHADOWPEN) {
- lightpen = drawinfo->dri_Pens[SHINEPEN];
- darkpen = drawinfo->dri_Pens[SHADOWPEN];
- textpen = drawinfo->dri_Pens[TEXTPEN];
- fillpen = drawinfo->dri_Pens[FILLPEN];
- }
- FreeScreenDrawInfo(s, drawinfo);
- }
-
- cancel_gim = make_gim(strings[MSG_CANCEL], textpen, lightpen, darkpen, s, IntuitionBase, GfxBase);
- if (cancel_gim) {
- abort_gim = make_gim(strings[MSG_ABORT], textpen, lightpen, darkpen, s, IntuitionBase, GfxBase);
- if (abort_gim) {
- disconnect_gim = make_gim(strings[MSG_DISCONNECT], textpen, lightpen, darkpen, s, IntuitionBase, GfxBase);
- if (disconnect_gim) {
- login_gim = make_gim(strings[MSG_LOGIN], textpen, lightpen, darkpen, s, IntuitionBase, GfxBase);
- if (login_gim) {
- UnlockPubScreen(nil, s);
- return true;
- }
- free_gim(disconnect_gim, IntuitionBase, GfxBase);
- }
- free_gim(abort_gim, IntuitionBase, GfxBase);
- }
- free_gim(cancel_gim, IntuitionBase, GfxBase);
- }
-
- UnlockPubScreen(nil, s);
-
- return false;
- }
-
- void free_gims(void)
- {
- free_gim(login_gim, IntuitionBase, GfxBase);
- free_gim(disconnect_gim, IntuitionBase, GfxBase);
- free_gim(abort_gim, IntuitionBase, GfxBase);
- free_gim(cancel_gim, IntuitionBase, GfxBase);
- }
-
- #define BUFF_SIZE 100
-
- boolean get_anon_login(void)
- {
- b8 user[BUFF_SIZE], host[BUFF_SIZE];
- sb32 i, j;
- struct EasyStruct es;
-
- es.es_StructSize = sizeof(struct EasyStruct);
- es.es_Flags = 0;
- es.es_Title = strings[MSG_FTPM_STARTUP_ERROR];
- es.es_GadgetFormat = strings[MSG_CONTINUE_EXIT];
-
- i = GetVar(strings[MSG_USER], user, BUFF_SIZE, 0);
- j = GetVar(strings[MSG_HOST], host, BUFF_SIZE, 0);
-
- /* four cases here */
- if (i >= 0 && j >= 0) {
- anon_login = (b8 *)allocate(i + j + 2, V_cstr);
- if (!anon_login) return false;
-
- strcpy(anon_login, user);
- anon_login[i] = '@';
- strcpy(anon_login + i + 1, host);
- } else if (i < 0 && j >= 0) {
- anon_login = (b8 *)allocate(j + 9, V_cstr);
- if (!anon_login) return false;
-
- strcpy(anon_login, "unknown@");
- strcat(anon_login, host);
-
- es.es_TextFormat = strings[MSG_USER_NOT_SET];
- if (!EasyRequest(nil, &es, 0, anon_login)) {
- deallocate(anon_login, V_cstr);
- return false;
- }
- } else if (i >= 0 && j < 0) {
- anon_login = (b8 *)allocate(i + 9, V_cstr);
- if (!anon_login) return false;
-
- strcpy(anon_login, user);
- strcat(anon_login, "@unknown");
-
- es.es_TextFormat = strings[MSG_HOST_NOT_SET];
- if (!EasyRequest(nil, &es, 0, anon_login)) {
- deallocate(anon_login, V_cstr);
- return false;
- }
- } else {
- anon_login = (b8 *)allocate(16, V_cstr);
- if (!anon_login) return false;
-
- strcpy(anon_login, "unknown@unknown");
-
- es.es_TextFormat = strings[MSG_USER_HOST_NOT_SET];
- if (!EasyRequest(nil, &es, 0, anon_login)) {
- deallocate(anon_login, V_cstr);
- return false;
- }
- }
-
- return true;
- }
-
- boolean create_volume(void)
- {
- b32 vlen;
-
- ftp_volume = (struct DosList *)allocate_flags(sizeof(struct DosList), MEMF_PUBLIC, V_DosList);
- if (ftp_volume) {
- ftp_volume->dol_Type = DLT_VOLUME;
- ftp_volume->dol_Task = ftp_port;
- ftp_volume->dol_Lock = 0;
- DateStamp(&ftp_volume->dol_misc.dol_volume.dol_VolumeDate);
- ftp_volume->dol_misc.dol_volume.dol_LockList = 0;
- ftp_volume->dol_misc.dol_volume.dol_DiskType = ID_DOS_DISK;
-
- vlen = strlen(strings[MSG_VOLUME]);
- volume_name = (b8 *)allocate_flags(vlen + 2, MEMF_PUBLIC, V_bstr);
- if (volume_name) {
- volume_name[0] = vlen;
- strcpy(&volume_name[1], strings[MSG_VOLUME]);
-
- ftp_volume->dol_Name = (b32)volume_name >> 2;
- if (AddDosEntry(ftp_volume)) {
- return true;
- }
-
- deallocate(volume_name, V_bstr);
- }
- deallocate(ftp_volume, V_DosList);
- }
-
- return false;
- }
-
- void destroy_volume(void)
- {
- struct DosList *dllock;
-
- dllock = LockDosList(LDF_VOLUMES | LDF_DELETE | LDF_WRITE);
-
- if (RemDosEntry(ftp_volume)) {
- deallocate(volume_name, V_bstr);
- deallocate(ftp_volume, V_DosList);
- }
-
- UnLockDosList(LDF_VOLUMES | LDF_DELETE | LDF_WRITE);
-
- return;
- }
-
- boolean launch_status(void)
- {
- struct Process *child;
-
- status_mess = (status_message *)allocate(sizeof(*status_mess), V_status_message);
- if (!status_mess) return false;
-
- status_mess->header.mn_Length = sizeof(*status_mess);
- status_mess->header.mn_Node.ln_Name = "status startup message";
- status_mess->header.mn_Node.ln_Type = NT_MESSAGE;
- status_mess->header.mn_Node.ln_Pri = 0;
-
- ensure(status_mess, V_status_message);
-
- status_control = CreatePort(0, 0);
- if (status_control) {
- child = CreateNewProcTags(
- NP_Entry, status_handler,
- NP_Name, strings[MSG_STATUS_HANDLER],
- NP_StackSize, 6000,
- TAG_END, 0
- );
-
- if (child) {
- status_port = &child->pr_MsgPort;
-
- status_mess->header.mn_ReplyPort = startup_sync;
- PutMsg(status_port, &status_mess->header);
-
- WaitPort(startup_sync); GetMsg(startup_sync);
-
- if (status_mess->command != SM_KILL) {
- return true;
- }
- }
-
- DeletePort(status_control);
- }
-
- deallocate(status_mess, V_status_message);
-
- startup_error(strings[MSG_CANT_LAUNCH_STATUS]);
-
- return false;
- }
-
- void shutdown_status(void)
- {
- status_message *sm;
-
- status_mess->command = SM_KILL;
- status_mess->header.mn_ReplyPort = startup_sync;
-
- PutMsg(status_port, &status_mess->header);
-
- while (1) {
- Wait ((1 << status_control->mp_SigBit) | (1 << startup_sync->mp_SigBit));
-
- while (sm = (status_message *)GetMsg(status_control)) {
- verify(sm, V_status_message);
-
- ReplyMsg(&sm->header);
- }
-
- if (sm = (status_message *)GetMsg(startup_sync)) {
- deallocate(status_mess, V_status_message);
- DeletePort(status_control);
- return;
- }
- }
- }
-
- void setup_strings(void)
- {
- int i;
-
- my_locale = nil;
- cat = nil;
-
- if (LocaleBase) {
- my_locale = OpenLocale(0);
- if (my_locale) {
- cat = OpenCatalog(my_locale, "FTPMount.catalog",
- OC_BuiltInLanguage, "english",
- TAG_END
- );
- }
- }
-
- if (cat) {
- for (i = 0; i < NUM_MSGS; i++) {
- strings[i] = GetCatalogStr(cat, i, strings[i]);
- }
- }
- }
-
- void cleanup_strings(void)
- {
- if (cat) CloseCatalog(cat);
- if (my_locale) CloseLocale(my_locale);
- }
-