"Fossies" - the Fresh Open Source Software archive 
Member "cftp-0.12/fn_basic.c" of archive cftp-0.12.tar.gz:
/*
$NiH: fn_basic.c,v 1.28 2002/09/16 12:42:30 dillo Exp $
fn_basic.c -- bindable functions: basics
Copyright (C) 1996-2002 Dieter Baron
This file is part of cftp, a fullscreen ftp client
The author can be contacted at <dillo@giga.or.at>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "util.h"
#include "directory.h"
#include "ftp.h"
#include "bindings.h"
#include "functions.h"
#include "display.h"
#include "rc.h"
#include "options.h"
#include "tty.h"
#include "list.h"
#include "tag.h"
#include "status.h"
#include "keys.h"
extern char version[];
void fn_version(char **args)
{
disp_status(DISP_STATUS, "%s", version);
}
void fn_redraw(char **args)
{
if (args && strcmp(args[0], "-c") == 0) {
aux_scroll(list->cur-(win_lines/2), list->cur, -1);
}
disp_redraw();
}
void
fn_showname(char **args)
{
char *tmp;
if (args && strcmp(args[0], "-u") == 0) {
switch (binding_state) {
case bs_remote:
disp_status(DISP_STATUS, "ftp://%s%s%s%s",
status.host, curdir->path,
(strcmp(curdir->path, "/") == 0 ? "" : "/"),
LIST_LINE(list, list->cur)->name);
break;
case bs_tag:
disp_status(DISP_STATUS, "ftp://%s%s", status.host,
LIST_LINE(list, list->cur)->name);
break;
default:
disp_status(DISP_STATUS, "");
}
}
else if (args && strcmp(args[0], "-l") == 0) {
switch (binding_state) {
case bs_remote:
tmp = ((direntry *)LIST_LINE(list, list->cur))->link;
disp_status(DISP_STATUS, "%s", tmp ? tmp : "");
break;
default:
disp_status(DISP_STATUS, "");
}
}
else
disp_status(DISP_STATUS, "%s", LIST_LINE(list, list->cur)->name);
}
void fn_help(char **args)
{
static char spaces[] = " ";
struct binding *b;
FILE *f;
int what, c, i, j, l;
char *s, *t;
what = read_char("Help on <f>unction, <k>ey, or <o>ption "
"(shift for list)? ");
switch (what) {
case 'f':
s = read_string("Function: ", 1);
if (s == NULL || s[0] == '\0') {
free(s);
disp_status(DISP_STATUS, "");
return;
}
if ((i=find_function(s)) == -1)
disp_status(DISP_STATUS, "no such function: %s", s);
else
disp_status(DISP_STATUS, "%s: %s",
functions[i].name, functions[i].help);
free(s);
break;
case 'F':
if ((f=disp_open(opt_pager, 1)) == NULL)
return;
for (i=0; functions[i].name; i++) {
fprintf(f, "%-16.16s %s\n", functions[i].name, functions[i].help);
}
disp_close(f, 1);
disp_status(DISP_STATUS, "");
break;
case 'k':
c = read_char("Key: ");
b = get_function(c, bs_none);
if ((i=b->fn) == -1)
disp_status(DISP_STATUS, "[%s%s] key is unbound",
(binding_state != bs_none ?
binding_statename[binding_state] : ""),
print_key(c, 0));
else {
char *buf;
int cols;
cols = tty_cols;
if ((buf=(char *)malloc(cols+5)) == NULL)
break;
sprintf(buf, "[%s%s] %s",
(b->state != bs_none ?
binding_statename[b->state] : ""),
print_key(c, 0),
functions[i].name);
if (b->args) {
int i, l;
l = strlen(buf);
for (i=0; b->args[i]; i++)
if (strlen(b->args[i])+l+2 > cols) {
strcpy(buf+l, " ...");
break;
}
else {
sprintf(buf+l, " %s", b->args[i]);
l += strlen(b->args[i])+1;
}
}
disp_status(DISP_STATUS, "%s", buf);
free(buf);
}
break;
case 'K':
if ((f=disp_open(opt_pager, 1)) == NULL)
return;
for (i=0; i<max_fnkey+256; i++) {
for (b=&binding[i]; b; b=b->next) {
if (b->fn != -1) {
s = (b->state != bs_none ?
binding_statename[b->state] : "");
t = print_key(i, 0);
l = strlen(s)+strlen(t);
fprintf(f, "%s%s%s%s",
s, t, spaces+((l>16) ? 16 : l),
functions[b->fn].name);
if (b->args) {
for (j=0; b->args[j]; j++)
fprintf(f, " %s", b->args[j]);
}
fputc('\n', f);
}
}
}
disp_close(f, 1);
disp_status(DISP_STATUS, "");
break;
case 'o':
s = read_string("Option: ", 1);
if (s == NULL || s[0] == '\0') {
free(s);
disp_status(DISP_STATUS, "");
return;
}
for (i=0; option[i].name; i++)
if (strcasecmp(option[i].name, s) == 0
|| strcasecmp(option[i].shrt, s) == 0)
break;
if (option[i].name == NULL)
disp_status(DISP_STATUS, "no such option: %s", s);
else {
char *buf;
switch(option[i].type) {
case OPT_INT:
if ((buf=(char *)malloc(30)) == NULL)
break;
sprintf(buf, "(int) %d", *(option[i].var.i));
break;
case OPT_CHR:
if ((buf=(char *)malloc(30)) == NULL)
break;
sprintf(buf, "(char) `%c'", *(option[i].var.i));
break;
case OPT_STR:
if ((buf=(char *)malloc(strlen(*(option[i].var.s))+10))
== NULL)
break;
sprintf(buf, "(str) ``%s''", *(option[i].var.s));
break;
case OPT_BOOL:
if ((buf=(char *)malloc(30)) == NULL)
break;
sprintf(buf, "(bool) %s",
(*(option[i].var.i) ? "on" : "off"));
break;
case OPT_ENUM:
if ((buf=(char *)malloc(strlen(option[i].values[*(option[i].var.i)])+10))
== NULL)
break;
sprintf(buf, "(enum) %s",
option[i].values[*(option[i].var.i)]);
break;
default:
buf = NULL;
}
if (buf == NULL)
break;
disp_status(DISP_STATUS, "%s (%s) [%s]: %s",
option[i].name, option[i].shrt,
buf, option[i].help);
}
free(s);
break;
case 'O':
if ((f=disp_open(opt_pager, 1)) == NULL)
return;
for (i=0; option[i].name; i++) {
if (i > 0)
fputc('\n', f);
fprintf(f, "%s %-15.15s",
option[i].shrt, option[i].name);
switch(option[i].type) {
case OPT_INT:
fprintf(f, "(int) %d\n", *(option[i].var.i));
break;
case OPT_CHR:
fprintf(f, "(char) `%c'\n", *(option[i].var.i));
break;
case OPT_STR:
fprintf(f, "(str) ``%s''\n", *(option[i].var.s));
break;
case OPT_BOOL:
fprintf(f, "(bool) %s\n",
(*(option[i].var.i) ? "on" : "off"));
break;
case OPT_ENUM:
fprintf(f, "(enum) %s\n",
option[i].values[*(option[i].var.i)]);
break;
}
fprintf(f, " %s\n", option[i].help);
}
disp_close(f, 1);
disp_status(DISP_STATUS, "");
default:
disp_status(DISP_STATUS, "");
}
}
void fn_lcd(char **args)
{
char *lwd, *exp;
int freep;
if (args) {
lwd = args[0];
freep = 0;
}
else {
if (rc_inrc) {
rc_error("lcd: no directory specified");
return;
}
lwd = read_string("local directory: ", 1);
freep = 1;
}
exp = local_exp(lwd);
if (exp) {
if (chdir(exp) < 0 && rc_inrc)
rc_error("rc: cannot cd to %s: %s",
lwd, strerror(errno));
free(exp);
}
if (freep)
free(lwd);
if (!rc_inrc) {
lwd = getcwd(NULL, 1024);
disp_status(DISP_STATUS, "Current local directory: %s", lwd);
free(lwd);
}
}
void fn_shell(char **args)
{
char *cmd;
if (args)
cmd = args[0];
else
cmd = read_string("! ", 1);
escape_disp(0);
if (cmd[0] != '\0') {
system(cmd);
printf("[Press return] ");
fflush(stdout);
disp_prompt_char();
}
else
system("$SHELL -i");
disp_status(DISP_STATUS, "");
reenter_disp();
}
void fn_colon(char **args)
{
char *cmd, *p, *line = NULL;
int i;
if (args) {
cmd = args[0];
args++;
}
else {
line = p = read_string(": ", 1);
if (line == NULL || line[0] == '\0') {
free(line);
disp_status(DISP_STATUS, "");
return;
}
if ((cmd=rc_token(&p)) == NULL) {
disp_status(DISP_STATUS, "no function");
return;
}
}
if ((i=find_function(cmd)) < 0) {
disp_status(DISP_STATUS, "unknown function: %s", cmd);
if (line)
free(line);
return;
}
if (line) {
args = rc_list(p);
}
disp_status(DISP_STATUS, "");
if (functions[i].fn)
functions[i].fn(args);
if (line) {
free(line);
if (args) {
for (i=0; args[i]; i++)
free(args[i]);
free(args);
}
}
}
void fn_deidle(char **args)
{
ftp_deidle();
}
void fn_site(char **args)
{
char *line;
if (args == NULL) {
line = read_string("site ", 1);
if (line == NULL || line[0] == '\0') {
free(line);
disp_status(DISP_STATUS, "");
return;
}
}
else
line = args_to_string(args);
ftp_site(line);
free(line);
}
void fn_reconnect(char **args)
{
ftp_reconnect();
}
void fn_response(char **args)
{
struct ftp_hist *h;
FILE *f;
if (ftp_history == NULL) {
disp_status(DISP_STATUS, "no exchange available");
return;
}
if ((f=disp_open(opt_pager, 1)) == NULL)
return;
for (h=ftp_history; h; h=h->next)
fprintf(f, "%s\n", h->line);
disp_close(f, 1);
}
void
fn_prefix(char **args)
{
if (args == NULL) {
/* emacs C-u */
return;
}
else if (args[0][1] == '\0') {
if (isdigit(args[0][0]))
add_prefix(args[0][0] - '0');
else if (args[0][0] == '-')
negate_prefix();
}
else {
int p = atoi(args[0]);
if (p || args[0][0] == '0')
set_prefix(p);
}
}
void fn_set(char **args)
{
char *opt, *value;
char *line = NULL, *p;
char prompt[128];
int ival, i;
if (args) {
opt = args[0];
if (args[1])
value = args[1];
else {
if (rc_inrc) {
rc_error("no option value given");
return;
}
sprintf(prompt, "set %s to: ", opt);
p = line = read_string(prompt, 1);
value = rc_token(&p);
}
}
else {
if (rc_inrc) {
rc_error("no option value given");
return;
}
p = line = read_string("set ", 1);
opt = rc_token(&p);
if (opt == NULL) {
disp_status(DISP_STATUS, "");
return;
}
value = rc_token(&p);
}
if (opt == NULL || opt[0] == '\0') {
disp_status(DISP_STATUS, "no option.");
return;
}
for (i=0; option[i].name; i++)
if (strcasecmp(option[i].name, opt) == 0
|| strcasecmp(option[i].shrt, opt) == 0)
break;
if (option[i].name == NULL) {
if (rc_inrc)
rc_error("unknown option: %s", opt);
else
disp_status(DISP_STATUS, "unknown option: %s", opt);
return;
}
switch (option[i].type) {
case OPT_INT:
if (value) {
ival = atoi(value);
if (option[i].func)
option[i].func(ival, option[i].var.i);
else
*(option[i].var.i) = ival;
}
if (!rc_inrc)
disp_status(DISP_STATUS, "%s set to %d", option[i].name,
*(option[i].var.i));
break;
case OPT_CHR:
if (value) {
ival = value[0];
if (option[i].func)
option[i].func(ival, option[i].var.i);
else
*(option[i].var.i) = ival;
}
if (!rc_inrc)
disp_status(DISP_STATUS, "%s set to `%c'", option[i].name,
*(option[i].var.i));
break;
case OPT_STR:
if (value) {
if (option[i].func)
option[i].func(strdup(value), option[i].var.s);
else
*(option[i].var.s) = strdup(value);
}
if (!rc_inrc)
disp_status(DISP_STATUS, "%s set to `%s'", option[i].name,
*(option[i].var.s));
break;
case OPT_BOOL:
if (value) {
if (value[0] == 't')
ival = !*(option[i].var.i);
else if (value[0] == '0' || value[0] == 'n'
|| strcasecmp(value, "off") == 0)
ival = 0;
else
ival = 1;
if (option[i].func)
option[i].func(ival, option[i].var.i);
else
*(option[i].var.i) = ival;
}
if (!rc_inrc)
disp_status(DISP_STATUS, "%s set to %s", option[i].name,
(*(option[i].var.i) ? "on" : "off"));
break;
case OPT_ENUM:
if (value) {
for (ival=0; option[i].values[ival]; ival++) {
if (strcasecmp(value, option[i].values[ival]) == 0)
break;
}
if (option[i].values[ival] == NULL && !rc_inrc) {
disp_status(DISP_STATUS, "unknown value %s for option %s",
value, option[i].name);
break;
}
if (option[i].func)
option[i].func(ival, option[i].var.i);
else
*(option[i].var.i) = ival;
}
if (!rc_inrc)
disp_status(DISP_STATUS, "%s set to %s", option[i].name,
option[i].values[(*(option[i].var.i))]);
break;
}
if (line)
free(line);
return;
}
enum state leave_tag;
void
fn_state(char **args)
{
char *state, *line;
enum state st;
int freestatep;
freestatep = 0;
line = NULL;
if (args) {
if (args[0][0] != '<') {
if ((state=(char *)malloc(strlen(args[0])+3)) == NULL)
return;
sprintf(state, "<%s>", args[0]);
freestatep = 1;
}
else
state = args[0];
}
else {
line = read_string("State: ", 1);
if (line == NULL || line[0] == '\0')
return;
if (line[0] != '<') {
if ((state=(char *)malloc(strlen(line)+3)) == NULL)
return;
sprintf(state, "<%s>", line);
freestatep = 1;
}
else
state = line;
}
st = parse_state(state);
if (st == binding_state)
return;
enter_state(st);
if (freestatep)
free(state);
free(line);
}
void
fn_leave_tag(char **args)
{
if (binding_state != bs_tag) {
disp_status(DISP_STATUS, "not in <tag> mode");
return;
}
enter_state(leave_tag);
}
void
fn_mkdir(char **args)
{
char *name;
if (args == NULL) {
name = read_string("Directory: ", 1);
if (name == NULL || name[0] == '\0') {
disp_status(DISP_STATUS, "");
free(name);
return;
}
}
else
name = args[0];
ftp_mkdir(name);
if (args == NULL)
free(name);
return;
}
void
fn_rmdir(char **args)
{
char *name;
if (args == NULL) {
name = read_string("Directory: ", 1);
if (name == NULL || name[0] == '\0') {
disp_status(DISP_STATUS, "");
free(name);
return;
}
}
else
name = args[0];
ftp_rmdir(name);
if (args == NULL)
free(name);
return;
}