home *** CD-ROM | disk | FTP | other *** search
- /* main.c */
-
- /* $RCSfile: main.c,v $
- * $Revision: 14020.15 $
- * $Date: 93/07/09 11:50:12 $
- */
-
- #define _main_c_
-
- #define FTP_VERSION \
- "NcFTP 1.5.0 (Aug 22, 1993) by Mike Gleason, NCEMRSoft."
-
- /* #define BETA 1 */ /* If defined, it prints a little warning message. */
-
- #include "sys.h"
- #include <sys/types.h>
- #include <sys/param.h>
- #include <sys/socket.h>
- #include <sys/stat.h>
- #include <sys/time.h>
- #include <arpa/ftp.h>
- #include <setjmp.h>
- #include <signal.h>
- #include <string.h>
- #include <errno.h>
- #include <ctype.h>
- #include <netdb.h>
- #include <pwd.h>
-
- #ifdef SYSLOG
- # include <syslog.h>
- #endif
-
- #ifndef NO_UNISTDH
- # include <unistd.h>
- #endif
-
- #ifdef CURSES
- # undef HZ /* Collides with HaZeltine ! */
- # include <curses.h>
- #endif /* CURSES */
-
- #include "util.h"
- #include "cmds.h"
- #include "main.h"
- #include "ftp.h"
- #include "ftprc.h"
- #include "open.h"
- #include "set.h"
- #include "defaults.h"
- #include "copyright.h"
-
- /* main.c globals */
- int slrflag;
- int fromatty; /* input is from a terminal */
- int toatty; /* output is to a terminal */
- int doing_script; /* is a file being <redirected to me? */
- char *altarg; /* argv[1] with no shell-like preprocessing */
- struct servent serv; /* service spec for tcp/ftp */
- jmp_buf toplevel; /* non-local goto stuff for cmd scanner */
- char *line; /* input line buffer */
- char *stringbase; /* current scan point in line buffer */
- char *argbuf; /* argument storage buffer */
- char *argbase; /* current storage point in arg buffer */
- int margc; /* count of arguments on input line */
- char *margv[20]; /* args parsed from input line */
- struct userinfo uinfo; /* a copy of their pwent really */
- int ansi_escapes; /* for fancy graphics */
- int startup_msg = 1; /* TAR: display message on startup? */
- int ignore_rc; /* are we supposed to ignore the netrc */
- string progname; /* simple filename */
- string prompt, prompt2; /* shell prompt string */
- string anon_password; /* most likely your email address */
- string pager; /* program to browse text files */
- string version = FTP_VERSION;
- long eventnumber; /* number of commands we've done */
- FILE *logf = NULL; /* log user activity */
- longstring logfname; /* name of the logfile */
- long logsize = 4096L; /* max log size. 0 == no limit */
- int percent_flags; /* "%" in prompt string? */
- int at_flags; /* "@" in prompt string? */
- string mail_path; /* your mailbox */
- time_t mbox_time; /* last modified time of mbox */
- size_t epromptlen; /* length of the last line of the
- * prompt as it will appear on screen,
- * (i.e. no invis escape codes).
- */
- char *tcap_normal = "\033[0m"; /* Default ANSI escapes */
- char *tcap_boldface = "\033[1m";
- char *tcap_underline = "\033[4m";
- char *tcap_reverse = "\033[7m";
- size_t tcl_normal = 4, /* lengths of the above strings. */
- tcl_bold = 4,
- tcl_uline = 4,
- tcl_rev = 4;
-
- #ifdef CURSES
- static char tcbuf[2048];
- #endif
-
- /* main.c externs */
- extern int debug, verbose, mprompt;
- extern int options, cpend, data, connected, logged_in;
- extern int curtype, macnum, remote_is_unix;
- extern FILE *cout;
- extern struct cmd cmdtab[];
- extern str32 curtypename;
- extern char *macbuf;
- extern char *reply_string;
- extern char *short_verbose_msgs[4];
- extern string vstr;
- extern Hostname hostname;
- extern longstring cwd, lcwd, recent_file;
- extern int Optind;
- extern char *Optarg;
- #ifdef GATEWAY
- extern string gate_login;
- #endif
-
- void main(int argc, char **argv)
- {
- register char *cp;
- int top, opt, openopts = 0;
- string tmp, oline;
- struct servent *sptr;
-
- if ((cp = rindex(argv[0], '/'))) cp++;
- else cp = argv[0];
- (void) Strncpy(progname, cp);
-
- sptr = getservbyname("ftp", "tcp");
- if (sptr == 0) fatal("ftp/tcp: unknown service");
- serv = *sptr;
-
- if (init_arrays()) /* Reserve large blocks of memory now */
- fatal("could not reserve large amounts of memory.");
-
- /*
- * Set up defaults for FTP.
- */
- mprompt = dMPROMPT;
- debug = dDEBUG;
- verbose = dVERBOSE;
- (void) Strncpy(vstr, short_verbose_msgs[verbose+1]);
-
- (void) Strncpy(curtypename, dTYPESTR);
- curtype = dTYPE;
- (void) Strncpy(prompt, dPROMPT);
- #ifdef GATEWAY
- (void) Strncpy(gate_login, dGATEWAY_LOGIN);
- #endif
-
- #ifdef SOCKS
- SOCKSinit("ncftp");
- #endif
-
- /* Setup our pager variable, before we run through the rc,
- which may change it. */
- set_pager(getenv("PAGER"), 0);
- #ifdef CURSES
- ansi_escapes = 1;
- termcap_init();
- #else
- ansi_escapes = 0;
- if ((cp = getenv("TERM")) != NULL) {
- if ((*cp == 'v' && cp[1] == 't') /* vt100, vt102, ... */
- || (strcmp(cp, "xterm") == 0))
- ansi_escapes = 1;
- }
- #endif
- (void) getuserinfo();
-
- /* Init the mailbox checking code. */
- (void) time(&mbox_time);
-
- (void) Strncpy(anon_password, uinfo.username);
- if (getlocalhostname(uinfo.hostname, sizeof(uinfo.hostname)) == 0) {
- (void) Strncat(anon_password, "@");
- (void) Strncat(anon_password, uinfo.hostname);
- }
- #if dLOGGING
- (void) Strncpy(logfname, dLOGNAME);
- (void) LocalDotPath(logfname);
- #else
- *logfname = 0;
- #endif
- (void) Strncpy(recent_file, dRECENTF);
- (void) LocalDotPath(recent_file);
-
- (void) get_cwd(lcwd, (int) sizeof(lcwd));
-
- #ifdef SYSLOG
- # ifdef LOG_LOCAL3
- openlog ("NcFTP", LOG_PID, LOG_LOCAL3);
- # else
- openlog ("NcFTP", LOG_PID);
- # endif
- #endif /* SYSLOG */
-
-
- ignore_rc = 0;
- (void) strcpy(oline, "open ");
- while ((opt = Getopt(argc, argv, "D:V:INRHaicmup:rd:g:")) >= 0) {
- switch(opt) {
- case 'a':
- case 'c':
- case 'i':
- case 'm':
- case 'u':
- case 'r':
- (void) sprintf(tmp, "-%c ", opt);
- goto cattmp;
-
- case 'p':
- case 'd':
- case 'g':
- (void) sprintf(tmp, "-%c %s ", opt, Optarg);
- cattmp:
- (void) strcat(oline, tmp);
- openopts++;
- break;
-
- case 'D':
- debug = atoi(Optarg);
- break;
-
- case 'V':
- set_verbose(Optarg, 0);
- break;
-
- case 'I':
- mprompt = !mprompt;
- break;
-
- case 'N':
- ++ignore_rc;
- break;
-
- case 'H':
- (void) show_version(0, NULL);
- exit (0);
-
- default:
- usage:
- (void) fprintf(stderr, "Usage: %s [program options] [[open options] site.to.open[:path]]\n\
- Program Options:\n\
- -D x : Set debugging level to x (a number).\n\
- -H : Show version and compilation information.\n\
- -I : Toggle interactive (mprompt) mode.\n\
- -N : Toggle reading of the .netrc/.ncftprc.\n\
- -V x : Set verbosity to level x (-1,0,1,2).\n\
- Open Options:\n\
- -a : Open anonymously (this is the default).\n\
- -u : Open, specify user/password.\n\
- -i : Ignore machine entry in your .netrc.\n\
- -p N : Use port #N for connection.\n\
- -r : \"Redial\" until connected.\n\
- -d N : Redial, pausing N seconds between tries.\n\
- -g N : Redial, giving up after N tries.\n\
- :path : ``Colon-mode:'' If \"path\" is a file, it opens site, retrieves\n\
- file \"path,\" then exits; if \"path\" is a remote directory,\n\
- it opens site then starts you in that directory..\n\
- -c : If you're using colon-mode with a file path, this will cat the\n\
- file to stdout instead of storing on disk.\n\
- -m : Just like -c, only it pipes the file to your $PAGER.\n\
- Examples:\n\
- ncftp ftp.unl.edu:/pub/README (just fetches README then quits)\n\
- ncftp (just enters ncftp command shell)\n\
- ncftp -V -u ftp.unl.edu\n\
- ncftp -c ftp.unl.edu:/pub/README (cats README to stdout then quits)\n\
- ncftp -D -r -d 120 -g 10 ftp.unl.edu\n", progname);
- exit(1);
- }
- }
-
- cp = argv[Optind]; /* the site to open. */
- if (cp == NULL) {
- if (openopts)
- goto usage;
- } else
- (void) strcat(oline, cp);
-
- if (ignore_rc <= 0)
- (void) thrash_rc();
- if (ignore_rc <= 1)
- ReadRecentSitesFile();
-
- (void) fix_options(); /* adjust "options" according to "debug" */
-
- fromatty = doing_script = isatty(0);
- toatty = isatty(1);
- (void) UserLoggedIn(); /* Init parent-death detection. */
- cpend = 0; /* no pending replies */
-
- if (*logfname)
- logf = fopen (logfname, "a");
-
-
- /* The user specified a host, maybe in 'colon-mode', on the command
- * line. Open it now...
- */
- if (argc > 1 && cp) {
- if (setjmp(toplevel))
- exit(0);
- (void) Signal(SIGINT, intr);
- (void) Signal(SIGPIPE, lostpeer);
- (void) strcpy(line, oline);
- makeargv();
- /* setpeer uses this to tell if it was called from the cmd-line. */
- eventnumber = 0L;
- (void) cmdOpen(margc, margv);
- }
- eventnumber = 1L;
-
- (void) init_prompt();
-
- if (startup_msg) { /* TAR */
- if (ansi_escapes) {
- #ifdef BETA
- # define BETA_MSG "\n\
- For testing purposes only. Do not re-distribute or subject to novice users."
- #else
- # define BETA_MSG ""
- #endif
-
- #ifndef CURSES
- (void) printf("%s%s%s%s\n",
- tcap_boldface, FTP_VERSION, BETA_MSG, tcap_normal);
- #else
- string vis;
- (void) sprintf(vis, "%s%s%s%s\n",
- tcap_boldface, FTP_VERSION, BETA_MSG, tcap_normal);
- tcap_put(vis);
- #endif /* !CURSES */
- }
- else
- (void) printf("%s%s\n", FTP_VERSION, BETA_MSG);
- } /* TAR */
- if (NOT_VQUIET)
- PrintTip();
- top = setjmp(toplevel) == 0;
- if (top) {
- (void) Signal(SIGINT, intr);
- (void) Signal(SIGPIPE, lostpeer);
- }
- for (;;) {
- (void) cmdscanner(top);
- top = 1;
- }
- } /* main */
-
-
-
- /*ARGSUSED*/
- void intr SIG_PARAMS
- {
- dbprintf("intr()\n");
- (void) Signal(SIGINT, intr);
- (void) longjmp(toplevel, 1);
- } /* intr */
-
-
-
- int getuserinfo(void)
- {
- register char *cp;
- struct passwd *pw;
- string str;
- extern char *home; /* for glob.c */
-
- pw = getpwuid(getuid());
- if (pw != NULL) {
- (void) Strncpy(uinfo.username, pw->pw_name);
- (void) Strncpy(uinfo.shell, pw->pw_shell);
- (void) Strncpy(uinfo.homedir, pw->pw_dir);
- uinfo.uid = pw->pw_uid;
- home = uinfo.homedir; /* for glob.c */
- cp = getenv("MAIL");
- if (cp == NULL)
- cp = getenv("mail");
- if (cp == NULL)
- (void) sprintf(str, "/usr/spool/mail/%s", uinfo.username);
- else
- (void) Strncpy(str, cp);
- cp = str;
-
- /*
- * mbox variable may be like MAIL=(28 /usr/mail/me /usr/mail/you),
- * so try to find the first mail path.
- */
- while ((*cp != '/') && (*cp != 0))
- cp++;
- (void) Strncpy(mail_path, cp);
- if ((cp = index(mail_path, ' ')) != NULL)
- *cp = '\0';
- return (0);
- } else {
- (void) Strncpy(uinfo.username, "unknown");
- (void) Strncpy(uinfo.shell, "/bin/sh");
- (void) Strncpy(uinfo.homedir, "."); /* current directory */
- uinfo.uid = 999;
- return (-1);
- }
- } /* getuserinfo */
-
-
-
-
- int init_arrays(void)
- {
- if ((macbuf = (char *) malloc((size_t)(MACBUFLEN))) == NULL)
- goto barf;
- if ((line = (char *) malloc((size_t)(CMDLINELEN))) == NULL)
- goto barf;
- if ((argbuf = (char *) malloc((size_t)(CMDLINELEN))) == NULL)
- goto barf;
- if ((reply_string = (char *) malloc((size_t)(RECEIVEDLINELEN))) == NULL)
- goto barf;
-
- *macbuf = '\0';
- init_transfer_buffer();
- return (0);
- barf:
- return (-1);
- } /* init_arrays */
-
-
-
- #ifndef BUFSIZ
- #define BUFSIZ 512
- #endif
-
- void init_transfer_buffer(void)
- {
- extern char *xferbuf;
- extern size_t xferbufsize;
-
- /* Make sure we use a multiple of BUFSIZ for efficiency. */
- xferbufsize = (MAX_XFER_BUFSIZE / BUFSIZ) * BUFSIZ;
- while (1) {
- xferbuf = (char *) malloc (xferbufsize);
- if (xferbuf != NULL || xferbufsize < 1024)
- break;
- xferbufsize >>= 2;
- }
-
- if (xferbuf != NULL) return;
- fatal("out of memory for transfer buffer.");
- } /* init_transfer_buffer */
-
-
-
-
- void init_prompt(void)
- {
- register char *cp;
-
- percent_flags = at_flags = 0;
- for (cp = prompt; *cp; cp++) {
- if (*cp == '%') percent_flags = 1;
- else if (*cp == '@') at_flags = 1;
- }
- } /* init_prompt */
-
-
-
- /*ARGSUSED*/
- void lostpeer SIG_PARAMS
- {
- if (connected) {
- close_streams(1);
- if (data >= 0) {
- (void) shutdown(data, 1+1);
- (void) close(data);
- data = -1;
- }
- connected = 0;
- }
- if (connected) {
- close_streams(1);
- connected = 0;
- }
- hostname[0] = cwd[0] = 0;
- logged_in = macnum = 0;
- } /* lostpeer */
-
-
- /*
- * Command parser.
- */
- void cmdscanner(int top)
- {
- register struct cmd *c;
- #ifdef CURSES
- string vis, *vp;
- #endif
-
- if (!top)
- (void) putchar('\n');
- for (;;) {
- if (!doing_script && !UserLoggedIn())
- (void) quit(0, NULL);
- if (Gets(strprompt(), line, (size_t)CMDLINELEN) == NULL) {
- (void) quit(0, NULL); /* control-d */
- }
- eventnumber++;
- dbprintf("\"%s\"\n", line);
- (void) makeargv();
- if (margc == 0) {
- continue; /* blank line... */
- }
- c = getcmd(margv[0]);
- if (c == (struct cmd *) -1) {
- (void) printf("?Ambiguous command\n");
- continue;
- }
- if (c == 0) {
- if (!implicit_cd(margv[0]))
- (void) printf("?Invalid command\n");
- continue;
- }
- if (c->c_conn && !connected) {
- (void) printf ("Not connected.\n");
- continue;
- }
- if ((*c->c_handler)(margc, margv) == USAGE)
- cmd_usage(c);
- if (c->c_handler != help)
- break;
- }
- (void) Signal(SIGINT, intr);
- (void) Signal(SIGPIPE, lostpeer);
- } /* cmdscanner */
-
-
-
-
- char *strprompt(void)
- {
- time_t tyme;
- char eventstr[8];
- char *dname, *lastlinestart;
- register char *p, *q;
- string str;
- int flag;
-
- if (at_flags == 0 && percent_flags == 0) {
- epromptlen = strlen(prompt);
- return (prompt); /* But don't overwrite it! */
- }
- epromptlen = 0;
- lastlinestart = prompt2;
- if (at_flags) {
- for (p = prompt, q = prompt2, *q = 0; (*p); p++) {
- if (*p == '@') switch (flag = *++p) {
- case '\0':
- --p;
- break;
- case 'M':
- if (CheckNewMail() > 0)
- q = Strpcpy(q, "(Mail) ");
- break;
- case 'N':
- q = Strpcpy(q, "\n");
- lastlinestart = q;
- epromptlen = 0;
- break;
- case 'P': /* reset to no bold, no uline, no inverse, etc. */
- if (ansi_escapes) {
- q = Strpcpy(q, tcap_normal);
- epromptlen += tcl_normal;
- }
- break;
- case 'B': /* toggle boldface */
- if (ansi_escapes) {
- q = Strpcpy(q, tcap_boldface);
- epromptlen += tcl_bold;
- }
- break;
- case 'U': /* toggle underline */
- if (ansi_escapes) {
- q = Strpcpy(q, tcap_underline);
- epromptlen += tcl_uline;
- }
- break;
- case 'R':
- case 'I': /* toggle inverse (reverse) video */
- if (ansi_escapes) {
- q = Strpcpy(q, tcap_reverse);
- epromptlen += tcl_rev;
- }
- break;
- case 'D': /* insert current directory */
- case 'J':
- if ((flag == 'J') && (remote_is_unix)) {
- /* Not the whole path, just the dir name. */
- dname = rindex(cwd, '/');
- if (dname == NULL)
- dname = cwd;
- else if ((dname != cwd) && (dname[1]))
- ++dname;
- } else
- dname = cwd;
- if (dname[0]) {
- q = Strpcpy(q, dname);
- q = Strpcpy(q, " ");
- }
- break;
- case 'H': /* insert name of connected host */
- if (logged_in) {
- (void) sprintf(str, "%s ", hostname);
- q = Strpcpy(q, str);
- }
- break;
- case 'C': /* Insert host:path (colon-mode format. */
- if (logged_in) {
- (void) sprintf(str, "%s:%s ", hostname, cwd);
- q = Strpcpy(q, str);
- } else
- q = Strpcpy(q, "(not connected)");
- break;
- case 'c':
- if (logged_in) {
- (void) sprintf(str, "%s:%s\n", hostname, cwd);
- q = Strpcpy(q, str);
- lastlinestart = q; /* there is a \n at the end. */
- epromptlen = 0;
- }
- break;
- case '!':
- case 'E': /* insert event number */
- (void) sprintf(eventstr, "%ld", eventnumber);
- q = Strpcpy(q, eventstr);
- break;
- default:
- *q++ = *p; /* just copy it; unknown switch */
- } else
- *q++ = *p;
- }
- *q = '\0';
- } else
- (void) strcpy(prompt2, prompt);
-
- if (percent_flags) {
- /* only strftime if the user requested it (with a %something),
- otherwise don't waste time doing nothing. */
- (void) time(&tyme);
- (void) Strncpy(str, prompt2);
- (void) strftime(prompt2, sizeof(str), str, localtime(&tyme));
- }
- epromptlen = (size_t) ((long) strlen(lastlinestart) - (long) epromptlen);
- return (prompt2);
- } /* strprompt */
-
-
- /*
- * Slice a string up into argc/argv.
- */
-
- void makeargv(void)
- {
- char **argp;
-
- margc = 0;
- argp = margv;
- stringbase = line; /* scan from first of buffer */
- argbase = argbuf; /* store from first of buffer */
- slrflag = 0;
- while (*argp++ = slurpstring())
- margc++;
- } /* makeargv */
-
-
-
-
- /*
- * Parse string into argbuf;
- * implemented with FSM to
- * handle quoting and strings
- */
- char *slurpstring(void)
- {
- int got_one = 0;
- register char *sb = stringbase;
- register char *ap = argbase;
- char *tmp = argbase; /* will return this if token found */
-
- if (*sb == '!' || *sb == '$') { /* recognize ! as a token for shell */
- switch (slrflag) { /* and $ as token for macro invoke */
- case 0:
- slrflag++;
- stringbase++;
- return ((*sb == '!') ? "!" : "$");
- /* NOTREACHED */
- case 1:
- slrflag++;
- altarg = stringbase;
- break;
- default:
- break;
- }
- }
-
- S0:
- switch (*sb) {
-
- case '\0':
- goto OUT;
-
- case ' ':
- case '\t':
- case '\n':
- case '=':
- sb++; goto S0;
-
- default:
- switch (slrflag) {
- case 0:
- slrflag++;
- break;
- case 1:
- slrflag++;
- altarg = sb;
- break;
- default:
- break;
- }
- goto S1;
- }
-
- S1:
- switch (*sb) {
-
- case ' ':
- case '\t':
- case '\n':
- case '=':
- case '\0':
- goto OUT; /* end of token */
-
- case '\\':
- sb++; goto S2; /* slurp next character */
-
- case '"':
- sb++; goto S3; /* slurp quoted string */
-
- default:
- *ap++ = *sb++; /* add character to token */
- got_one = 1;
- goto S1;
- }
-
- S2:
- switch (*sb) {
-
- case '\0':
- goto OUT;
-
- default:
- *ap++ = *sb++;
- got_one = 1;
- goto S1;
- }
-
- S3:
- switch (*sb) {
-
- case '\0':
- goto OUT;
-
- case '"':
- sb++; goto S1;
-
- default:
- *ap++ = *sb++;
- got_one = 1;
- goto S3;
- }
-
- OUT:
- if (got_one)
- *ap++ = '\0';
- argbase = ap; /* update storage pointer */
- stringbase = sb; /* update scan pointer */
- if (got_one) {
- return(tmp);
- }
- switch (slrflag) {
- case 0:
- slrflag++;
- break;
- case 1:
- slrflag++;
- altarg = (char *) 0;
- break;
- default:
- break;
- }
- return((char *)0);
- } /* slurpstring */
-
- /*
- * Help command.
- * Call each command handler with argc == 0 and argv[0] == name.
- */
- int
- help(int argc, char **argv)
- {
- register struct cmd *c;
- int showall = 0, helpall = 0;
- char *arg;
- int i, j, k;
- int nRows, nCols;
- int nCmds2Print;
- int screenColumns;
- int len, widestName;
- char *cp, **cmdnames, spec[16];
-
- if (argc == 2) {
- showall = (strcmp(argv[1], "showall") == 0);
- helpall = (strcmp(argv[1], "helpall") == 0);
- }
- if (argc == 1 || showall) {
- (void) printf("\
- Commands may be abbreviated. 'help showall' shows aliases, invisible and\n\
- unsupported commands. 'help <command>' gives a brief description of <command>.\n\n");
-
- for (c = cmdtab, nCmds2Print=0; c->c_name != NULL; c++)
- if (!c->c_hidden || showall)
- nCmds2Print++;
-
- if ((cmdnames = (char **) malloc(sizeof(char *) * nCmds2Print)) == NULL)
- fatal("out of memory!");
-
- for (c = cmdtab, i=0, widestName=0; c->c_name != NULL; c++) {
- if (!c->c_hidden || showall) {
- cmdnames[i++] = c->c_name;
- len = (int) strlen(c->c_name);
- if (len > widestName)
- widestName = len;
- }
- }
-
- if ((cp = getenv("COLUMNS")) == NULL)
- screenColumns = 80;
- else
- screenColumns = atoi(cp);
-
- widestName += 2; /* leave room for white-space in between cols. */
- nCols = screenColumns / widestName;
- /* if ((screenColumns % widestName) > 0) nCols++; */
- nRows = nCmds2Print / nCols;
- if ((nCmds2Print % nCols) > 0)
- nRows++;
-
- (void) sprintf(spec, "%%-%ds", widestName);
- for (i=0; i<nRows; i++) {
- for (j=0; j<nCols; j++) {
- k = nRows*j + i;
- if (k < nCmds2Print)
- (void) printf(spec, cmdnames[k]);
- }
- (void) printf("\n");
- }
- free(cmdnames);
- } else if (helpall) {
- /* Really intended to debug the help strings. */
- for (c = cmdtab; c->c_name != NULL; c++) {
- cmd_help(c);
- cmd_usage(c);
- }
- } else while (--argc > 0) {
- arg = *++argv;
- c = getcmd(arg);
- if (c == (struct cmd *)-1)
- (void) printf("?Ambiguous help command %s\n", arg);
- else if (c == (struct cmd *)0)
- (void) printf("?Invalid help command %s\n", arg);
- else {
- cmd_help(c);
- cmd_usage(c);
- }
- }
- return NOERR;
- } /* help */
-
-
- /*
- * If the user wants to, s/he can specify the maximum size of the log
- * file, so it doesn't waste too much disk space. If the log is too
- * fat, trim the older lines (at the top) until we're under the limit.
- */
- void trim_log(void)
- {
- FILE *new, *old;
- struct stat st;
- long fat;
- string tmplogname, str;
-
- if (logsize <= 0 || *logfname == 0 || stat(logfname, &st) ||
- (old = fopen(logfname, "r")) == NULL)
- return; /* never trim, or no log */
- fat = st.st_size - logsize;
- if (fat <= 0L) return; /* log too small yet */
- while (fat > 0L) {
- if (FGets(str, old) == NULL) return;
- fat -= (long) strlen(str);
- }
- /* skip lines until a new site was opened */
- while (1) {
- if (FGets(str, old) == NULL) {
- (void) fclose(old);
- (void) unlink(logfname);
- return; /* nothing left, start anew */
- }
- if (*str != '\t') break;
- }
-
- /* copy the remaining lines in "old" to "new" */
- (void) Strncpy(tmplogname, logfname);
- tmplogname[strlen(tmplogname) - 1] = 'T';
- if ((new = fopen(tmplogname, "w")) == NULL) {
- (void) PERROR("trim_log", tmplogname);
- return;
- }
- (void) fputs(str, new);
- while (FGets(str, old))
- (void) fputs(str, new);
- (void) fclose(old); (void) fclose(new);
- if (unlink(logfname) < 0)
- PERROR("trim_log", logfname);
- if (rename(tmplogname, logfname) < 0)
- PERROR("trim_log", tmplogname);
- } /* trim_log */
-
-
-
-
- int CheckNewMail(void)
- {
- struct stat stbuf;
-
- if (*mail_path == '\0') return 0;
- if (stat(mail_path, &stbuf) < 0) { /* cant find mail_path so we'll */
- *mail_path = '\0'; /* never check it again */
- return 0;
- }
-
- /*
- * Check if the size is non-zero and the access time is less than
- * the modify time -- this indicates unread mail.
- */
- if ((stbuf.st_size != 0) && (stbuf.st_atime <= stbuf.st_mtime)) {
- if (stbuf.st_mtime > mbox_time) {
- (void) printf("%s\n", NEWMAILMESSAGE);
- mbox_time = stbuf.st_mtime;
- }
- return 1;
- }
-
- return 0;
- } /* CheckNewMail */
-
-
-
- #ifdef CURSES
- void termcap_get(char *dest, char *attr)
- {
- static char area[1024];
- static char *s = area;
- char buf[32];
- int foo;
-
- (void) Strncpy(buf, tgetstr(attr, &s));
- if (buf[0]) {
- for (foo = 0; (buf[foo] <= '9') && (buf[foo] >= '0'); foo++);
- if ((dest = (char *)malloc(strlen(&(buf[foo])) + 1)) == NULL)
- *dest = 0;
- else
- (void) strcpy(dest, &(buf[foo]));
- } else
- *dest = 0;
- } /* termcap_get */
-
-
-
- void termcap_init(void)
- {
- static char area[1024];
- static char *s = area;
- char *term;
-
- if ((term = getenv("TERM")) == NULL) {
- term = "dumb"; /* TAR */
- ansi_escapes = 0;
- }
- if (tgetent(tcbuf,term) != 1) {
- (void) fprintf(stderr,"Can't get termcap entry for terminal [%s]\n", term);
- } else {
- termcap_get(tcap_normal, "me");
- termcap_get(tcap_boldface, "md");
- termcap_get(tcap_underline, "us");
- termcap_get(tcap_reverse, "so");
- tcl_normal = strlen(tcap_normal);
- tcl_bold = strlen(tcap_boldface);
- tcl_uline = strlen(tcap_underline);
- tcl_rev = strlen(tcap_reverse);
- }
- } /* termcap_init */
-
-
-
- static int c_output(int c)
- {
- putchar(c);
- } /* c_output */
-
-
-
-
- void tcap_put(char *cap)
- {
- tputs(cap, 0, c_output);
- } /* tcap_put */
-
- #endif /* CURSES */
-
- /* eof main.c */
-