mirror of
https://github.com/wiiu-env/ftpiiu_plugin.git
synced 2024-12-22 19:11:47 +01:00
Replace console with one built-in to libctru
This commit is contained in:
parent
1797235420
commit
20f29f60b8
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.
@ -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, ...);
|
||||
|
@ -1,3 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
void gfxDrawSprite(gfxScreen_t screen, gfx3dSide_t side, u8* spriteData, u16 width, u16 height, s16 x, s16 y);
|
||||
#ifdef _3DS
|
||||
#include <3ds.h>
|
||||
|
||||
void gfxDrawSprite(gfxScreen_t screen, gfx3dSide_t side, u8* spriteData, u16 width, u16 height, s16 x, s16 y);
|
||||
|
||||
#endif
|
||||
|
654
source/console.c
654
source/console.c
@ -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, ...)
|
||||
{
|
||||
|
277
source/ftp.c
277
source/ftp.c
@ -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);
|
||||
|
||||
|
5
source/gfx.c
Executable file → Normal file
5
source/gfx.c
Executable file → Normal 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)
|
||||
@ -28,4 +28,5 @@ 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
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user