Commit 92654638 authored by Pontus Sköld's avatar Pontus Sköld Committed by Niels Möller
Browse files

Checked in Pontus Sköld's lsftp client.

* src/sftp/Makefile.am (lsftp_SOURCES):
* src/sftp/commands.c: New file.
* src/sftp/commands.h: New file.
* src/sftp/dc.c: New file.
* src/sftp/dc.h: New file.
* src/sftp/lsftp.c: New file.
* src/sftp/lsftp.h: New file.
* src/sftp/misc_fun.c: New file.
* src/sftp/misc_fun.h: New file.
* src/sftp/rl.c: New file.
* src/sftp/rl.h: New file.
* src/sftp/sftp_bind.c: New file.
* src/sftp/sftp_bind.h: New file.
* src/sftp/sftp_c.c: New file.
* src/sftp/sftp_c.h: New file.
* src/sftp/str_utils.c: New file.
* src/sftp/str_utils.h: New file.

Rev: src/sftp/commands.c:1.1
Rev: src/sftp/commands.h:1.1
Rev: src/sftp/dc.c:1.1
Rev: src/sftp/dc.h:1.1
Rev: src/sftp/lsftp.c:1.1
Rev: src/sftp/lsftp.h:1.1
Rev: src/sftp/misc_fun.c:1.1
Rev: src/sftp/misc_fun.h:1.1
Rev: src/sftp/rl.c:1.1
Rev: src/sftp/rl.h:1.1
Rev: src/sftp/sftp_bind.c:1.1
Rev: src/sftp/sftp_bind.h:1.1
Rev: src/sftp/sftp_c.c:1.1
Rev: src/sftp/sftp_c.h:1.1
Rev: src/sftp/str_utils.c:1.1
Rev: src/sftp/str_utils.h:1.1
parent 9e95d96c
This diff is collapsed.
/*
* @(#) $Id$
*
* commands.h
*/
/* lsftp, an implementation of the sftp protocol
*
* Copyright (C) 2001, Pontus Sköld
* Portions of this code originately from the readline manual
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef LSFTP_COMMANDS_H
#define LSFTP_COMMANDS_H
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <glob.h>
#include <limits.h>
#include <ctype.h>
#include <errno.h>
#include <grp.h>
#include <pwd.h>
#include "sftp_bind.h"
#include "dc.h"
#include "str_utils.h"
#include "misc_fun.h"
#define NOCOMMAND -4710
#define UNKNOWNCOMMAND -4711
#define WORDLENMAX 256
extern int mainloop; /* Flag to end mainloop */
extern int sloppy_complete;
extern int buggy_server_treshold;
/* Public functions */
int handle_command(char* s);
/* Internal below */
int com_help( char* arg, char* command );
int com_about( char* arg, char* command );
int com_escape( char* arg, char* command);
int com_quit( char* arg, char* command );
int com_jobs( char* arg, char* command );
int com_close( char* arg, char* command );
int com_open( char* arg, char* command );
int com_cd( char* arg, char* command );
int com_rm( char* arg, char* command );
int com_ls( char* arg, char* command );
int com_pwd( char* arg, char* command );
int com_mv( char* arg, char* command );
int com_ln( char* arg, char* command );
int com_mkdir( char* arg, char* command );
int com_set( char* arg, char* command );
int com_mail( char* arg, char* command );
int com_umask( char* arg, char* command );
int com_get( char* arg, char* command );
int com_put( char* arg, char* command );
int com_lcd( char* arg, char* command );
int com_lrm( char* arg, char* command );
int com_lls( char* arg, char* command );
int com_lpwd( char* arg, char* command );
int com_lmv( char* arg, char* command );
int com_chown( char* arg, char* command );
int com_chgrp( char* arg, char* command );
enum takes_as_arg
{
COMMAND,
LOCALFILE,
REMOTEFILE,
NOARG,
JOBID,
OTHERARG
};
typedef struct
{
char *name; /* User printable name of the function. */
int (*func)(); /* Function to call to do the job. */
char *doc; /* Documentation for this function. */
char* longdoc; /* Longer help to display for help command */
enum takes_as_arg arg_type;
int visible;
int uniquelen;
} command;
command commands[35];
#endif
/*
* @(#) $Id$
*
* dc.c - dircache functions
*/
/* lsftp, an implementation of the sftp protocol
*
* Copyright (C) 2001, Pontus Skld
* Portions of this code originately from the readline manual
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "dc.h"
static int dc_entries = 1024;
static struct lsftp_dc_s* lsftp_dircache = 0;
int lsftp_dc_init( int new_dc_entries )
{
int i;
/* We flush the cache when resulting */
if( lsftp_dircache )
lsftp_dc_uninit();
dc_entries = new_dc_entries;
lsftp_dircache = malloc( sizeof( struct lsftp_dc_s ) * dc_entries );
for( i = 0; i < dc_entries; i++ )
{
lsftp_dircache[i].name = 0;
lsftp_dircache[i].hash = 0;
lsftp_dircache[i].posixperms = 0;
}
return 1;
}
void lsftp_dc_uninit()
{
int i;
if( !lsftp_dircache )
return;
for( i = 0; i < dc_entries; i++ )
free( lsftp_dircache[i].name );
free( lsftp_dircache );
lsftp_dircache = 0;
dc_entries = 0;
return;
}
int lsftp_dc_index( char* name )
{
int h;
int i;
if( !lsftp_dircache )
return -1;
h = lsftp_dc_hash( name );
for( i = 0; i < dc_entries; i++ )
if( lsftp_dircache[i].hash == h && /* Hash is correct? */
!strcmp( lsftp_dircache[i].name, name )
)
return i;
return -1; /* No match */
}
int lsftp_dc_free_index()
{
int i;
if( !lsftp_dircache )
return -1;
for( i = 0; i < dc_entries; i++ )
if( lsftp_dircache[i].hash == 0 &&
lsftp_dircache[i].name == 0
)
return i;
return -1; /* No match */
}
int lsftp_dc_make_index()
{
static int nextexpire = 0; /* FIXME: How choose which to expire? */
int i = nextexpire++;
if( !lsftp_dircache )
return -1;
if( nextexpire == dc_entries ) /* Filled? */
nextexpire = 0;
free( lsftp_dircache[i].name );
lsftp_dircache[i].name = 0;
lsftp_dircache[i].hash = 0;
lsftp_dircache[i].posixperms = 0;
return i;
}
int lsftp_dc_notice( char* name, struct sftp_attrib* a )
{
char* s;
int i;
if( !lsftp_dircache )
return -1;
s = strdup( name );
if( !s ) /* Malloc failed? */
return -1;
i = lsftp_dc_free_index();
if( -1 == i ) /* All slots taken? */
i = lsftp_dc_make_index();
lsftp_dircache[i].name = s;
lsftp_dircache[i].hash = lsftp_dc_hash( s );
lsftp_dircache[i].posixperms = sftp_attrib_perms( a );
return 0;
}
int lsftp_dc_remove( char* name )
{
int i;
if( !lsftp_dircache )
return -1;
i = lsftp_dc_index( name );
if( -1 == i ) /* Not found? */
return 0;
free( lsftp_dircache[i].name );
lsftp_dircache[i].name = 0;
lsftp_dircache[i].hash = 0;
lsftp_dircache[i].posixperms = 0;
return 1;
}
int lsftp_dc_hash( char* name )
{
/* FIXME: Calculate */
return 5;
}
int lsftp_dc_l_isdir( char* name )
{
/*
* Check whatever a local name is a directory
*
* Return 1 if it is, 0 if it isn't, -1 if we couldn't find out
*
*/
struct stat st;
int failed;
failed = stat( name, &st );
if( failed )
return -1; /* stat failed */
return S_ISDIR( st.st_mode );
}
int lsftp_dc_r_isdir( char* name )
{
/*
* Check whatever a remote name is a directory
*
* Return 1 if it is, 0 if it isn't, -1 if we couldn't find out
*
*/
int i;
int id;
struct stat st;
/* printf( "Checking directory status of %s: ", name ); */
if( lsftp_dircache )
{
i = lsftp_dc_index( name );
if( -1 != i && /* Found it? */
-1 != lsftp_dircache[i].posixperms && /* Has permissions? */
!(lsftp_dircache[i].posixperms & S_IFLNK)
)
/* { */
/* printf( "%d (from cache), posixperms are %d\n", S_ISDIR( lsftp_dircache[i].posixperms ), */
/* lsftp_dircache[i].posixperms ); */
return S_ISDIR( lsftp_dircache[i].posixperms );
/* } */
}
/* Not found in cache (or link), we need to stat */
id = lsftp_do_stat( name, &st );
if( id > 0) /* Not a failure? */
{
lsftp_await_command( id );
if( -1 != st.st_mode ) /* We've got permissions? */
/* { */
/* printf( "%d\n", S_ISDIR( st.st_mode ) ); */
return S_ISDIR( st.st_mode );
/* } */
}
/* printf( "%d (failed) \n", -1 ); */
return -1; /* Failed, report it */
}
int lsftp_dc_glob_matches( char* fname, char* glob, int period )
{
/*
* Return 0 if filename doesn't match glob, 1 if it matches.
*
*/
#ifdef HAVE_FNMATCH
if( !glob || !fname )
return 0;
if( !period )
return !fnmatch( glob, fname, FNM_PATHNAME | FNM_PERIOD);
else
return !fnmatch( glob, fname, FNM_PATHNAME );
#else
/* We have our own fnmatch function if needed */
int i = 0;
int j = 0;
int match = 1;
int lastslash = -1;
if( !glob || !fname )
return 0;
/* printf( "Trying to match fname %s with glob %s (period %d), return ", */
/* fname, */
/* glob, */
/* period */
/* ); */
while( fname[i] && glob[j] )
{
switch( glob[j] )
{
case '*':
if( !period &&
'.' == fname[i] &&
i == ( lastslash + 1)
) /* Don't match first . */
match = 0;
if( !glob[j+1] ) /* End of pattern? Break */
{
printf( "%d\n", match );
return match;
}
else
{
/* More */
}
break;
case '?':
i++;
j++;
break;
case '[':
{
char f = fname[i++];
int inverted = 0;
int openmatch = 0;
char startrange;
char endrange;
j++; /* Compensate for the beginning [ */
if( /* Starts with ! or ^, when invert */
'!' == glob[j] &&
'^' == glob[j]
)
{
inverted++;
j++;
}
else if( ']' == glob[j] ) /* First char means */
{
if( ']' == f)
openmatch++;
j++;
}
while( glob[j] &&
']' != glob[j]
)
{
char g = glob[j++];
if( !inverted )
{
if( g == f ) /* Match? */
openmatch++;
if( '-' == glob[j] && glob[j+1] ) /* Range? */
{
startrange = g;
endrange = glob[j+1];
if( f >= startrange && /* FIXME: How to check with local charsets ? */
f <= endrange
)
openmatch++;
j += 2; /* Move forward */
}
}
else
{
/* Inverted goes here */
if( '-' == glob[j] && glob[j+1] ) /* Range? */
{
startrange = g;
endrange = glob[j+1];
if( f < startrange || /* FIXME: How to check with local charsets ? */
f > endrange
)
openmatch++;
j += 2; /* Move forward */
}
else
if( g != f )
openmatch++;
}
}
if( !glob[j++] ) /* End of glob without terminated [ - error (skip closing ] too) */
match = 0;
if( !openmatch ) /* Matching failed */
match = 0;
}
break;
default: /* This is the case for normal charaters */
if( '/' ==fname[i] ) /* Remember position of rightmost slash */
lastslash = i;
if( glob[j] != fname[i] )
match = 0;
i++;
j++;
}
}
if( fname[i] || fname[j] ) /* One finished but not the other */
match = 0;
printf( "%d\n", match );
return match;
#endif /* HAVE_FNMATCH */
}
char** lsftp_dc_r_sloppy_glob( char* glob, int nocheck )
{
char** retval;
char** mem;
int count = 0;
int i;
/* We'll have at most dc_entries matches */
if( !lsftp_dircache )
return 0;
mem = malloc( sizeof( char* ) * ( dc_entries + 1 ) );
if( !mem ) /* malloc failed? Bail out */
{
perror( "malloc failed" );
return 0;
}
for( i = 0; i < dc_entries; i++ )
{
if( lsftp_dircache[i].name )
if(
lsftp_dc_glob_matches(
lsftp_dircache[i].name,
glob,
0
)
)
mem[count++] = strdup( lsftp_dircache[i].name );
}
mem[count++] = 0;
retval = realloc( mem, count * sizeof( char* ) );
if( !retval ) /* realloc failed? mem is unchanged, return it */
return mem;
return retval;
}
char* lsftp_dc_path_no_glob( char* glob )
{