⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fsplib.c

📁 一个linux下的ftp程序。它是使用文件传输协议的一系列程序的集合。
💻 C
📖 第 1 页 / 共 2 页
字号:
       /* set entry namelen field */       if (namelen > 255)           entry->namlen = 255;       else           entry->namlen = namelen;       /* set record length */	          entry->reclen = 10+namelen;       /* pad to 4 byte boundary */       while( dir->dirpos & 0x3 )       {         dir->dirpos++;         entry->reclen++;       }       /* and return it */       *result=entry;       return 0;      }}struct dirent * fsp_readdir(FSP_DIR *dirp){    static struct dirent entry;    struct dirent *result;            if (dirp == NULL) return NULL;    if ( fsp_readdir_r(dirp,&entry,&result) )        return NULL;    else        return result;}long fsp_telldir(FSP_DIR *dirp){    return dirp->dirpos;}void fsp_seekdir(FSP_DIR *dirp, long loc){    dirp->dirpos=loc;}void fsp_rewinddir(FSP_DIR *dirp){    dirp->dirpos=0;}int fsp_closedir(FSP_DIR *dirp){    if (dirp == NULL)         return -1;    if(dirp->dirname) free(dirp->dirname);    free(dirp->data);    free(dirp);    return 0;}/*  ***************** File input/output functions *********  */FSP_FILE * fsp_fopen(FSP_SESSION *session, const char *path,const char *modeflags){    FSP_FILE   *f;    if(session == NULL || path == NULL || modeflags == NULL)    {	errno = EINVAL;	return NULL;    }    f=calloc(1,sizeof(FSP_FILE));    if (f == NULL)    {	return NULL;    }    /* check and parse flags */    switch (*modeflags++)    {	case 'r':		  break;        case 'w':		  f->writing=1;		  break;        case 'a':	          /* not supported */		  free(f);		  errno = ENOTSUP;		  return NULL;        default:		  free(f);		  errno = EINVAL;		  return NULL;    }    if (*modeflags == '+' || ( *modeflags=='b' && modeflags[1]=='+'))    {	free(f);	errno = ENOTSUP;	return NULL;    }    /* build request packet */    if(f->writing)    {	f->out.cmd=FSP_CC_UP_LOAD;    }    else    {        if(buildfilename(session,&f->out,path))	{	    free(f);            return NULL;	}        f->bufpos=FSP_SPACE;	f->out.cmd=FSP_CC_GET_FILE;    }    f->out.xlen=0;    /* setup control variables */    f->s=session;    f->name=strdup(path);    if(f->name == NULL)    {	free(f);	errno = ENOMEM;	return NULL;    }    return f;}size_t fsp_fread(void *dest,size_t size,size_t count,FSP_FILE *file){    size_t total,done,havebytes;    char *ptr;    total=count*size;    done=0;    ptr=dest;        if(file->eof) return 0;    while(1)    {	/* need more data? */	if(file->bufpos>=FSP_SPACE)	{	    /* fill the buffer */	    file->out.pos=file->pos;	    if(fsp_transaction(file->s,&file->out,&file->in))	    {	         file->err=1;		 return done/size;	    }	    if(file->in.cmd != FSP_CC_GET_FILE)	    {		errno = EIO;		file->err=1;		return done/size;	    }	    file->bufpos=FSP_SPACE-file->in.len;	    if(file->bufpos > 0)	    {	       memmove(file->in.buf+file->bufpos,file->in.buf,file->in.len);	    }	    file->pos+=file->in.len;	}	havebytes=FSP_SPACE - file->bufpos;	if (havebytes == 0 )	{	    /* end of file! */	    file->eof=1;	    errno = 0;	    return done/size;	}	/* copy ready data to output buffer */	if(havebytes <= total )	{	    /* copy all we have */	    memcpy(ptr,file->in.buf+file->bufpos,havebytes);	    ptr+=havebytes;	    file->bufpos=FSP_SPACE;	    done+=havebytes;	    total-=havebytes;	} else	{	    /* copy bytes left */	    memcpy(ptr,file->in.buf+file->bufpos,total);	    file->bufpos+=total;	    errno = 0;	    return count;	}    }}size_t fsp_fwrite(const void * source, size_t size, size_t count, FSP_FILE * file){    size_t total,done,freebytes;    const char *ptr;    if(file->eof || file->err)	return 0;    file->out.len=FSP_SPACE;    total=count*size;    done=0;    ptr=source;    while(1)    {	/* need to write some data? */	if(file->bufpos>=FSP_SPACE)	{	    /* fill the buffer */	    file->out.pos=file->pos;	    if(fsp_transaction(file->s,&file->out,&file->in))	    {	         file->err=1;		 return done/size;	    }	    if(file->in.cmd != FSP_CC_UP_LOAD)	    {		errno = EIO;		file->err=1;		return done/size;	    }	    file->bufpos=0;	    file->pos+=file->out.len;	    done+=file->out.len;	}	freebytes=FSP_SPACE - file->bufpos;	/* copy input data to output buffer */	if(freebytes <= total )	{	    /* copy all we have */	    memcpy(file->out.buf+file->bufpos,ptr,freebytes);	    ptr+=freebytes;	    file->bufpos=FSP_SPACE;	    total-=freebytes;	} else	{	    /* copy bytes left */	    memcpy(file->out.buf+file->bufpos,ptr,total);	    file->bufpos+=total;	    errno = 0;	    return count;	}    }}int fsp_fpurge(FSP_FILE *file){    if(file->writing)    {	file->bufpos=0;    }    else    {	file->bufpos=FSP_SPACE;    }    errno = 0;    return 0;}int fsp_fflush(FSP_FILE *file){    if(file == NULL)    {	errno = ENOTSUP;	return -1;    }    if(!file->writing)    {	errno = EBADF;	return -1;    }    if(file->eof || file->bufpos==0)    {	errno = 0;	return 0;    }    file->out.pos=file->pos;    file->out.len=file->bufpos;    if(fsp_transaction(file->s,&file->out,&file->in))    {	 file->err=1;	 return -1;    }    if(file->in.cmd != FSP_CC_UP_LOAD)    {	errno = EIO;	file->err=1;	return -1;    }    file->bufpos=0;    file->pos+=file->out.len;        errno = 0;    return 0;}int fsp_fclose(FSP_FILE *file){    int rc;    rc=0;    errno = 0;    if(file->writing)    {        if(fsp_fflush(file))	{  	    rc=-1;	}	else if(fsp_install(file->s,file->name,0))	{	    rc=-1;	}    }    free(file->name);    free(file);    return rc;}int fsp_fseek(FSP_FILE *stream, long offset, int whence){    long newoffset;    switch(whence)    {	case SEEK_SET:	              newoffset = offset;		      break;        case SEEK_CUR:		      newoffset = stream->pos + offset;		      break;        case SEEK_END:	              errno = ENOTSUP;		      return -1;	default:		      errno = EINVAL;		      return -1;    }    if(stream->writing)    {	if(fsp_fflush(stream))	{	    return -1;	}    }    stream->pos=newoffset;    stream->eof=0;    fsp_fpurge(stream);    return 0;}long fsp_ftell(FSP_FILE *f){    return f->pos + f->bufpos;}void fsp_rewind(FSP_FILE *f){    if(f->writing)	fsp_fflush(f);    f->pos=0;    f->err=0;    f->eof=0;    fsp_fpurge(f);}/*  **************** Utility functions ****************** *//* return 0 if user has enough privs for uploading the file */int fsp_canupload(FSP_SESSION *s,const char *fname){  char *dir;  unsigned char dirpro;  int rc;  struct stat sb;  dir=directoryfromfilename(fname);  if(dir == NULL)  {      errno = ENOMEM;      return -1;  }    rc=fsp_getpro(s,dir,&dirpro);  free(dir);  if(rc)  {      return -1;  }    if(dirpro & FSP_DIR_OWNER)       return 0;    if( ! (dirpro & FSP_DIR_ADD))      return -1;        if (dirpro & FSP_DIR_DEL)     return 0;       /* we need to check file existence, because we can not overwrite files */    rc = fsp_stat(s,fname,&sb);    if (rc == 0)      return -1;  else      return 0;}/* install file opened for writing */int fsp_install(FSP_SESSION *s,const char *fname,time_t timestamp){    int rc;    FSP_PKT in,out;    /* and install a new file */    out.cmd=FSP_CC_INSTALL;    out.xlen=0;    out.pos=0;    rc=0;    if( buildfilename(s,&out,fname) )	rc=-1;    else	{	    if (timestamp != 0)	    {		/* add timestamp extra data */		*(uint32_t *)(out.buf+out.len)=htonl(timestamp);		out.xlen=4;		out.pos=4;	    }	    if(fsp_transaction(s,&out,&in))	    {		rc=-1;	    } else	    {		if(in.cmd != FSP_CC_INSTALL)		{		    rc=-1;		    errno = EPERM;		}	    }	}    return rc;}/* Get protection byte from the directory */int fsp_getpro(FSP_SESSION *s,const char *directory,unsigned char *result){   FSP_PKT in,out;      if(buildfilename(s,&out,directory))       return -1;   out.cmd=FSP_CC_GET_PRO;   out.xlen=0;   out.pos=0;   if(fsp_transaction(s,&out,&in))       return -1;   if(in.cmd != FSP_CC_GET_PRO || in.pos != FSP_PRO_BYTES)   {       errno = ENOMSG;       return -1;   }   if(result)      *result=in.buf[in.len];   errno = 0;   return  0;}int fsp_stat(FSP_SESSION *s,const char *path,struct stat *sb){   FSP_PKT in,out;   unsigned char ftype;      if(buildfilename(s,&out,path))       return -1;   out.cmd=FSP_CC_STAT;   out.xlen=0;   out.pos=0;   if(fsp_transaction(s,&out,&in))       return -1;   if(in.cmd != FSP_CC_STAT)   {       errno = ENOTSUP;       return -1;   }   /* parse results */   ftype=in.buf[8];   if(ftype == 0)   {       errno = ENOENT;       return -1;   }   sb->st_uid=sb->st_gid=0;   sb->st_mtime=sb->st_ctime=sb->st_atime=ntohl( *(const uint32_t *)( in.buf ));   sb->st_size=ntohl( *(const uint32_t *)(in.buf + 4 ));   sb->st_blocks=(sb->st_size+511)/512;   if (ftype==FSP_RDTYPE_DIR)   {       sb->st_mode=S_IFDIR | 0755;       sb->st_nlink=2;   }   else   {       sb->st_mode=S_IFREG | 0644;       sb->st_nlink=1;   }   errno = 0;   return  0;}int fsp_mkdir(FSP_SESSION *s,const char *directory){   return simplecommand(s,directory,FSP_CC_MAKE_DIR);}int fsp_rmdir(FSP_SESSION *s,const char *directory){   return simplecommand(s,directory,FSP_CC_DEL_DIR);}int fsp_unlink(FSP_SESSION *s,const char *directory){   return simplecommand(s,directory,FSP_CC_DEL_FILE);}int fsp_rename(FSP_SESSION *s,const char *from, const char *to){   FSP_PKT in,out;   int l;      if(buildfilename(s,&out,from))       return -1;   /* append target name */   l=strlen(to)+1;   if( l + out.len > FSP_SPACE )   {       errno = ENAMETOOLONG;       return -1;   }   memcpy(out.buf+out.len,to,l);   out.xlen = l;   if(s->password)   {       l=strlen(s->password)+1;       if(out.len + out.xlen + l > FSP_SPACE)       {	   errno = ENAMETOOLONG;	   return -1;       }       out.buf[out.len+out.xlen-1] = '\n';       memcpy(out.buf+out.len+out.xlen,s->password,l);       out.xlen += l;   }   out.cmd=FSP_CC_RENAME;   out.pos=out.xlen;       if(fsp_transaction(s,&out,&in))       return -1;   if(in.cmd != FSP_CC_RENAME)   {       errno = EPERM;       return -1;   }   errno = 0;    return 0;}int fsp_access(FSP_SESSION *s,const char *path, int mode){    struct stat sb;    int rc;    unsigned char dirpro;    char *dir;    rc=fsp_stat(s,path,&sb);    if(rc == -1)    {	/* not found */	/* errno is set by fsp_stat */	return -1;    }    /* just test file existence */    if(mode == F_OK)    {	errno = 0;	return  0;    }    /* deny execute access to file */    if (mode & X_OK)    {	if(S_ISREG(sb.st_mode))	{	    errno = EACCES;	    return -1;	}    }        /* Need to get ACL of directory */    if(S_ISDIR(sb.st_mode))	dir=NULL;    else	dir=directoryfromfilename(path);	        rc=fsp_getpro(s,dir==NULL?path:dir,&dirpro);    /* get pro failure */    if(rc)    {	if(dir) free(dir);	errno = EACCES;	return -1;    }    /* owner shortcut */    if(dirpro & FSP_DIR_OWNER)    {	if(dir) free(dir);	errno = 0;	return 0;    }    /* check read access */    if(mode & R_OK)    {	if(dir)	{	    if(! (dirpro & FSP_DIR_GET))	    {		free(dir);		errno = EACCES;		return -1;	    }	} else	{	    if(! (dirpro & FSP_DIR_LIST))	    {		errno = EACCES;		return -1;	    }	}    }    /* check write access */    if(mode & W_OK)    {	if(dir)	{	    if( !(dirpro & FSP_DIR_DEL) || !(dirpro & FSP_DIR_ADD))	    {		free(dir);		errno = EACCES;		return -1;	    }	} else	{	    /* when checking directory for write access we are cheating	       by allowing ADD or DEL right */	    if( !(dirpro & FSP_DIR_DEL) && !(dirpro & FSP_DIR_ADD))	    {		errno = EACCES;		return -1;	    }	}    }    if(dir) free(dir);    errno = 0;    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -