/*
* File: reply.c
*
* Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de)
*
* History:
*
* 10 Sep 95 Framstag initial version
* 21 Dec 95 Framstag changed multi-line format
* 17 Mar 95 Framstag replaced uname() with gethostname()
* 8 Apr 96 Framstag changed signature command
* 10 May 96 Framstag uname() is used back again
* 13 May 96 Framstag uname() and gethostname()
* 24 Sep 96 Framstag better host.domain-name determination
* 2 Dec 96 Framstag even better domain-name determination
* 29 Dec 96 Framstag included get_domainname
* 21 Jan 97 Framstag added reply 414
* 23 Feb 97 Framstag extended with TYPE=MIME
* 24 Feb 97 Framstag sprintf() -> snprintf()
* 7 Dec 97 Framstag added reply 532
* 19 Dec 97 Framstag added reply 540 and 541
* 12 Mar 98 Framstag reply 523 -> 430 (same text)
* 2001-02-06 Framstag added reply 429
*
* Send the appropiate reply code and reply text conforming to NVT telnet
* standard. Inspired by RFC-959 (ftp).
*
* Copyright © 1995-2001 Ulli Horlacher
* This file is covered by the GNU General Public License
*/
#include "config.h" /* various #defines */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "io.h" /* socket and file IO extensions */
#ifdef ULTRIX
struct utsname {
char sysname[32];
char nodename[32];
char release[32];
char version[32];
char machine[32];
};
int uname (struct utsname *);
#else
#include <sys/utsname.h>
#endif
#if defined(SOLARIS2)
int gethostname(char *, int);
#endif
#if defined(LINUX)
int gethostname(char *, size_t);
#endif
#include "string.h" /* extended string functions */
/*
* get_domainname - add domainname to host-string
*
* INPUT: host - hostname
*
* OUTPUT: host - hostname.domainname or hostname (if no domain was found)
*
* This is an ugly hack: we determin the domain by looking at /etc/resolf.conf
* if not set in sendfile.cf
*/
void get_domainname(char *host) {
char line[MAXLEN];
char *cp;
extern char domain[FLEN];
FILE *inf;
/* global variable domain set (in sendfiled.c)? */
if (*domain) {
if ((cp=strchr(host,'.'))) *(++cp)=0;
} else {
/* if host-name contains already a '.', we are ready */
if (strchr(host,'.')) return;
/* look in resolver config-file */
inf=rfopen("/etc/resolv.conf","r");
if (!inf) return;
while (fgetl(line,inf)) {
str_trim(line);
/* is there the domain or search option set? */
if (str_beq(line,"domain") || str_beq(line,"search")) {
/* isolate the domain name */
if ((cp=strchr(line,' '))) {
strcpy(domain,++cp);
if ((cp=strchr(domain,' '))) *cp=0;
break;
}
}
}
fclose(inf);
}
strcat(host,".");
strcat(host,domain);
}
/*
* reply - send string conforming to NVT telnet standard
*
* INPUT: rc - reply code
*
* terminates program on fatal error
*/
void reply(int rc) {
char *text, /* reply code and reply text */
host[FLEN+1]; /* hostname */
#ifndef NEXT
struct utsname sysname;
#endif
switch (rc) {
case 200: text="200 Command ok.";
break;
case 201: text="201 File has been received correctly.";
break;
case 202: text="202 Command not implemented, superfluous at this site.";
break;
case 203: text="203 *schnuffel* *schnuffel* =:3";
break;
case 205: text="205 Non-ASCII character in command line ignored.";
break;
case 214: text="214-The following commands are recognized:\r\n"
"214- FROM <sender> [<real name>]\r\n"
"214- TO <recipient>\r\n"
"214- FILE <name>\r\n"
"214- SIZE <bytes to transfer> <original file size uncompressed>\r\n"
"214- TYPE BINARY|SOURCE|MIME|TEXT=<character set name> [COMPRESSED|CRYPTED]\r\n"
"214- DATE <ISO-8601 date & time string (UTC)>\r\n"
"214- SIGN <pgp signature (armor)>\r\n"
"214- ATTR TAR|EXE|NONE\r\n"
"214- MSG <message>\r\n"
"214- DEL\r\n"
"214- RESEND\r\n"
"214- DATA\r\n"
"214- QUIT\r\n"
"214-All arguments have to be UTF-7 encoded.\r\n"
"214 You must specify at least FROM, TO, FILE, SIZE and "
"DATA to send a file.";
break;
case 215: text="215 sendfiled "VERSION"-"REVISION" for "SYSTEM;
break;
case 220: text=(char *) malloc(MAXLEN);
if (gethostname(host,FLEN)<0)
strcpy(host,"UNKNOWN");
else
get_domainname(host);
#ifdef NEXT
snprintf(text,MAXLEN-1,
"220 %s "PROTOCOL" server (sendfiled "VERSION
" on NeXTstep/Mach) ready.",host);
#else
if (uname(&sysname)<0)
snprintf(text,MAXLEN-1,"220 %s "PROTOCOL" server (sendfiled "
VERSION") ready.",host);
else
snprintf(text,MAXLEN-1,"220 %s "PROTOCOL" server (sendfiled "
VERSION" on %s) ready.",host,sysname.sysname);
#endif
break;
case 221: text="221 Goodbye.";
break;
case 230: text="230 <xxx Bytes already received>";
break;
case 231: text="231 <xxx Bytes will follow>";
break;
case 250: text="250 End of transfer.";
break;
case 260: text="260 DEBUG-OUTPUT";
break;
case 302: text="302 Header ok, send data.";
break;
case 331: text="331 <challenge: xxxxx>";
break;
case 401: text="401 Got unexpected EOF.";
break;
case 410: text="410 No access to spool directory (permission problems?).";
break;
case 411: text="411 Can't create user spool directory.";
break;
case 412: text="412 Can't write to user spool directory.";
break;
case 413: text="413 User spool file quota exceeded.";
break;
case 414: text="414 Can't start spool postprocessing.";
break;
case 415: text="415 TCP error: received too few data.";
break;
case 421: text="421 Service currently not available.";
break;
case 429: text="429 Timeout.";
break;
case 430: text="430 You are not allowed to send to this user.";
break;
case 451: text="451 Requested action aborted: server error.";
break;
case 452: text="452 Insufficient storage space.";
break;
case 453: text="453 Insufficient system resources.";
break;
case 460: text="460 Authentication error.";
break;
case 490: text="490 Internal error.";
break;
case 500: text="500 Syntax error, command unrecognized.";
break;
case 501: text="501 Syntax error in parameters or arguments.";
break;
case 502: text="502 Command not implemented.";
break;
case 503: text="503 Bad sequence of commands.";
break;
case 504: text="504 Command not implemented for that parameter.";
break;
case 505: text="505 Missing argument.";
break;
case 506: text="506 Command line too long.";
break;
case 507: text="507 Bad argument.";
break;
case 510: text="510 User has set a forward to xxx@yyy";
text="510-This SAFT-server can only receive messages.\r\n"
"510 Send files to xxx@yyy";
break;
case 511: text="511 This SAFT-server can only receive files.\r\n";
break;
case 512: text="512 This SAFT-server can only receive messages.\r\n";
break;
case 520: text="520 User unknown.";
break;
case 521: text="521 User is not allowed to receive files or messages.";
break;
case 522: text="522 User cannot receive messages.";
break;
case 530: text="530 Authorization failed.";
break;
case 531: text="531 This file has been already received.";
break;
case 532: text="532 This file is currently transfered by you "
"within another process.";
break;
case 540: text="540 Secure mode enforced: you have to sign your files";
break;
case 541: text="541 Secure mode enforced: you have to encrypt your files";
break;
case 550: text="550 File not found.";
break;
default: text="599 Unknown error.";
}
/* send string conforming to NVT standard */
printf("%s\r\n",text);
fflush(stdout);
/* if a fatal and non recoverable error occured terminate the program */
if (text[0]=='4') exit(1);
}
/*
* from RFC-959 (ftp):
*
* 110 Restart marker reply.
* In this case, the text is exact and not left to the
* particular implementation, it must read:
* MARK yyyy=mmmm
* Where yyyy is User-process data stream marker, and mmmm
* server's equivalent marker (note the spaces between markers
* and "=").
* 120 Service ready in nnn minutes.
* 125 Data connection already open, transfer starting.
* 150 File status okay, about to open data connection.
*
* 200 Command okay.
* 202 Command not implemented, superfluous at this site.
* 211 System status, or system help reply.
* 212 Directory status.
* 213 File status.
* 214 Help message.
* On how to use the server or the meaning of a particular
* non-standard command. This reply is useful only to the
* human user.
* 215 NAME system type.
* Where NAME is an official system name from the list in the
* Assigned Numbers document.
* 220 Service ready for new user.
* 221 Service closing control connection.
* Logged out if appropriate.
* 225 Data connection open, no transfer in progress.
* 226 Closing data connection.
* Requested file action successful (for example, file
* transfer or file abort).
* 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2).
* 230 User logged in, proceed.
* 250 Requested file action okay, completed.
* 257 "PATHNAME" created.
*
* 331 User name okay, need password.
* 332 Need account for login.
* 350 Requested file action pending further information.
*
* 421 Service not available, closing control connection.
* This may be a reply to any command if the service knows it
* must shut down.
* 425 Can't open data connection.
* 426 Connection closed, transfer aborted.
* 450 Requested file action not taken.
* File unavailable (e.g., file busy).
* 451 Requested action aborted: local error in processing.
* 452 Requested action not taken.
* Insufficient storage space in system.
* 500 Syntax error, command unrecognized.
* This may include errors such as command line too long.
* 501 Syntax error in parameters or arguments.
* 502 Command not implemented.
* 503 Bad sequence of commands.
* 504 Command not implemented for that parameter.
* 530 Not logged in.
* 532 Need account for storing files.
* 550 Requested action not taken.
* File unavailable (e.g., file not found, no access).
* 551 Requested action aborted: page type unknown.
* 552 Requested file action aborted.
* Exceeded storage allocation (for current directory or dataset).
* 553 Requested action not taken.
* File name not allowed.
*/
syntax highlighted by Code2HTML, v. 0.9.1