/* ftprc.c */

#include "sys.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>

#ifdef SCO324
#	include <sys/arpa.h>
#endif

#include <string.h>
#include <ctype.h>
#include "ftpdefs.h"
#include "defaults.h"
#include "ftprc.h"
#include "main.h"
#include "cmds.h"
#include "copyright.h"

/* ftprc.c global variables */
siteptr					firstsite = NULL, lastsite = NULL;
char					rcname[MAXPATHLEN];
int						parsing_rc = 0;

extern char				*line, *margv[];
extern int				margc;
extern string			anon_password;		/* most likely your email address */
extern struct userinfo	uinfo;

int thrash_rc(void)
{
	struct stat			st;
	string				word, str;
	char				cwd[MAXPATHLEN];
	char				*cp, *dp, *rc;
	FILE				*fp;
	int					i;

	(void) get_cwd(cwd, sizeof(cwd));
	if (cwd[strlen(cwd) - 1] != '/')
		(void) Strncat(cwd, "/");

	/* Because some versions of regular ftp complain about ncftp's
	 * #set commands, FTPRC takes precedence over NETRC.
	 */
	for (i=0; i<2; i++) {
		rc = (i == 0) ? FTPRC : NETRC;

		sprintf(rcname, "%s%s", cwd, rc);
		if (stat(rcname, &st) == 0)
			goto foundrc;
		
		sprintf(rcname, "%s.%s", cwd, rc);
		if (stat(rcname, &st) == 0)
			goto foundrc;

		(void) sprintf(rcname, "%s/.%s", uinfo.homedir, rc);
		if (stat(rcname, &st) == 0)
			goto foundrc;
	}

	return (0);	/* it's OK not to have an rc. */
	
foundrc:	
	if ((st.st_mode & 077) != 0)				/* rc must be unreadable by others. */
		(void) chmod(rcname, 0600);

	if ((fp = fopen(rcname, "r")) == NULL) {
		Perror(rcname);
		return -1;
	}
	
	parsing_rc = 1;
	while (cp = FGets(str, fp)) {
		while (isspace(*cp)) ++cp;		/* skip leading space. */
		if (*cp == '#') {
			if ((strncmp("set", ++cp, (size_t)3) == 0) || (strncmp("unset", cp, (size_t)5) == 0)) {
				(void) strcpy(line, cp);
				makeargv();
				set(margc, margv);			
				/* setting or unsetting a variable. */
			} /* else a comment. */
		} else {
			if (strncmp(cp, "machine", (size_t) 7) == 0) {
				/* We have a new machine record. */
				cp += 7;
				while (isspace(*cp)) ++cp;	/* skip delimiting space. */
				dp = word;
				while (*cp && !isspace(*cp)) *dp++ = *cp++;	/* copy the name. */
				*dp = 0;
				AddNewSitePtr(word);
			}
		}
	}
	(void) fclose(fp);
	parsing_rc = 0;
	return 1;
}	/* thrash_rc */



void AddNewSitePtr(char *word)
{
	siteptr			s;

	if (s = (siteptr) malloc(sizeof(site))) {
		s->next = NULL;
		if (s->name = malloc(strlen(word) + 1)) {
			(void) strcpy(s->name, word);
			if (firstsite == NULL)
				firstsite = lastsite = s;
			else {
				lastsite->next = s;
				lastsite = s;
			}
		} else {
			free(s);
		}
	}
}	/* AddNewSitePtr */




void GetFullSiteName(char *host)
{
	register siteptr s, s2;

	/* see if 'host' is in our list of favorite sites. */
	for (s = firstsite; s != NULL; s2=s->next, s=s2)
		if (strstr(s->name, host) != NULL) {
			(void) strcpy(host, s->name);
			break;
		}
}	/* GetFullSiteName */




int ruserpass2(char *host, char **username, char **pass, char **acct)
{
	FILE			*fp;
	char			*cp, *dp, *dst, *ep;
	str32			macname;
	char			*varname;
	int				site_found;
	string			str;
	static string	auser;
	static str32	apass, aacct;

	site_found = 0;

	if ((fp = fopen(rcname, "r")) != NULL) {
		parsing_rc = 1;
		while (FGets(str, fp)) {
			if (cp = strstr(str, "machine")) {
				/* Look for the machine token. */
				cp += 7;
				while (isspace(*cp))
					cp++;
			} else
				continue;
			if (strncmp(cp, host, strlen(host)) == 0) {
				site_found = 1;
				while (!isspace(*cp))
					++cp;		/* skip the site name. */
				do {
					/* Skip any comments ahead of time. */
					for (dp=cp; *dp; dp++) {
						if (*dp == '#') {
							*dp = 0;
							break;
						}
					}

					ep = cp;
					while (1) {
						varname = strtok(ep, RC_DELIM);
						if (!varname) break;
						dst = ep = NULL;
						switch (*varname) {
							case 'u':	/* user */
								*username = dst = auser;
								break;
							case 'l':	/* login */
								*username = dst = auser;
								break;
							case 'p':	/* password */
								*pass = dst = apass;
								break;
							case 'a':	/* account */
								*acct = dst = aacct;
								break;
						/*	case 'd':  /o default */
						/* unused -- use 'set anon_password.' */
							case 'm':	/* macdef or machine */
								if (strcmp(varname, "macdef"))
									goto done;	/* new machine record... */
								dst = macname;
								break;
							default:
								(void) fprintf(stderr, "Unknown .netrc keyword \"%s\"\n",
									varname
								);
						}
						if (dst) {
							dp = strtok(ep, RC_DELIM);
							if (dp)
								(void) strcpy(dst, dp);
							if (dst == macname) {
								/*
								 *	Read in the lines of the macro.
								 *	The macro's end is denoted by
								 *	a blank line.
								 */
								(void) make_macro(macname, fp);
								goto nextline;
							}
						}
					}
nextline: ;
				} while (cp = FGets(str, fp));
				break;
			}		/* end if we found the machine record. */
		}
done:
		parsing_rc = 0;
		(void) fclose(fp);
	}

	if (!site_found) {
		/* didn't find it in the rc. */
		return (0);
	}

	if (*username == NULL) {
		*username = "anonymous";
		*pass = anon_password;
	}

	/* Make sure the password looks like an address. */
	if (strcmp(*username, "anonymous") == 0) {
		if (*pass == NULL || index(*pass, '@') == NULL)
			*pass = anon_password;
	}
	return (1);	/* found */
}	/* ruserpass2 */

/* eof ftprc.c */
