Replace console with one built-in to libctru

This commit is contained in:
mtheall 2015-01-07 23:26:01 -06:00
parent 1797235420
commit 20f29f60b8
16 changed files with 176 additions and 784 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,7 +1,17 @@
#pragma once
#define ESC(x) "\x1b[" #x
#define RESET ESC(0m)
#define BLACK ESC(30m)
#define RED ESC(31;1m)
#define GREEN ESC(32;1m)
#define YELLOW ESC(33;1m)
#define BLUE ESC(34;1m)
#define MAGENTA ESC(35;1m)
#define CYAN ESC(36;1m)
#define WHITE ESC(37;1m)
void console_init(void);
void console_exit(void);
__attribute__((format(printf,1,2)))
void console_set_status(const char *fmt, ...);

View File

@ -1,3 +1,8 @@
#pragma once
#ifdef _3DS
#include <3ds.h>
void gfxDrawSprite(gfxScreen_t screen, gfx3dSide_t side, u8* spriteData, u16 width, u16 height, s16 x, s16 y);
#endif

View File

@ -9,321 +9,22 @@
#include "gfx.h"
#ifdef _3DS
#include "sans_8_kerning_bin.h"
#include "sans_8_render_bin.h"
#include "sans_10_kerning_bin.h"
#include "sans_10_render_bin.h"
#include "sans_12_kerning_bin.h"
#include "sans_12_render_bin.h"
#include "sans_14_kerning_bin.h"
#include "sans_14_render_bin.h"
#include "sans_16_kerning_bin.h"
#include "sans_16_render_bin.h"
#include "banner_bin.h"
/* TODO: add support for non-ASCII characters */
/*! rendering information */
typedef struct
{
int c; /*!< character */
int y_off; /*!< vertical offset */
int width; /*!< width */
int height; /*!< height */
int x_adv; /*!< horizontal advance */
u8 data[]; /*!< width*height bitmap */
} render_info_t;
/*! kerning information */
typedef struct
{
int prev; /*!< previous character */
int next; /*!< next character */
int x_off; /*!< horizontal adjustment */
} kerning_info_t;
/*! font data */
typedef struct
{
const char *name; /*!< font name */
render_info_t **render_info; /*!< render information list */
kerning_info_t *kerning_info; /*!< kerning information list */
size_t num_render_info; /*!< number of render information nodes */
size_t num_kerning_info; /*!< number of kerning information nodes */
int pt; /*!< font size */
} font_t;
/*! font information */
typedef struct
{
const char *name; /*!< font name */
int pt; /*!< font size */
const u8 *render_data; /*!< render data */
const u8 *kerning_data; /*!< kerning data */
const u32 *render_data_size; /*!< render data size */
const u32 *kerning_data_size; /*!< kerning data size */
} font_info_t;
/*! font descriptors */
static font_info_t font_info[] =
{
#define FONT_INFO(name, pt) \
{ #name, pt, name##_##pt##_render_bin, name##_##pt##_kerning_bin, \
&name##_##pt##_render_bin_size, &name##_##pt##_kerning_bin_size, }
FONT_INFO(sans, 8),
FONT_INFO(sans, 10),
FONT_INFO(sans, 12),
FONT_INFO(sans, 14),
FONT_INFO(sans, 16),
};
/*! number of font descriptors */
static const size_t num_font_info = sizeof(font_info)/sizeof(font_info[0]);
/*! find next render info
*
* @param[in] info current render info
*
* @returns next render info
*/
static render_info_t*
next_render_info(render_info_t *info)
{
char *ptr = (char*)info;
ptr += sizeof(*info) + info->width*info->height;
ptr = (char*)(((int)ptr + sizeof(int)-1) & ~(sizeof(int)-1));
return (render_info_t*)ptr;
}
/*! free font info
*
* @param[in] font
*/
static void
free_font(font_t *font)
{
free(font->render_info);
free(font);
}
/*! load font info
*
* @param[in] name
* @param[in] pt
* @param[in] render_data
* @param[in] render_data_size
* @param[in] kerning data
* @param[in] kerning_data_size
*
* @returns font info
*/
static font_t*
load_font(const char *name,
int pt,
const u8 *render_data,
size_t render_data_size,
const u8 *kerning_data,
size_t kerning_data_size)
{
size_t i;
render_info_t *rinfo;
font_t *font;
/* allocate new font info */
font = (font_t*)calloc(1, sizeof(font_t));
if(font != NULL)
{
/* count number of render entries */
rinfo = (render_info_t*)render_data;
while((u8*)rinfo < render_data + render_data_size)
{
++font->num_render_info;
rinfo = next_render_info(rinfo);
}
/* allocate array of render info pointers */
font->render_info = (render_info_t**)calloc(font->num_render_info, sizeof(render_info_t));
if(font->render_info != NULL)
{
/* fill in the pointer list */
rinfo = (render_info_t*)render_data;
i = 0;
while((u8*)rinfo < render_data + render_data_size)
{
font->render_info[i++] = rinfo;
rinfo = next_render_info(rinfo);
}
/* fill in the kerning info */
font->kerning_info = (kerning_info_t*)kerning_data;
font->num_kerning_info = kerning_data_size / sizeof(kerning_info_t);
/* set font size and name */
font->pt = pt;
font->name = name;
}
else
{
/* failed to allocate render info list */
free_font(font);
font = NULL;
}
}
return font;
}
/*! list of font info entries */
static font_t **fonts;
/*! number of font info entries */
static size_t num_fonts = 0;
/*! compare two fonts
*
* @param[in] p1 left side of comparison (font_t**)
* @param[in] p2 right side of comparison (font_t**)
*
* @returns <0 if p1 < p2
* @returns 0 if p1 == p2
* @returns >0 if p1 > p2
*/
static int
font_cmp(const void *p1,
const void *p2)
{
/* interpret parameters */
font_t *f1 = *(font_t**)p1;
font_t *f2 = *(font_t**)p2;
/* major key is font name */
int rc = strcmp(f1->name, f2->name);
if(rc != 0)
return rc;
/* minor key is font size */
if(f1->pt < f2->pt)
return -1;
if(f1->pt > f2->pt)
return 1;
return 0;
}
/*! search for a font by name and size
*
* @param[in] name font name
* @param[in] pt font size
*
* @returns matching font
*/
static font_t*
find_font(const char *name,
int pt)
{
/* create a key to search for */
font_t key, *keyptr;
key.name = name;
key.pt = pt;
keyptr = &key;
/* search for the key */
void *font = bsearch(&keyptr, fonts, num_fonts, sizeof(font_t*), font_cmp);
if(font == NULL)
return NULL;
/* found it */
return *(font_t**)font;
}
static PrintConsole status_console;
static PrintConsole main_console;
/*! initialize console subsystem */
void
console_init(void)
{
size_t i;
consoleInit(GFX_TOP, &status_console);
consoleSetWindow(&status_console, 0, 0, 50, 1);
/* allocate font list */
fonts = (font_t**)calloc(num_font_info, sizeof(font_t*));
if(fonts == NULL)
return;
consoleInit(GFX_TOP, &main_console);
consoleSetWindow(&main_console, 0, 1, 50, 29);
/* load fonts */
for(i = 0; i < num_font_info; ++i)
{
font_info_t *info = &font_info[i];
fonts[num_fonts] = load_font(info->name, info->pt,
info->render_data,
*info->render_data_size,
info->kerning_data,
*info->kerning_data_size);
if(fonts[num_fonts] != NULL)
++num_fonts;
}
/* sort the list for bsearch later */
qsort(fonts, num_fonts, sizeof(font_t*), font_cmp);
}
/*! deinitialize console subsystem */
void
console_exit(void)
{
int i;
/* free the font info */
for(i = 0; i < num_fonts; ++i)
free_font(fonts[i]);
/* free the font info list */
free(fonts);
fonts = NULL;
}
/*! status bar contents */
static char status[64];
/*! console buffer */
static char buffer[8192];
/*! pointer to end of buffer */
static char *buffer_end = buffer + sizeof(buffer);
/*! pointer to end of console contents */
static char *end = buffer;
/*! count lines in console contents */
static size_t
count_lines(void)
{
size_t lines = 0;
char *p = buffer;
/* search for each newline character */
while(p < end && (p = strchr(p, '\n')) != NULL)
{
++lines;
++p;
}
return lines;
}
/*! remove lines that have "scrolled" off screen */
static void
reduce_lines(void)
{
int lines = count_lines();
char *p = buffer;
/* we can fit 18 lines on the screen */
/* TODO make based on pt size */
while(lines > 18)
{
p = strchr(p, '\n');
++p;
--lines;
}
/* move the new beginning to where it needs to be */
ptrdiff_t distance = p - buffer;
memmove(buffer, buffer+distance, end - p);
end -= distance;
*end = 0;
consoleSelect(&main_console);
}
/*! set status bar contents
@ -336,10 +37,11 @@ console_set_status(const char *fmt, ...)
{
va_list ap;
consoleSelect(&status_console);
va_start(ap, fmt);
memset(status, 0, sizeof(status));
vsnprintf(status, sizeof(status)-1, fmt, ap);
vprintf(fmt, ap);
va_end(ap);
consoleSelect(&main_console);
}
/*! add text to the console
@ -350,349 +52,20 @@ console_set_status(const char *fmt, ...)
void
console_print(const char *fmt, ...)
{
int rc;
va_list ap;
/* append to the end of the console buffer */
va_start(ap, fmt);
rc = vsnprintf(end, buffer_end - end - 1, fmt, ap);
vprintf(fmt, ap);
va_end(ap);
/* null terminate buffer */
end += rc;
if(end >= buffer_end)
end = buffer_end - 1;
*end = 0;
/* scroll */
reduce_lines();
}
/*! compare render information
*
* @param[in] p1 left side of comparison (render_info_t**)
* @param[in] p2 right side of comparison (render_info_t**)
*
* @returns <0 if p1 < p2
* @returns 0 if p1 == p2
* @returns >0 if p1 > p2
*/
static int
render_info_cmp(const void *p1,
const void *p2)
{
/* interpret parameters */
render_info_t *r1 = *(render_info_t**)p1;
render_info_t *r2 = *(render_info_t**)p2;
/* ordered by character */
if(r1->c < r2->c)
return -1;
else if(r1->c > r2->c)
return 1;
return 0;
}
/*! search for render info by character
*
* @param[in] font font info
* @param[in] char character
*
* @returns matching render info
*/
static render_info_t*
find_render_info(font_t *font,
char c)
{
/* create a key to search for */
render_info_t key, *keyptr;
key.c = c;
keyptr = &key;
/* search for the key */
void *info = bsearch(&keyptr, font->render_info, font->num_render_info,
sizeof(render_info_t*), render_info_cmp);
if(info == NULL)
return NULL;
/* found it */
return *(render_info_t**)info;
}
/*! compare kerning information
*
* @param[in] p1 left side of comparison (kerning_info_t*)
* @param[in] p2 right side of comparison (kerning_info_t*)
*
* @returns <0 if p1 < p2
* @returns 0 if p1 == p2
* @returns >0 if p1 > p2
*/
static int
kerning_info_cmp(const void *p1,
const void *p2)
{
/* interpret parameters */
kerning_info_t *k1 = (kerning_info_t*)p1;
kerning_info_t *k2 = (kerning_info_t*)p2;
/* major key is prev */
if(k1->prev < k2->prev)
return -1;
if(k1->prev > k2->prev)
return 1;
/* minor key is next */
if(k1->next < k2->next)
return -1;
if(k1->next > k2->next)
return 1;
return 0;
}
/*! search for kerning info by character pair
*
* @param[in] font font info
* @param[in] prev prev character
* @param[in] next next character
*
* @returns matching render info
*/
static kerning_info_t*
find_kerning_info(font_t *font,
char prev,
char next)
{
/* create a key to search for */
kerning_info_t key;
key.prev = prev;
key.next = next;
/* search for the key */
void *info = bsearch(&key, font->kerning_info, font->num_kerning_info,
sizeof(kerning_info_t), kerning_info_cmp);
if(info == NULL)
return NULL;
/* found it */
return (kerning_info_t*)info;
}
/*! clear framebuffer
*
* @param[in] screen screen to clear
* @param[in] side which side on the stereoscopic display
* @param[in] rgbColor clear color
*/
static void
clear_screen(gfxScreen_t screen,
gfx3dSide_t side,
u8 rgbColor[3])
{
/* get the framebuffer information */
u16 fbWidth, fbHeight;
u8 *fb = gfxGetFramebuffer(screen, side, &fbWidth, &fbHeight);
/* fill the framebuffer with the clear color */
int i;
for(i = 0; i < fbWidth*fbHeight; ++i)
{
*(fb++) = rgbColor[2];
*(fb++) = rgbColor[1];
*(fb++) = rgbColor[0];
}
}
/*! draw a quad
*
* @param[in] screen screen to draw to
* @param[in] side which side on the stereoscopic display
* @param[in] data quad data
* @param[in] x quad x position
* @param[in] y quad y position
* @param[in] w quad width
* @param[in] h quad height
*
* @note this quad data is 8-bit alpha-only
* @note uses framebuffer native coordinates
*/
static void
draw_quad(gfxScreen_t screen,
gfx3dSide_t side,
const u8 *data,
int x,
int y,
int w,
int h)
{
int i, j;
int index = 0;
int stride = w;
/* get the framebuffer information */
u16 width, height;
u8 *fb = gfxGetFramebuffer(screen, side, &width, &height);
/* this quad is totally offscreen; don't draw */
if(x > width || y > height)
return;
/* this quad is totally offscreen; don't draw */
if(x + w < 0 || y + h < 0)
return;
/* adjust parameters for partially visible quad */
if(x < 0)
{
index -= x;
w += x;
x = 0;
}
/* adjust parameters for partially visible quad */
if(y < 0)
{
index -= y*stride;
h += y;
y = 0;
}
/* adjust parameters for partially visible quad */
if(x + w > width)
w = width - x;
/* adjust parameters for partially visible quad */
if(y + h > height)
h = height - y;
/* move framebuffer pointer to quad start position */
fb += (y*width + x)*3;
/* fill in data */
for(j = 0; j < h; ++j)
{
for(i = 0; i < w; ++i)
{
/* alpha blending; assuming color is white */
int v = data[index];
fb[0] = fb[0]*(0xFF-v)/0xFF + v;
fb[1] = fb[1]*(0xFF-v)/0xFF + v;
fb[2] = fb[2]*(0xFF-v)/0xFF + v;
++index;
fb += 3;
}
index += (stride-w);
fb += (width-w)*3;
}
}
/*! draw text to framebuffer
*
* @param[in] screen screen to draw to
* @param[in] side which side on the stereoscopic display
* @param[in] font font to use when rendering
* @param[in] data quad data
* @param[in] x quad x position
* @param[in] y quad y position
*
* @note uses intuitive coordinates
*/
static void
draw_text(gfxScreen_t screen,
gfx3dSide_t side,
font_t *font,
const char *data,
int x,
int y)
{
render_info_t *rinfo;
kerning_info_t *kinfo;
const char *p;
int xoff = x, yoff = y;
char prev = 0;
/* draw each character */
for(p = data; *p != 0; ++p)
{
/* newline; move down a line and all the way left */
if(*p == '\n')
{
xoff = x;
yoff += font->pt + font->pt/2;
prev = 0;
continue;
}
/* look up the render info for this character */
rinfo = find_render_info(font, *p);
/* couldn't find it; just ignore it */
if(rinfo == NULL)
continue;
/* find kerning data */
kinfo = NULL;
if(prev != 0)
kinfo = find_kerning_info(font, prev, *p);
/* adjust for kerning */
if(kinfo != NULL)
xoff += kinfo->x_off >> 6;
/* save this character for next kerning lookup */
prev = *p;
/* render character */
if(rinfo->width != 0 && rinfo->height != 0)
{
int x, y;
/* get framebuffer info */
u16 width, height;
gfxGetFramebuffer(screen, side, &width, &height);
/* transform intuitive coordinates to framebuffer-native */
x = width - yoff - font->pt - 2 - (rinfo->height - rinfo->y_off);
y = xoff;
/* draw character */
draw_quad(screen, side, rinfo->data, x, y,
rinfo->height, rinfo->width);
}
/* advance to next character coordinate */
xoff += rinfo->x_adv >> 6;
}
}
/*! draw console to screen */
void
console_render(void)
{
font_t *font;
/* clear all screens */
u8 bluish[] = { 0, 0, 127 };
clear_screen(GFX_TOP, GFX_LEFT, bluish);
gfxDrawSprite(GFX_BOTTOM, GFX_LEFT, (u8*)banner_bin, 240, 320, 0, 0);
/* look up font for status bar and draw status bar */
font = find_font("sans", 10);
if(font != NULL)
draw_text(GFX_TOP, GFX_LEFT, font, status, 4, 4);
else
debug("%s: couldn't find 'sans 10pt'\n", __func__);
/* look up font for console and draw console */
font = find_font("sans", 8);
if(font != NULL)
draw_text(GFX_TOP, GFX_LEFT, font, buffer, 4, 20);
else
debug("%s: couldn't find 'sans 8pt'\n", __func__);
/* flush framebuffer */
gfxFlushBuffers();
gspWaitForVBlank();
@ -707,11 +80,6 @@ console_init(void)
{
}
void
console_exit(void)
{
}
void
console_set_status(const char *fmt, ...)
{

View File

@ -165,6 +165,7 @@ static ftp_command_t ftp_commands[] =
/*! number of ftp commands */
static const size_t num_ftp_commands = sizeof(ftp_commands)/sizeof(ftp_commands[0]);
#ifdef _3DS
static inline int Errno(void)
{
int err = SOC_GetErrno();
@ -172,6 +173,7 @@ static inline int Errno(void)
return -err;
return err;
}
#endif
/*! compare ftp command descriptors
*
@ -265,14 +267,14 @@ ftp_set_socket_nonblocking(int fd)
flags = fcntl(fd, F_GETFL, 0);
if(flags == -1)
{
console_print("fcntl: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "fcntl: %d %s\n" RESET, Errno(), strerror(Errno()));
return -1;
}
rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
if(rc != 0)
{
console_print("fcntl: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "fcntl: %d %s\n" RESET, Errno(), strerror(Errno()));
return -1;
}
@ -297,23 +299,23 @@ ftp_closesocket(int fd, int connected)
rc = getpeername(fd, (struct sockaddr*)&addr, &addrlen);
if(rc != 0)
{
console_print("getpeername: %d %s\n", Errno(), strerror(Errno()));
console_print("closing connection to fd=%d\n", fd);
console_print(RED "getpeername: %d %s\n" RESET, Errno(), strerror(Errno()));
console_print(YELLOW "closing connection to fd=%d\n" RESET, fd);
}
else
console_print("closing connection to %s:%u\n",
console_print(YELLOW "closing connection to %s:%u\n" RESET,
inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
/* shutdown connection */
rc = shutdown(fd, SHUT_RDWR);
if(rc != 0)
console_print("shutdown: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "shutdown: %d %s\n" RESET, Errno(), strerror(Errno()));
}
/* close socket */
rc = closesocket(fd);
if(rc != 0)
console_print("closesocket: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "closesocket: %d %s\n" RESET, Errno(), strerror(Errno()));
}
/*! close command socket on ftp session
@ -335,7 +337,7 @@ ftp_session_close_cmd(ftp_session_t *session)
static void
ftp_session_close_pasv(ftp_session_t *session)
{
console_print("stop listening on %s:%u\n",
console_print(YELLOW "stop listening on %s:%u\n" RESET,
inet_ntoa(session->pasv_addr.sin_addr),
ntohs(session->pasv_addr.sin_port));
@ -370,14 +372,14 @@ ftp_session_close_file(ftp_session_t *session)
ret = FSFILE_Close(session->fd);
if(ret != 0)
console_print("FSFILE_Close: 0x%08X\n", (unsigned int)ret);
console_print(RED "FSFILE_Close: 0x%08X\n" RESET, (unsigned int)ret);
session->fd = -1;
#else
int rc;
rc = close(session->fd);
if(rc != 0)
console_print("close: %d %s\n", errno, strerror(errno));
console_print(RED "close: %d %s\n" RESET, errno, strerror(errno));
session->fd = -1;
#endif
}
@ -401,7 +403,7 @@ ftp_session_open_file_read(ftp_session_t *session)
FS_OPEN_READ, FS_ATTRIBUTE_NONE);
if(ret != 0)
{
console_print("FSUSER_OpenFile: 0x%08X\n", (unsigned int)ret);
console_print(RED "FSUSER_OpenFile: 0x%08X\n" RESET, (unsigned int)ret);
return -1;
}
@ -409,7 +411,7 @@ ftp_session_open_file_read(ftp_session_t *session)
ret = FSFILE_GetSize(session->fd, &size);
if(ret != 0)
{
console_print("FSFILE_GetSize: 0x%08X\n", (unsigned int)ret);
console_print(RED "FSFILE_GetSize: 0x%08X\n" RESET, (unsigned int)ret);
ftp_session_close_file(session);
return -1;
}
@ -422,7 +424,7 @@ ftp_session_open_file_read(ftp_session_t *session)
session->fd = open(session->buffer, O_RDONLY);
if(session->fd < 0)
{
console_print("open '%s': %d %s\n", session->buffer, errno, strerror(errno));
console_print(RED "open '%s': %d %s\n" RESET, session->buffer, errno, strerror(errno));
return -1;
}
@ -430,7 +432,7 @@ ftp_session_open_file_read(ftp_session_t *session)
rc = fstat(session->fd, &st);
if(rc != 0)
{
console_print("fstat '%s': %d %s\n", session->buffer, errno, strerror(errno));
console_print(RED "fstat '%s': %d %s\n" RESET, session->buffer, errno, strerror(errno));
ftp_session_close_file(session);
return -1;
}
@ -462,7 +464,7 @@ ftp_session_read_file(ftp_session_t *session)
session->buffer, sizeof(session->buffer));
if(ret != 0)
{
console_print("FSFILE_Read: 0x%08X\n", (unsigned int)ret);
console_print(RED "FSFILE_Read: 0x%08X\n" RESET, (unsigned int)ret);
return -1;
}
@ -478,7 +480,7 @@ ftp_session_read_file(ftp_session_t *session)
rc = read(session->fd, session->buffer, sizeof(session->buffer));
if(rc < 0)
{
console_print("read: %d %s\n", errno, strerror(errno));
console_print(RED "read: %d %s\n" RESET, errno, strerror(errno));
return -1;
}
@ -509,7 +511,7 @@ ftp_session_open_file_write(ftp_session_t *session)
FS_OPEN_WRITE|FS_OPEN_CREATE, FS_ATTRIBUTE_NONE);
if(ret != 0)
{
console_print("FSUSER_OpenFile: 0x%08X\n", (unsigned int)ret);
console_print(RED "FSUSER_OpenFile: 0x%08X\n" RESET, (unsigned int)ret);
return -1;
}
@ -517,7 +519,7 @@ ftp_session_open_file_write(ftp_session_t *session)
ret = FSFILE_SetSize(session->fd, 0);
if(ret != 0)
{
console_print("FSFILE_SetSize: 0x%08X\n", (unsigned int)ret);
console_print(RED "FSFILE_SetSize: 0x%08X\n" RESET, (unsigned int)ret);
ftp_session_close_file(session);
}
#else
@ -525,7 +527,7 @@ ftp_session_open_file_write(ftp_session_t *session)
session->fd = open(session->buffer, O_WRONLY|O_CREAT|O_TRUNC, 0644);
if(session->fd < 0)
{
console_print("open '%s': %d %s\n", session->buffer, errno, strerror(errno));
console_print(RED "open '%s': %d %s\n" RESET, session->buffer, errno, strerror(errno));
return -1;
}
#endif
@ -557,11 +559,11 @@ ftp_session_write_file(ftp_session_t *session)
FS_WRITE_FLUSH);
if(ret != 0)
{
console_print("FSFILE_Write: 0x%08X\n", (unsigned int)ret);
console_print(RED "FSFILE_Write: 0x%08X\n" RESET, (unsigned int)ret);
return -1;
}
else if(bytes == 0)
console_print("FSFILE_Write: wrote 0 bytes\n");
console_print(RED "FSFILE_Write: wrote 0 bytes\n" RESET);
/* adjust file position */
session->filepos += bytes;
@ -576,11 +578,11 @@ ftp_session_write_file(ftp_session_t *session)
session->buffersize - session->bufferpos);
if(rc < 0)
{
console_print("write: %d %s\n", errno, strerror(errno));
console_print(RED "write: %d %s\n" RESET, errno, strerror(errno));
return -1;
}
else if(rc == 0)
console_print("write: wrote 0 bytes\n");
console_print(RED "write: wrote 0 bytes\n" RESET);
/* adjust file position */
session->filepos += rc;
@ -602,7 +604,7 @@ ftp_session_close_cwd(ftp_session_t *session)
/* close open directory handle */
ret = FSDIR_Close(session->fd);
if(ret != 0)
console_print("FSDIR_Close: 0x%08X\n", (unsigned int)ret);
console_print(RED "FSDIR_Close: 0x%08X\n" RESET, (unsigned int)ret);
session->fd = -1;
#else
int rc;
@ -610,7 +612,7 @@ ftp_session_close_cwd(ftp_session_t *session)
/* close open directory pointer */
rc = closedir(session->dp);
if(rc != 0)
console_print("closedir: %d %s\n", errno, strerror(errno));
console_print(RED "closedir: %d %s\n" RESET, errno, strerror(errno));
session->dp = NULL;
#endif
}
@ -632,7 +634,7 @@ ftp_session_open_cwd(ftp_session_t *session)
FS_makePath(PATH_CHAR, session->cwd));
if(ret != 0)
{
console_print("FSUSER_OpenDirectory: 0x%08X\n", (unsigned int)ret);
console_print(RED "FSUSER_OpenDirectory: 0x%08X\n" RESET, (unsigned int)ret);
return -1;
}
#else
@ -640,7 +642,7 @@ ftp_session_open_cwd(ftp_session_t *session)
session->dp = opendir(session->cwd);
if(session->dp == NULL)
{
console_print("opendir '%s': %d %s\n", session->cwd, errno, strerror(errno));
console_print(RED "opendir '%s': %d %s\n" RESET, session->cwd, errno, strerror(errno));
return -1;
}
#endif
@ -720,18 +722,18 @@ ftp_send_response(ftp_session_t *session,
if(rc >= sizeof(buffer))
{
/* couldn't fit message; just send code */
console_print("%s: buffersize too small\n", __func__);
console_print(RED "%s: buffersize too small\n" RESET, __func__);
rc = sprintf(buffer, "%d\r\n", code);
}
/* send response */
to_send = rc;
console_print("%s", buffer);
console_print(GREEN "%s" RESET, buffer);
rc = send(session->cmd_fd, buffer, to_send, 0);
if(rc < 0)
console_print("send: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "send: %d %s\n" RESET, Errno(), strerror(Errno()));
else if(rc != to_send)
console_print("only sent %u/%u bytes\n",
console_print(RED "only sent %u/%u bytes\n" RESET,
(unsigned int)rc, (unsigned int)to_send);
return rc;
@ -791,18 +793,18 @@ ftp_session_new(int listen_fd)
new_fd = accept(listen_fd, (struct sockaddr*)&addr, &addrlen);
if(new_fd < 0)
{
console_print("accept: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "accept: %d %s\n" RESET, Errno(), strerror(Errno()));
return;
}
console_print("accepted connection from %s:%u\n",
console_print(CYAN "accepted connection from %s:%u\n" RESET,
inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
/* allocate a new session */
session = (ftp_session_t*)malloc(sizeof(ftp_session_t));
if(session == NULL)
{
console_print("failed to allocate session\n");
console_print(RED "failed to allocate session\n" RESET);
ftp_closesocket(new_fd, 1);
return;
}
@ -838,7 +840,7 @@ ftp_session_new(int listen_fd)
rc = getsockname(new_fd, (struct sockaddr*)&session->pasv_addr, &addrlen);
if(rc != 0)
{
console_print("getsockname: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "getsockname: %d %s\n" RESET, Errno(), strerror(Errno()));
ftp_send_response(session, 451, "Failed to get connection info\r\n");
ftp_session_destroy(session);
return;
@ -877,7 +879,7 @@ ftp_session_accept(ftp_session_t *session)
new_fd = accept(session->pasv_fd, (struct sockaddr*)&addr, &addrlen);
if(new_fd < 0)
{
console_print("accept: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "accept: %d %s\n" RESET, Errno(), strerror(Errno()));
ftp_session_set_state(session, COMMAND_STATE);
ftp_send_response(session, 425, "Failed to establish connection\r\n");
return -1;
@ -892,7 +894,7 @@ ftp_session_accept(ftp_session_t *session)
return -1;
}
console_print("accepted connection from %s:%u\n",
console_print(CYAN "accepted connection from %s:%u\n" RESET,
inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
ftp_session_set_state(session, DATA_TRANSFER_STATE);
@ -926,7 +928,7 @@ ftp_session_connect(ftp_session_t *session)
session->data_fd = socket(AF_INET, SOCK_STREAM, 0);
if(session->data_fd < 0)
{
console_print("socket: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "socket: %d %s\n" RESET, Errno(), strerror(Errno()));
return -1;
}
@ -935,7 +937,7 @@ ftp_session_connect(ftp_session_t *session)
sizeof(session->peer_addr));
if(rc != 0)
{
console_print("connect: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "connect: %d %s\n" RESET, Errno(), strerror(Errno()));
ftp_closesocket(session->data_fd, 0);
session->data_fd = -1;
return -1;
@ -945,7 +947,7 @@ ftp_session_connect(ftp_session_t *session)
if(rc != 0)
return -1;
console_print("connected to %s:%u\n",
console_print(CYAN "connected to %s:%u\n" RESET,
inet_ntoa(session->peer_addr.sin_addr),
ntohs(session->peer_addr.sin_port));
@ -971,7 +973,7 @@ ftp_session_read_command(ftp_session_t *session)
if(rc < 0)
{
/* error retrieving command */
console_print("recv: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "recv: %d %s\n" RESET, Errno(), strerror(Errno()));
ftp_session_close_cmd(session);
return;
}
@ -1062,7 +1064,7 @@ ftp_session_poll(ftp_session_t *session)
/* poll the selected socket */
rc = poll(&pollinfo, 1, 0);
if(rc < 0)
console_print("poll: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "poll: %d %s\n" RESET, Errno(), strerror(Errno()));
else if(rc > 0)
{
if(pollinfo.revents != 0)
@ -1072,7 +1074,7 @@ ftp_session_poll(ftp_session_t *session)
{
case COMMAND_STATE:
if(pollinfo.revents & POLL_UNKNOWN)
console_print("cmd_fd: revents=0x%08X\n", pollinfo.revents);
console_print(YELLOW "cmd_fd: revents=0x%08X\n" RESET, pollinfo.revents);
/* we need to read a new command */
if(pollinfo.revents & (POLLERR|POLLHUP))
@ -1083,7 +1085,7 @@ ftp_session_poll(ftp_session_t *session)
case DATA_CONNECT_STATE:
if(pollinfo.revents & POLL_UNKNOWN)
console_print("pasv_fd: revents=0x%08X\n", pollinfo.revents);
console_print(YELLOW "pasv_fd: revents=0x%08X\n" RESET, pollinfo.revents);
/* we need to accept the PASV connection */
if(pollinfo.revents & (POLLERR|POLLHUP))
@ -1100,7 +1102,7 @@ ftp_session_poll(ftp_session_t *session)
case DATA_TRANSFER_STATE:
if(pollinfo.revents & POLL_UNKNOWN)
console_print("data_fd: revents=0x%08X\n", pollinfo.revents);
console_print(YELLOW "data_fd: revents=0x%08X\n" RESET, pollinfo.revents);
/* we need to transfer data */
if(pollinfo.revents & (POLLERR|POLLHUP))
@ -1136,48 +1138,32 @@ ftp_init(void)
ret = fsInit();
if(ret != 0)
{
console_print("fsInit: 0x%08X\n", (unsigned int)ret);
return -1;
console_print(RED "fsInit: 0x%08X\n" RESET, (unsigned int)ret);
goto fs_fail;
}
/* open SDMC archive */
ret = FSUSER_OpenArchive(NULL, &sdmcArchive);
if(ret != 0)
{
console_print("FSUSER_OpenArchive: 0x%08X\n", (unsigned int)ret);
ret = fsExit();
if(ret != 0)
console_print("fsExit: 0x%08X\n", (unsigned int)ret);
return -1;
console_print(RED "FSUSER_OpenArchive: 0x%08X\n" RESET, (unsigned int)ret);
goto archive_fail;
}
/* allocate buffer for SOC service */
SOC_buffer = (u32*)memalign(SOC_ALIGN, SOC_BUFFERSIZE);
if(SOC_buffer == NULL)
{
console_print("memalign: failed to allocate\n");
ret = FSUSER_CloseArchive(NULL, &sdmcArchive);
if(ret != 0)
console_print("FSUSER_CloseArchive: 0x%08X\n", (unsigned int)ret);
ret = fsExit();
if(ret != 0)
console_print("fsExit: 0x%08X\n", (unsigned int)ret);
return -1;
console_print(RED "memalign: failed to allocate\n" RESET);
goto memalign_fail;
}
/* initialize SOC service */
ret = SOC_Initialize(SOC_buffer, SOC_BUFFERSIZE);
if(ret != 0)
{
console_print("SOC_Initialize: 0x%08X\n", (unsigned int)ret);
free(SOC_buffer);
ret = FSUSER_CloseArchive(NULL, &sdmcArchive);
if(ret != 0)
console_print("FSUSER_CloseArchive: 0x%08X\n", (unsigned int)ret);
ret = fsExit();
if(ret != 0)
console_print("fsExit: 0x%08X\n", (unsigned int)ret);
return -1;
console_print(RED "SOC_Initialize: 0x%08X\n" RESET, (unsigned int)ret);
goto soc_fail;
}
#endif
@ -1185,7 +1171,7 @@ ftp_init(void)
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if(listenfd < 0)
{
console_print("socket: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "socket: %d %s\n" RESET, Errno(), strerror(Errno()));
ftp_exit();
return -1;
}
@ -1205,7 +1191,7 @@ ftp_init(void)
rc = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
if(rc != 0)
{
console_print("setsockopt: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "setsockopt: %d %s\n" RESET, Errno(), strerror(Errno()));
ftp_exit();
return -1;
}
@ -1216,7 +1202,7 @@ ftp_init(void)
rc = bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
if(rc != 0)
{
console_print("bind: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "bind: %d %s\n" RESET, Errno(), strerror(Errno()));
ftp_exit();
return -1;
}
@ -1225,14 +1211,17 @@ ftp_init(void)
rc = listen(listenfd, 5);
if(rc != 0)
{
console_print("listen: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "listen: %d %s\n" RESET, Errno(), strerror(Errno()));
ftp_exit();
return -1;
}
/* print server address */
#ifdef _3DS
console_set_status(STATUS_STRING " IP:%s Port:%u",
console_set_status("\n" GREEN STATUS_STRING " "
YELLOW "IP:" CYAN "%s "
YELLOW "Port:" CYAN "%u"
RESET,
inet_ntoa(serv_addr.sin_addr),
ntohs(serv_addr.sin_port));
#else
@ -1242,7 +1231,7 @@ ftp_init(void)
rc = getsockname(listenfd, (struct sockaddr*)&serv_addr, &addrlen);
if(rc != 0)
{
console_print("getsockname: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "getsockname: %d %s\n" RESET, Errno(), strerror(Errno()));
ftp_exit();
return -1;
}
@ -1250,18 +1239,39 @@ ftp_init(void)
rc = gethostname(hostname, sizeof(hostname));
if(rc != 0)
{
console_print("gethostname: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "gethostname: %d %s\n" RESET, Errno(), strerror(Errno()));
ftp_exit();
return -1;
}
console_set_status(STATUS_STRING " IP:%s Port:%u",
console_set_status(GREEN STATUS_STRING " "
YELLOW "IP:" CYAN "%s "
YELLOW "Port:" CYAN "%u"
RESET,
hostname,
ntohs(serv_addr.sin_port));
}
#endif
return 0;
#ifdef _3DS
soc_fail:
free(SOC_buffer);
memalign_fail:
ret = FSUSER_CloseArchive(NULL, &sdmcArchive);
if(ret != 0)
console_print(RED "FSUSER_CloseArchive: 0x%08X\n" RESET, (unsigned int)ret);
archive_fail:
ret = fsExit();
if(ret != 0)
console_print(RED "fsExit: 0x%08X\n" RESET, (unsigned int)ret);
fs_fail:
return -1;
#endif
}
/*! deinitialize ftp subsystem */
@ -1284,13 +1294,13 @@ ftp_exit(void)
/* deinitialize SOC service */
ret = SOC_Shutdown();
if(ret != 0)
console_print("SOC_Shutdown: 0x%08X\n", (unsigned int)ret);
console_print(RED "SOC_Shutdown: 0x%08X\n" RESET, (unsigned int)ret);
free(SOC_buffer);
/* deinitialize FS service */
ret = fsExit();
if(ret != 0)
console_print("fsExit: 0x%08X\n", (unsigned int)ret);
console_print(RED "fsExit: 0x%08X\n" RESET, (unsigned int)ret);
#endif
}
@ -1307,7 +1317,7 @@ ftp_loop(void)
rc = poll(&pollinfo, 1, 0);
if(rc < 0)
console_print("poll: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "poll: %d %s\n" RESET, Errno(), strerror(Errno()));
else if(rc > 0)
{
if(pollinfo.revents & POLLIN)
@ -1316,7 +1326,7 @@ ftp_loop(void)
}
else
{
console_print("listenfd: revents=0x%08X\n", pollinfo.revents);
console_print(YELLOW "listenfd: revents=0x%08X\n" RESET, pollinfo.revents);
}
}
@ -1436,7 +1446,7 @@ list_transfer(ftp_session_t *session)
ret = FSDIR_Read(session->fd, &entries, 1, &dent);
if(ret != 0)
{
console_print("FSDIR_Read: 0x%08X\n", (unsigned int)ret);
console_print(RED "FSDIR_Read: 0x%08X\n" RESET, (unsigned int)ret);
ftp_session_close_cwd(session);
ftp_session_set_state(session, COMMAND_STATE);
ftp_send_response(session, 450, "failed to read directory\r\n");
@ -1480,7 +1490,7 @@ list_transfer(ftp_session_t *session)
rc = lstat(session->buffer, &st);
if(rc != 0)
{
console_print("stat '%s': %d %s\n", session->buffer, errno, strerror(errno));
console_print(RED "stat '%s': %d %s\n" RESET, session->buffer, errno, strerror(errno));
ftp_session_close_cwd(session);
ftp_session_set_state(session, COMMAND_STATE);
ftp_send_response(session, 550, "unavailable\r\n");
@ -1506,10 +1516,10 @@ list_transfer(ftp_session_t *session)
{
if(Errno() == EWOULDBLOCK)
return -1;
console_print("send: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "send: %d %s\n" RESET, Errno(), strerror(Errno()));
}
else
console_print("send: %d %s\n", ECONNRESET, strerror(ECONNRESET));
console_print(YELLOW "send: %d %s\n" RESET, ECONNRESET, strerror(ECONNRESET));
ftp_session_close_cwd(session);
ftp_session_set_state(session, COMMAND_STATE);
@ -1552,10 +1562,10 @@ retrieve_transfer(ftp_session_t *session)
{
if(Errno() == EWOULDBLOCK)
return -1;
console_print("send: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "send: %d %s\n" RESET, Errno(), strerror(Errno()));
}
else
console_print("send: %d %s\n", ECONNRESET, strerror(ECONNRESET));
console_print(YELLOW "send: %d %s\n" RESET, ECONNRESET, strerror(ECONNRESET));
ftp_session_close_file(session);
ftp_session_set_state(session, COMMAND_STATE);
@ -1581,7 +1591,7 @@ store_transfer(ftp_session_t *session)
{
if(Errno() == EWOULDBLOCK)
return -1;
console_print("recv: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "recv: %d %s\n" RESET, Errno(), strerror(Errno()));
}
ftp_session_close_file(session);
@ -1589,7 +1599,6 @@ store_transfer(ftp_session_t *session)
if(rc == 0)
{
console_print("Wrote %llu bytes\n", session->filepos);
ftp_send_response(session, 226, "OK\r\n");
}
else
@ -1622,7 +1631,7 @@ store_transfer(ftp_session_t *session)
FTP_DECLARE(ALLO)
{
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -1632,7 +1641,7 @@ FTP_DECLARE(ALLO)
FTP_DECLARE(APPE)
{
/* TODO */
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -1641,7 +1650,7 @@ FTP_DECLARE(APPE)
FTP_DECLARE(CDUP)
{
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -1652,7 +1661,7 @@ FTP_DECLARE(CDUP)
FTP_DECLARE(CWD)
{
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -1677,7 +1686,7 @@ FTP_DECLARE(CWD)
ret = FSDIR_Close(fd);
if(ret != 0)
console_print("FSDIR_Close: 0x%08X\n", (unsigned int)ret);
console_print(RED "FSDIR_Close: 0x%08X\n" RESET, (unsigned int)ret);
#else
struct stat st;
int rc;
@ -1685,7 +1694,7 @@ FTP_DECLARE(CWD)
rc = stat(session->buffer, &st);
if(rc != 0)
{
console_print("stat '%s': %d %s\n", session->buffer, errno, strerror(errno));
console_print(RED "stat '%s': %d %s\n" RESET, session->buffer, errno, strerror(errno));
return ftp_send_response(session, 550, "unavailable\r\n");
}
@ -1707,7 +1716,7 @@ FTP_DECLARE(DELE)
int rc;
#endif
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -1718,14 +1727,14 @@ FTP_DECLARE(DELE)
ret = FSUSER_DeleteFile(NULL, sdmcArchive, FS_makePath(PATH_CHAR, session->buffer));
if(ret != 0)
{
console_print("FSUSER_DeleteFile: 0x%08X\n", (unsigned int)ret);
console_print(RED "FSUSER_DeleteFile: 0x%08X\n" RESET, (unsigned int)ret);
return ftp_send_response(session, 550, "failed to delete file\r\n");
}
#else
rc = unlink(session->buffer);
if(rc != 0)
{
console_print("unlink: %d %s\n", errno, strerror(errno));
console_print(RED "unlink: %d %s\n" RESET, errno, strerror(errno));
return ftp_send_response(session, 550, "failed to delete file\r\n");
}
#endif
@ -1735,7 +1744,7 @@ FTP_DECLARE(DELE)
FTP_DECLARE(FEAT)
{
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -1746,7 +1755,7 @@ FTP_DECLARE(LIST)
{
ssize_t rc;
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
if(ftp_session_open_cwd(session) != 0)
{
@ -1798,7 +1807,7 @@ FTP_DECLARE(MKD)
int rc;
#endif
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -1809,14 +1818,14 @@ FTP_DECLARE(MKD)
ret = FSUSER_CreateDirectory(NULL, sdmcArchive, FS_makePath(PATH_CHAR, session->buffer));
if(ret != 0)
{
console_print("FSUSER_OpenDirectory: 0x%08X\n", (unsigned int)ret);
console_print(RED "FSUSER_OpenDirectory: 0x%08X\n" RESET, (unsigned int)ret);
return ftp_send_response(session, 550, "failed to create directory\r\n");
}
#else
rc = mkdir(session->buffer, 0755);
if(rc != 0)
{
console_print("mkdir: %d %s\n", errno, strerror(errno));
console_print(RED "mkdir: %d %s\n" RESET, errno, strerror(errno));
return ftp_send_response(session, 550, "failed to create directory\r\n");
}
#endif
@ -1826,7 +1835,7 @@ FTP_DECLARE(MKD)
FTP_DECLARE(MODE)
{
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -1839,7 +1848,7 @@ FTP_DECLARE(MODE)
FTP_DECLARE(NLST)
{
/* TODO */
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -1848,13 +1857,13 @@ FTP_DECLARE(NLST)
FTP_DECLARE(NOOP)
{
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
return ftp_send_response(session, 200, "OK\r\n");
}
FTP_DECLARE(PASS)
{
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -1868,7 +1877,7 @@ FTP_DECLARE(PASV)
char *p;
in_port_t port;
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
memset(buffer, 0, sizeof(buffer));
@ -1879,14 +1888,14 @@ FTP_DECLARE(PASV)
session->pasv_fd = socket(AF_INET, SOCK_STREAM, 0);
if(session->pasv_fd < 0)
{
console_print("socket: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "socket: %d %s\n" RESET, Errno(), strerror(Errno()));
return ftp_send_response(session, 451, "\r\n");
}
session->pasv_addr.sin_port = htons(next_data_port());
#ifdef _3DS
console_print("binding to %s:%u\n",
console_print(YELLOW "binding to %s:%u\n" RESET,
inet_ntoa(session->pasv_addr.sin_addr),
ntohs(session->pasv_addr.sin_port));
#endif
@ -1894,7 +1903,7 @@ FTP_DECLARE(PASV)
sizeof(session->pasv_addr));
if(rc != 0)
{
console_print("bind: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "bind: %d %s\n" RESET, Errno(), strerror(Errno()));
ftp_session_close_pasv(session);
return ftp_send_response(session, 451, "\r\n");
}
@ -1902,7 +1911,7 @@ FTP_DECLARE(PASV)
rc = listen(session->pasv_fd, 5);
if(rc != 0)
{
console_print("listen: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "listen: %d %s\n" RESET, Errno(), strerror(Errno()));
ftp_session_close_pasv(session);
return ftp_send_response(session, 451, "\r\n");
}
@ -1914,14 +1923,14 @@ FTP_DECLARE(PASV)
&addrlen);
if(rc != 0)
{
console_print("getsockname: %d %s\n", Errno(), strerror(Errno()));
console_print(RED "getsockname: %d %s\n" RESET, Errno(), strerror(Errno()));
ftp_session_close_pasv(session);
return ftp_send_response(session, 451, "\r\n");
}
}
#endif
console_print("listening on %s:%u\n",
console_print(YELLOW "listening on %s:%u\n" RESET,
inet_ntoa(session->pasv_addr.sin_addr),
ntohs(session->pasv_addr.sin_port));
@ -1948,7 +1957,7 @@ FTP_DECLARE(PORT)
unsigned long val;
struct sockaddr_in addr;
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -2030,7 +2039,7 @@ FTP_DECLARE(PORT)
FTP_DECLARE(PWD)
{
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -2039,7 +2048,7 @@ FTP_DECLARE(PWD)
FTP_DECLARE(QUIT)
{
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_send_response(session, 221, "disconnecting\r\n");
ftp_session_close_cmd(session);
@ -2050,7 +2059,7 @@ FTP_DECLARE(QUIT)
FTP_DECLARE(REST)
{
/* TODO */
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -2061,7 +2070,7 @@ FTP_DECLARE(RETR)
{
int rc;
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
if(build_path(session, args) != 0)
{
@ -2120,7 +2129,7 @@ FTP_DECLARE(RMD)
int rc;
#endif
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -2131,14 +2140,14 @@ FTP_DECLARE(RMD)
ret = FSUSER_DeleteDirectory(NULL, sdmcArchive, FS_makePath(PATH_CHAR, session->buffer));
if(ret != 0)
{
console_print("FSUSER_DeleteDirectory: 0x%08X\n", (unsigned int)ret);
console_print(RED "FSUSER_DeleteDirectory: 0x%08X\n" RESET, (unsigned int)ret);
return ftp_send_response(session, 550, "failed to delete directory\r\n");
}
#else
rc = rmdir(session->buffer);
if(rc != 0)
{
console_print("rmdir: %d %s\n", errno, strerror(errno));
console_print(RED "rmdir: %d %s\n" RESET, errno, strerror(errno));
return ftp_send_response(session, 550, "failed to delete directory\r\n");
}
#endif
@ -2155,7 +2164,7 @@ FTP_DECLARE(RNFR)
int rc;
struct stat st;
#endif
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -2180,14 +2189,14 @@ FTP_DECLARE(RNFR)
if(ret != 0)
{
console_print("no such file or directory\n");
console_print(RED "no such file or directory\n" RESET);
return ftp_send_response(session, 450, "no such file or directory\r\n");
}
#else
rc = lstat(session->buffer, &st);
if(rc != 0)
{
console_print("lstat: %d %s\n", errno, strerror(errno));
console_print(RED "lstat: %d %s\n" RESET, errno, strerror(errno));
return ftp_send_response(session, 450, "no such file or directory\r\n");
}
#endif
@ -2206,7 +2215,7 @@ FTP_DECLARE(RNTO)
#endif
char buffer[XFER_BUFFERSIZE];
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -2230,14 +2239,14 @@ FTP_DECLARE(RNTO)
sdmcArchive, FS_makePath(PATH_CHAR, session->buffer));
if(ret != 0)
{
console_print("FSUSER_RenameFile/Directory: 0x%08X\n", (unsigned int)ret);
console_print(RED "FSUSER_RenameFile/Directory: 0x%08X\n" RESET, (unsigned int)ret);
return ftp_send_response(session, 550, "failed to rename file/directory\r\n");
}
#else
rc = rename(buffer, session->buffer);
if(rc != 0)
{
console_print("rename: %d %s\n", errno, strerror(errno));
console_print(RED "rename: %d %s\n" RESET, errno, strerror(errno));
return ftp_send_response(session, 550, "failed to rename file/directory\r\n");
}
#endif
@ -2249,7 +2258,7 @@ FTP_DECLARE(STOR)
{
int rc;
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
if(build_path(session, args) != 0)
{
@ -2302,7 +2311,7 @@ FTP_DECLARE(STOR)
FTP_DECLARE(STOU)
{
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -2311,7 +2320,7 @@ FTP_DECLARE(STOU)
FTP_DECLARE(STRU)
{
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -2323,7 +2332,7 @@ FTP_DECLARE(STRU)
FTP_DECLARE(SYST)
{
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -2332,7 +2341,7 @@ FTP_DECLARE(SYST)
FTP_DECLARE(TYPE)
{
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);
@ -2341,7 +2350,7 @@ FTP_DECLARE(TYPE)
FTP_DECLARE(USER)
{
console_print("%s %s\n", __func__, args ? args : "");
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
ftp_session_set_state(session, COMMAND_STATE);

3
source/gfx.c Executable file → Normal file
View File

@ -1,6 +1,6 @@
#ifdef _3DS
#include <string.h>
#include <3ds.h>
#endif
/* Function to draw sprite, from smea/3ds_hb_menu */
void gfxDrawSprite(gfxScreen_t screen, gfx3dSide_t side, u8* spriteData, u16 width, u16 height, s16 x, s16 y)
@ -29,3 +29,4 @@ void gfxDrawSprite(gfxScreen_t screen, gfx3dSide_t side, u8* spriteData, u16 wid
memcpy(&fbAdr[((x+xOffset)+(y+j)*fbWidth)*3], &spriteData[((xOffset)+(j)*width)*3], widthDrawn*3);
}
}
#endif

View File

@ -66,13 +66,13 @@ main(int argc,
srvInit();
aptInit();
hidInit(NULL);
gfxInit();
gfxInitDefault();
gfxSet3D(false);
#endif
/* initialize console subsystem */
console_init();
console_set_status(STATUS_STRING);
console_set_status("\n" GREEN STATUS_STRING RESET);
/* initialize ftp subsystem */
if(ftp_init() == 0)
@ -86,7 +86,6 @@ main(int argc,
console_print("Press B to exit\n");
loop(wait_for_b);
console_exit();
#ifdef _3DS
/* deinitialize 3DS services */