/*****************************************************************************\ * Copyright (c) 2002 Pelle Johansson. * * All rights reserved. * * * * This file is part of the moftpd package. Use and distribution of * * this software is governed by the terms in the file LICENCE, which * * should have come with this package. * \*****************************************************************************/ /* $moftpd: com_settings.c 1251 2005-03-06 22:24:29Z morth $ */ #include "system.h" #include "commands.h" #include "connection.h" #include "utf8fs/memory.h" extern const char *localeDir; extern const char *localeSuffix; /* Settings commands */ int command_mode(connection_t *conn, const char *arg, int expected) { switch(arg[0]) { case 0: reply (conn, "501 Argument missing."); return 0; case 'S': case 's': reply (conn, "200 Mode set to Stream."); return 0; case 'B': case 'b': reply (conn, "504 Mode Block unsupported."); return 0; case 'C': case 'c': reply (conn, "504 Mode Compressed unsupported."); return 0; } reply (conn, "501 Unrecognised mode."); return 0; } int command_type(connection_t *conn, const char *arg, int expected) { switch(arg[0]) { case 0: reply (conn, "501 Argument missing."); return 0; case 'A': case 'a': if (arg[1] == ' ') { switch (arg[2]) { case 0: case 'N': conn->subtype = 0; reply (conn, "200 Type set to Non-Print Text."); break; case 'T': conn->subtype = 'T'; reply (conn, "504 Type Telnet Formatted Text unsupported."); return 0; case 'C': reply (conn, "504 Type Carriage Control Text unsupported."); return 0; } } else { conn->subtype = 0; reply(conn, "200 Type set to Non-Print Text."); } conn->type = ttText; return 0; case 'E': case 'e': reply (conn, "504 Type EBCDIC unsupported."); return 0; case 'I': case 'i': reply (conn, "200 Type set to Image."); conn->type = ttImage; conn->subtype = 0; return 0; case 'L': case 'l': if (arg[1] == ' ') { if (atoi (arg + 2) == 8) { conn->type = ttImage; conn->subtype = 8; reply (conn, "200 Type set to Local 8."); } else reply (conn, "504 Unsupported local size."); } else reply (conn, "501 Missing argument to L"); return 0; } reply(conn, "501 Unrecognised type."); return 0; } int command_stru(connection_t *conn, const char *arg, int expected) { switch(arg[0]) { case 0: reply (conn, "501 Argument missing."); return 0; case 'F': case 'f': reply (conn, "200 File structure set to File."); return 0; case 'R': case 'r': reply (conn, "504 File structure Record unsupported."); return 0; case 'P': case 'p': reply (conn, "504 File structure Page unsupported."); return 0; } reply(conn, "501 Unrecognised file structure."); return 0; } int command_opts (connection_t *conn, const char *arg, int expected) { const char *ap; if (!strlen (arg)) { reply (conn, "501 Argument missing."); return 0; } if (!strncasecmp (arg, "MLST", 4) && (arg[4] == ' ' || !arg[4])) { conn->mlstTags = 0; if (arg[4]) { arg += 5; while ((ap = strchr (arg, ';'))) { switch (ap - arg) { case 4: if (!strncasecmp (arg, "TYPE", 4)) conn->mlstTags |= tfType; else if (!strncasecmp (arg, "PERM", 4)) conn->mlstTags |= tfPerm; else if (!strncasecmp (arg, "SIZE", 4)) conn->mlstTags |= tfSize; break; case 6: if (!strncasecmp (arg, "UNIQUE", 6)) conn->mlstTags |= tfUnique; else if (!strncasecmp (arg, "MODIFY", 6)) conn->mlstTags |= tfModify; break; } arg = ap + 1; } } reply (conn, "200 MLST OPTS %s%s%s%s%s", conn->mlstTags & tfType? "TYPE;" : "", conn->mlstTags & tfUnique? "UNIQUE;" : "", conn->mlstTags & tfModify? "MODIFY;" : "", conn->mlstTags & tfPerm? "PERM;" : "", conn->mlstTags & tfSize? "SIZE;" : ""); } else if (!strncasecmp (arg, "UTF8", 4) && (!arg[4] || arg[4] == ' ')) { if (arg[4] == ' ' && !strcasecmp (arg + 5, "ON")) reply (conn, "200 UTF8 is always on."); else reply (conn, "500 UTF8 is always on."); } else reply (conn, "501 No such setting."); return 0; } int command_lang(connection_t *conn, const char *arg, int expected) { char *tmp, *tp, *lp; int fd; if (!strlen (arg)) arg = "en"; tmp = talloc (strlen (localeDir) + strlen (arg) + strlen (localeSuffix) + 1); if (!tmp) { reply (conn, "500 %s", strerror (errno)); return 0; } strcpy (tmp, localeDir); lp = tp = tmp + strlen (tmp); strcpy (tp, arg); while (*tp) { *tp = tolower (*tp); tp++; } while (tp) { *tp = 0; if (!strcmp (lp, "en")) { if (conn->langFd >= 0) close_shared (conn->langFd); conn->langFd = -1; pfree (conn->currLang, conn); conn->currLang = NULL; reply (conn, "200 Language set to English."); return 0; } strcpy (tp, localeSuffix); fd = open_shared (tmp); if (fd >= 0) { if (conn->langFd >= 0) close_shared (conn->langFd); conn->langFd = fd; pfree (conn->currLang, conn); *tp = 0; conn->currLang = pstring (lp, conn); reply (conn, "200 Language set to English."); return 0; } *tp = 0; tp = strrchr (lp, '-'); } reply (conn, "504 Unknown language."); return 0; }