summaryrefslogtreecommitdiffstats
path: root/sftp_server/protocol.c
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2005-12-12 12:21:09 +0000
committerAris Adamantiadis <aris@0xbadc0de.be>2005-12-12 12:21:09 +0000
commitc5287c543e28048f5cac844a5f03debb2df60271 (patch)
treeb0ced0d6883442eeeb630bb914e9dbd60dbab41c /sftp_server/protocol.c
parent4fd1df0586ed08911467141e605afa0c0c610e6a (diff)
downloadlibssh-c5287c543e28048f5cac844a5f03debb2df60271.tar.gz
libssh-c5287c543e28048f5cac844a5f03debb2df60271.tar.xz
libssh-c5287c543e28048f5cac844a5f03debb2df60271.zip
removed mercurius from trunk
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@66 7dcaeef0-15fb-0310-b436-a5af3365683c
Diffstat (limited to 'sftp_server/protocol.c')
-rw-r--r--sftp_server/protocol.c416
1 files changed, 0 insertions, 416 deletions
diff --git a/sftp_server/protocol.c b/sftp_server/protocol.c
deleted file mode 100644
index 8ab16d93..00000000
--- a/sftp_server/protocol.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/* protocol dependant part of Mercurius */
-/*
-Copyright 2005 Aris Adamantiadis
-
-This file is part of the SSH Library
-
-The SSH Library is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or (at your
-option) any later version.
-
-The SSH Library 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 Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with the SSH Library; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-MA 02111-1307, USA. */
-
-#include <libssh/libssh.h>
-#include <libssh/sftp.h>
-#include <libssh/server.h>
-#include <dirent.h>
-#include <errno.h>
-
-#include <string.h>
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <time.h>
-#include "server.h"
-
-#define TYPE_DIR 1
-#define TYPE_FILE 1
-struct sftp_handle {
- int type;
- int offset;
- char *name;
- int eof;
- DIR *dir;
- FILE *file;
-};
-
-int reply_status(SFTP_CLIENT_MESSAGE *msg){
- switch(errno){
- case EACCES:
- return sftp_reply_status(msg,SSH_FX_PERMISSION_DENIED,
- "permission denied");
- case ENOENT:
- return sftp_reply_status(msg,SSH_FX_NO_SUCH_FILE,
- "no such file or directory");
- case ENOTDIR:
- return sftp_reply_status(msg,SSH_FX_FAILURE,
- "not a directory");
- default:
- return sftp_reply_status(msg,SSH_FX_FAILURE,NULL);
- }
-}
-
-void handle_opendir(SFTP_CLIENT_MESSAGE *msg){
- DIR *dir=opendir(msg->filename);
- struct sftp_handle *hdl;
- STRING *handle;
- if(!dir){
- reply_status(msg);
- return;
- }
- hdl=malloc(sizeof(struct sftp_handle));
- memset(hdl,0,sizeof(struct sftp_handle));
- hdl->type=TYPE_DIR;
- hdl->offset=0;
- hdl->dir=dir;
- hdl->name=strdup(msg->filename);
- handle=sftp_handle_alloc(msg->sftp,hdl);
- sftp_reply_handle(msg,handle);
- free(handle);
-}
-
-SFTP_ATTRIBUTES *attr_from_stat(struct stat *statbuf){
- SFTP_ATTRIBUTES *attr=malloc(sizeof(SFTP_ATTRIBUTES));
- memset(attr,0,sizeof(*attr));
- attr->size=statbuf->st_size;
- attr->uid=statbuf->st_uid;
- attr->gid=statbuf->st_gid;
- attr->permissions=statbuf->st_mode;
- attr->atime=statbuf->st_atime;
- attr->mtime=statbuf->st_mtime;
- attr->flags=SSH_FILEXFER_ATTR_SIZE | SSH_FILEXFER_ATTR_UIDGID
- | SSH_FILEXFER_ATTR_PERMISSIONS | SSH_FILEXFER_ATTR_ACMODTIME;
- return attr;
-}
-
-int handle_stat(SFTP_CLIENT_MESSAGE *msg,int follow){
- struct stat statbuf;
- SFTP_ATTRIBUTES *attr;
- int ret;
- if(follow)
- ret=stat(msg->filename,&statbuf);
- else
- ret=lstat(msg->filename,&statbuf);
- if(ret<0){
- reply_status(msg);
- return 0;
- }
- attr=attr_from_stat(&statbuf);
- sftp_reply_attr(msg, attr);
- sftp_attributes_free(attr);
- return 0;
-}
-
-char *long_name(char *file, struct stat *statbuf){
- static char buf[256];
- char buf2[100];
- int mode=statbuf->st_mode;
- char *time,*ptr;
- strcpy(buf,"");
- switch(mode & S_IFMT){
- case S_IFDIR:
- strcat(buf,"d");
- break;
- default:
- strcat(buf,"-");
- break;
- }
- /* user */
- if(mode & 0400)
- strcat(buf,"r");
- else
- strcat(buf,"-");
- if(mode & 0200)
- strcat(buf,"w");
- else
- strcat(buf,"-");
- if(mode & 0100){
- if(mode & S_ISUID)
- strcat(buf,"s");
- else
- strcat(buf,"x");
- } else
- strcat(buf,"-");
- /*group*/
- if(mode & 040)
- strcat(buf,"r");
- else
- strcat(buf,"-");
- if(mode & 020)
- strcat(buf,"w");
- else
- strcat(buf,"-");
- if(mode & 010)
- strcat(buf,"x");
- else
- strcat(buf,"-");
- /* other */
- if(mode & 04)
- strcat(buf,"r");
- else
- strcat(buf,"-");
- if(mode & 02)
- strcat(buf,"w");
- else
- strcat(buf,"-");
- if(mode & 01)
- strcat(buf,"x");
- else
- strcat(buf,"-");
- strcat(buf," ");
- snprintf(buf2,sizeof(buf2),"%3d %d %d %d",(int)statbuf->st_nlink,
- (int)statbuf->st_uid,(int)statbuf->st_gid,(int)statbuf->st_size);
- strcat(buf,buf2);
- time=ctime(&statbuf->st_mtime)+4;
- if((ptr=strchr(time,'\n')))
- *ptr=0;
- snprintf(buf2,sizeof(buf2)," %s %s",time,file);
- // +4 to remove the "WED "
- strcat(buf,buf2);
- return buf;
-}
-
-int handle_readdir(SFTP_CLIENT_MESSAGE *msg){
- struct sftp_handle *handle=sftp_handle(msg->sftp,msg->handle);
- SFTP_ATTRIBUTES *attr;
- struct dirent *dir;
- char *longname;
- struct stat statbuf;
- char file[1024];
- int i;
- if(!handle || handle->type!=TYPE_DIR){
- sftp_reply_status(msg,SSH_FX_BAD_MESSAGE,"invalid handle");
- return 0;
- }
- for(i=0; !handle->eof && i<50;++i){
- dir=readdir(handle->dir);
- if(!dir){
- handle->eof=1;
- break;
- }
- snprintf(file,sizeof(file),"%s/%s",handle->name,
- dir->d_name);
- if(lstat(file,&statbuf)){
- memset(&statbuf,0,sizeof(statbuf));
- }
- attr=attr_from_stat(&statbuf);
- longname=long_name(dir->d_name,&statbuf);
- sftp_reply_names_add(msg,dir->d_name,longname,attr);
- sftp_attributes_free(attr);
- }
- /* if there was at least one file, don't send the eof yet */
- if(i==0 && handle->eof){
- sftp_reply_status(msg,SSH_FX_EOF,NULL);
- return 0;
- }
- sftp_reply_names(msg);
- return 0;
-}
-
-int handle_read(SFTP_CLIENT_MESSAGE *msg){
- struct sftp_handle *handle=sftp_handle(msg->sftp,msg->handle);
- u32 len=msg->len;
- void *data;
- int r;
- if(!handle || handle->type!=TYPE_FILE){
- sftp_reply_status(msg,SSH_FX_BAD_MESSAGE,"invalid handle");
- return 0;
- }
- if(len>(2<<15)){
- /* 32000 */
- len=2<<15;
- }
- data=malloc(len);
- fseeko(handle->file,msg->offset,SEEK_SET);
- r=fread(data,1,len,handle->file);
- ssh_say(2,"read %d bytes\n",r);
- if(r<=0 && (len>0)){
- if(feof(handle->file)){
- sftp_reply_status(msg,SSH_FX_EOF,"End of file");
- } else {
- reply_status(msg);
- }
- return 0;
- }
- sftp_reply_data(msg,data,r);
- free(data);
- return 0;
-}
-
-int handle_write(SFTP_CLIENT_MESSAGE *msg){
- struct sftp_handle *handle=sftp_handle(msg->sftp,msg->handle);
- u32 len=string_len(msg->data);
- int r;
- if(!handle || handle->type!=TYPE_FILE){
- sftp_reply_status(msg,SSH_FX_BAD_MESSAGE,"invalid handle");
- return 0;
- }
- fseeko(handle->file,msg->offset,SEEK_SET);
- do {
- r=fwrite(string_data(msg->data),1,len,handle->file);
- ssh_say(2,"wrote %d bytes\n",r);
- if(r<=0 && (msg->data>0)){
- reply_status(msg);
- return 0;
- }
- len-=r;
- } while (len>0);
- sftp_reply_status(msg,SSH_FX_OK,"");
- return 0;
-}
-
-int handle_close(SFTP_CLIENT_MESSAGE *msg){
- struct sftp_handle *handle=sftp_handle(msg->sftp,msg->handle);
- if(!handle){
- sftp_reply_status(msg,SSH_FX_BAD_MESSAGE,"invalid handle");
- return 0;
- }
- sftp_handle_remove(msg->sftp,handle);
- if(handle->type==TYPE_DIR){
- closedir(handle->dir);
- } else {
- fclose(handle->file);
- }
- if(handle->name)
- free(handle->name);
- free(handle);
- sftp_reply_status(msg,SSH_FX_OK,NULL);
- return 0;
-}
-
-int handle_open(SFTP_CLIENT_MESSAGE *msg){
- int flags=0;
- int fd;
- FILE *file;
- char *mode="r";
- struct sftp_handle *hdl;
- STRING *handle;
- if(msg->flags & SSH_FXF_READ)
- flags |= O_RDONLY;
- if(msg->flags & SSH_FXF_WRITE)
- flags |= O_WRONLY;
- if(msg->flags & SSH_FXF_APPEND)
- flags |= O_APPEND;
- if(msg->flags & SSH_FXF_TRUNC)
- flags |= O_TRUNC;
- if(msg->flags & SSH_FXF_EXCL)
- flags |= O_EXCL;
- if(msg->flags & SSH_FXF_CREAT)
- flags |= O_CREAT;
- fd=open(msg->filename,flags,msg->attr->permissions);
- if(fd<0){
- reply_status(msg);
- return 0;
- }
- switch(flags& (O_RDONLY | O_WRONLY | O_APPEND | O_TRUNC)){
- case O_RDONLY:
- mode="r";
- break;
- case (O_WRONLY|O_RDONLY):
- mode="r+";
- break;
- case (O_WRONLY|O_TRUNC):
- mode="w";
- break;
- case (O_WRONLY | O_RDONLY | O_APPEND):
- mode="a+";
- break;
- default:
- switch(flags & (O_RDONLY | O_WRONLY)){
- case O_RDONLY:
- mode="r";
- break;
- case O_WRONLY:
- mode="w";
- break;
- }
- }
- file=fdopen(fd,mode);
- hdl=malloc(sizeof(struct sftp_handle));
- memset(hdl,0,sizeof(struct sftp_handle));
- hdl->type=TYPE_FILE;
- hdl->offset=0;
- hdl->file=file;
- hdl->name=strdup(msg->filename);
- handle=sftp_handle_alloc(msg->sftp,hdl);
- sftp_reply_handle(msg,handle);
- free(handle);
- return 0;
-}
-
-int sftploop(SSH_SESSION *session, SFTP_SESSION *sftp){
- SFTP_CLIENT_MESSAGE *msg;
- char buffer[PATH_MAX];
- do {
- msg=sftp_get_client_message(sftp);
- if(!msg)
- break;
- switch(msg->type){
- case SFTP_REALPATH:
- ssh_say(1,"client realpath : %s\n",msg->filename);
- realpath(msg->filename,buffer);
- ssh_say(2,"responding %s\n",buffer);
- sftp_reply_name(msg, buffer, NULL);
- break;
- case SFTP_OPENDIR:
- ssh_say(1,"client opendir(%s)\n",msg->filename);
- handle_opendir(msg);
- break;
- case SFTP_LSTAT:
- case SFTP_STAT:
- ssh_say(1,"client stat(%s)\n",msg->filename);
- handle_stat(msg,msg->type==SFTP_STAT);
- break;
- case SFTP_READDIR:
- ssh_say(1,"client readdir\n");
- handle_readdir(msg);
- break;
- case SFTP_CLOSE:
- ssh_say(1,"client close\n");
- handle_close(msg);
- break;
- case SFTP_OPEN:
- ssh_say(1,"client open(%s)\n",msg->filename);
- handle_open(msg);
- break;
- case SFTP_READ:
- ssh_say(1,"client read(off=%lld,len=%d)\n",msg->offset,msg->len);
- handle_read(msg);
- break;
- case SFTP_WRITE:
- ssh_say(1,"client write(off=%lld len=%d)\n)\n",msg->offset,string_len(msg->data));
- handle_write(msg);
- break;
- case SFTP_SETSTAT:
- case SFTP_FSETSTAT:
- case SFTP_REMOVE:
- case SFTP_MKDIR:
- case SFTP_RMDIR:
- case SFTP_FSTAT:
- case SFTP_RENAME:
- case SFTP_READLINK:
- case SFTP_SYMLINK:
- default:
- ssh_say(1,"Unknown message %d\n",msg->type);
- sftp_reply_status(msg,SSH_FX_OP_UNSUPPORTED,"Unsupported message");
- }
- sftp_client_message_free(msg);
- } while (1);
- if(!msg)
- return 1;
- return 0;
-}