📄 ftpdrive.c
字号:
/*
* Copyright (c) 2004, Dennis Kuschel.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @file ftpdrive.c
* @author Dennis Kuschel
* @brief Demonstration program for the filesystem and the FTP Demon.
*
* This software is from http://mycpu.mikrocontroller.net.
* Please send questions and bug reports to dennis_k@freenet.de.
*/
#include "../src/sys.h"
#include "../src/ftpd.h"
#include "../src/httpd.h"
#include "../src/filesys.h"
#include <sys/types.h>
#include <sys/stat.h>
/*---------------------------------------------------------------------------
* DEFINES
*-------------------------------------------------------------------------*/
#define FTP_USERNAME "test"
#define FTP_PASSWORD "1234"
#define _stat stat
/*---------------------------------------------------------------------------
* GLOBAL VARIABLES
*-------------------------------------------------------------------------*/
u32_t jiffies = 0;
sint_t stopTimerThread_g;
/*---------------------------------------------------------------------------
* FUNCTION PROTOTYPES
*-------------------------------------------------------------------------*/
DWORD WINAPI timer_thread(LPVOID arg);
DWORD WINAPI ftp_thread(LPVOID arg);
DWORD WINAPI http_thread(LPVOID arg);
void start_thread(LPTHREAD_START_ROUTINE function);
void mainprog(void);
void* load_file(char *filename);
sint_t ask(char *question);
/*-------------------------------------------------------------------------*/
void mainprog(void)
{
char img1_name[300];
char img2_name[300];
char img_sname[300];
char *savename;
char buf[300];
void *img1_buf, *img2_buf, *imgbuf;
sint_t img1_rdonly, img2_rdonly;
sint_t status;
u32_t ramsize, imgsize;
u32_t blocksize, fnamesize;
FILE *f;
img1_name[0] = 0;
img2_name[0] = 0;
img1_buf = NULL;
img2_buf = NULL;
img1_rdonly = 1;
img2_rdonly = 1;
ramsize = 0;
printf("\nThis program sets up a FTP server (demon) that uses an embedded\n");
printf("RAM drive to store the files. You may use any FTP client program\n");
printf("to access the RAM drive (you need to use the IP 127.0.0.1).\n");
printf("This program also includes the HTTP demon, so you are able to test\n");
printf("the embedded webserver with the files you have uploaded by FTP.\n");
printf("\nCopyright (c) 2004, Dennis Kuschel\n\n");
printf("\nThis program is not just a demonstration program for the\n");
printf("filesystem and FTPD, it can also be used as tool to generate\n");
printf("a ROM-able image for embedded devices. To do so, you should\n");
printf("answer the next question with No.\n\n");
if (ask("Do you want to load a drive image from disk?") == 1)
{
printf("Please enter the filename: ");
gets(img1_name);
if (*img1_name == 0)
{
printf("quit.\n");
return;
}
img1_buf = load_file(img1_name);
if (img1_buf == NULL)
{
printf("Failed to load the file!\n");
return;
}
if (ask("Shall this drive image marked read-only?") == 0)
img1_rdonly = 0;
}
if (img1_buf != NULL)
{
printf("\n");
if (ask("Do you want to load a second drive image from disk?") == 1)
{
printf("Please enter the filename: ");
gets(img2_name);
if (*img2_name == 0)
{
printf("quit.\n");
free(img1_buf);
return;
}
img2_buf = load_file(img2_name);
if (img2_buf == NULL)
{
printf("Failed to load the file!\n");
free(img1_buf);
return;
}
if (img1_rdonly == 0)
{
printf("Note: This image is marked read-only.\n");
}
else
{
if (ask("Shall this drive image marked read-only?") == 0)
img2_rdonly = 0;
}
}
}
if (img1_rdonly && (img2_buf == NULL))
{
printf("\n");
if (img1_buf != NULL)
{
status = ask("Do you want to create a new RAM drive image?");
}
else
{
printf("No image loaded, a new RAM-Drive will be created.\n");
status = 1;
}
if (status == 1)
{
do
{
printf("Please enter the RAM memory size (decimal, kilobytes): ");
gets(buf);
}
while (sscanf(buf, "%u", &ramsize) != 1);
if (ramsize == 0)
{
printf("error, quit.\n");
if (img1_buf != NULL)
free(img1_buf);
if (img2_buf != NULL)
free(img2_buf);
return;
}
ramsize *= 1024;
for (;;)
{
printf("Please enter the block size ([Enter]=default (512 bytes)): ");
gets(buf);
if (sscanf(buf, "%u", &blocksize) != 1)
blocksize = 0;
if (blocksize == 0)
blocksize = 512;
if ((blocksize >= 128) && (blocksize < ramsize/4))
break;
printf("Invalid value!\n\n");
}
for (;;)
{
printf("Please enter the max. filename length ([Enter]=default (128 bytes)): ");
gets(buf);
if (sscanf(buf, "%u", &fnamesize) != 1)
fnamesize = 0;
if (fnamesize == 0)
fnamesize = 128;
if ((fnamesize >= 8) && (fnamesize <= blocksize-32))
break;
printf("Invalid value!\n\n");
}
}
}
printf("\nStarting the RAM drive... ");
status = fsys_init(ramsize, blocksize, fnamesize);
if ((status == 0) && (img1_buf != NULL))
status = fsys_addDriveImage(img1_buf, img1_rdonly);
if ((status == 0) && (img2_buf != NULL))
status = fsys_addDriveImage(img2_buf, img2_rdonly);
if (status != 0)
{
printf("failed, quit.\n");
if (img1_buf != NULL)
free(img1_buf);
if (img2_buf != NULL)
free(img2_buf);
return;
}
printf("ok.\n");
printf("Starting FTP Demon... ");
start_thread(ftp_thread);
sysSleep(500);
if (!ftpd_running())
{
printf("failed, quit.\n");
fsys_term();
if (img1_buf != NULL)
free(img1_buf);
if (img2_buf != NULL)
free(img2_buf);
return;
}
printf("ok.\n");
printf("Starting HTTP Demon... ");
start_thread(http_thread);
sysSleep(500);
if (!httpd_running())
{
ftpd_stop();
printf("failed, quit.\n");
fsys_term();
if (img1_buf != NULL)
free(img1_buf);
if (img2_buf != NULL)
free(img2_buf);
return;
}
printf("ok.\n");
printf("\nFTP username: %s, password: %s\n",
FTP_USERNAME, FTP_PASSWORD);
printf("\n");
while (ask("FTPD is running, stop now?") == 0)
{
printf("Free space on drive: %u kb\n", fsys_free()/1024);
}
if (((img1_buf != NULL) && (img1_rdonly == 0)) ||
((img2_buf != NULL) && (img2_rdonly == 0)) ||
(ramsize > 0))
{
savename = NULL;
if ((img1_buf != NULL) && (img1_rdonly == 0))
savename = img1_name;
else
if ((img2_buf != NULL) && (img2_rdonly == 0))
savename = img2_name;
printf("\n");
if (ask("Save RAM-Drive image to disk?") == 1)
{
do
{
if (savename != NULL)
{
printf("Please enter the filename "
"([Enter]=default name: %s): ", savename);
}
else
{
printf("Please enter the filename: ");
}
gets(img_sname);
}
while ((savename == NULL) && (*img_sname == 0));
if (*img_sname != 0)
savename = img_sname;
f = NULL;
imgbuf = fsys_lockAndGetImage(&imgsize);
if (imgbuf != NULL)
{
if (ask("Shrink image to smalles size (not reversible)?") == 1)
{
imgsize = fsys_shrinkImage(imgbuf);
}
}
if ((imgbuf != NULL) && (imgsize != 0))
{
f = fopen(savename, "w+b");
if (f != NULL)
{
printf("\nSaveing image to file %s\n", savename);
if (fwrite(imgbuf, 1, imgsize, f) != imgsize)
{
imgbuf = NULL;
}
fclose(f);
}
fsys_unlockImage();
}
if ((f == NULL) || (imgbuf == NULL))
{
printf("Failed!\n");
}
else
{
printf("Successfully done.\n");
}
}
}
printf("\nShutting down HTTPD...");
if (httpd_stop() == 0)
{
printf(" OK\n");
}
else
{
printf(" FAILED\n");
}
printf("\nShutting down FTPD...");
if (ftpd_stop() == 0)
{
printf(" OK\n");
}
else
{
printf(" FAILED\n");
}
printf("Shutting down filesystem...\n");
fsys_term();
if (img1_buf != NULL)
free(img1_buf);
if (img2_buf != NULL)
free(img2_buf);
printf("Quit.\n");
}
/*-------------------------------------------------------------------------*/
sint_t ask(char *question)
{
char inbuf[100];
do
{
printf("%s <Y/N>: ", question);
gets(inbuf);
}
while ((strlen(inbuf) != 1) ||
((tolower(inbuf[0]) != 'y') && (tolower(inbuf[0]) != 'n')));
return (tolower(inbuf[0]) == 'y') ? 1 : 0;
}
void* load_file(char *filename)
{
struct stat st;
FILE *f;
void *m;
if (stat(filename, &st) != 0)
return NULL;
m = malloc(st.st_size);
if (m == NULL)
return NULL;
f = fopen(filename, "rb");
if (f == NULL)
{
free(m);
return NULL;
}
if (fread(m, 1, st.st_size, f) <= 0)
{
fclose(f);
free(m);
return NULL;
}
fclose(f);
return m;
}
/*-------------------------------------------------------------------------*/
DWORD WINAPI timer_thread(LPVOID arg)
{
(void) arg;
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
while (!stopTimerThread_g)
{
sysSleep(10);
jiffies++;
}
return 0;
}
DWORD WINAPI ftp_thread(LPVOID arg)
{
(void) arg;
ftpd_start(FTP_USERNAME, FTP_PASSWORD);
return 0;
}
DWORD WINAPI http_thread(LPVOID arg)
{
(void) arg;
httpd_start("/", 32768, 32768);
return 0;
}
void start_thread(LPTHREAD_START_ROUTINE function)
{
DWORD threadid;
CreateThread(NULL, 0, function, NULL, 0, &threadid);
}
/*-------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
WORD wVersionRequested;
WSADATA wsaData;
(void) argc;
(void) argv;
/* initialize the socket layer */
wVersionRequested = MAKEWORD(2,0);
if (WSAStartup(wVersionRequested, &wsaData) != 0)
{
printf("Sorry, no usable winsock.dll found.\n");
return 1;
}
if ((LOBYTE(wsaData.wVersion) != 2) ||
(HIBYTE(wsaData.wVersion) != 0))
{
printf("Sorry, no usable winsock.dll found.\n");
WSACleanup();
return 1;
}
/* create timer thread */
stopTimerThread_g = 0;
start_thread(timer_thread);
mainprog();
/* stop the timer thread */
stopTimerThread_g = 1;
sysSleep(20);
WSACleanup();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -