?? ntcp.c
字號:
/* * ntcp.c * * Copyright (C) 1995 Martin von L鰓is * Copyright (C) 1997 R間is Duchesne */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <errno.h>#ifdef HAVE_FCNTL_H#include <fcntl.h>#endif#ifdef HAVE_GETOPT_H#include <getopt.h>#else#define getopt_long(a,v,o,ol,x) getopt(a,v,o)#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_IO_H#include <io.h>#endif#include <string.h>#include <stdlib.h>#include <limits.h>#include "ntfstypes.h"#include "struct.h"#include "util.h"#include "nttools.h"#include "inode.h"char *short_opts="Vh";#ifdef HAVE_GETOPT_Hstruct option options[]={ {"version",0,0,'V'}, {"help",0,0,'h'}, {0,0,0,0}};#endifunsigned int type=ngt_nt;unsigned int charset=nct_utf8;void usage(void){ fprintf(stderr,"ntcp [-V|h] <src> <dst>\n" "Files on the NTFS volume are accessed as //<device>/<path>\n");}struct ntfs_file{ ntfs_inode ino; ntfs_attribute *data; ntfs_offset_t offset;};voidwrite_unix(void *file,void *buf,size_t len){ if(write(*(int*)file,buf,len)!=len){ perror("cp2unix"); exit(1); }}intread_unix(void *file,void *buf,size_t len){ int result; result=read(*(int*)file,buf,len); if(result==-1){ perror("read_unix"); exit(1); } return result;}intclose_unix(void *file){ close(*(int*)file); return errno;}voidwrite_nt(void *file,void* buf,size_t len){ struct ntfs_file* f=file; struct ntfs_io io; int error; io.fn_get=ntfs_get; io.param=buf; io.size=len; io.do_read=0; error=ntfs_readwrite_attr(&f->ino,f->data,f->offset,&io); if(error){ fprintf(stderr,"Error %d writing to ntfs\n",error); exit(1); } f->offset+=len;}intread_nt(void *file,void *buf,size_t len){ struct ntfs_file* f=file; struct ntfs_io io; int error; io.fn_put=ntfs_put; io.param=buf; io.size=len; io.do_read=1; error=ntfs_readwrite_attr(&f->ino,f->data,f->offset,&io); if(error){ fprintf(stderr,"Error %d reading from ntfs\n",error); exit(1); } f->offset+=io.size; return io.size;}int close_nt(void *file){ return ntfs_update_inode(file);}typedef struct _methods{ void (*write_func)(void*,void*,size_t); int (*read_func)(void*,void*,size_t); int (*close_func)(void*);} *methods;struct _methods m_unix ={ write_unix, read_unix, close_unix};struct _methods m_nt ={ write_nt, read_nt, close_nt};void copy(methods r,void *rf,methods w,void *wf){ void *buf=malloc(8192); int len; int error; do{ len=r->read_func(rf,buf,8192); w->write_func(wf,buf,len); }while(len==8192); /* FIXME: close read file. */ error = w->close_func(wf); if(error) fprintf(stderr,"When closing:%s\n", strerror(error));}intntfs_creat (ntfs_inode *dir, ntfs_inode *ino, char* name){ int error; error=ntfs_alloc_file(dir,ino,name,strlen(name)); if(error) return error; error=ntfs_update_inode(ino); if(error) return error; error=ntfs_update_inode(dir); return error;}int ntfs_open(char *name,methods m,void **f,int flags){ ntfs_volume *vol; char device[256]; char *it; int inum; struct ntfs_file *file; int error; for(it=name+2;*it && *it!='/';it++) /*nothing*/; strcpy(device,"/dev/"); strncpy(device+5,name+2,(it-name)-2); device[(it-name)+3]='\0'; vol=ntfs_open_volume(device,0,1,0); if(!vol)return ENODEV; vol->ngt=type; vol->nct=charset; file=malloc(sizeof(struct ntfs_file)); inum=5; /* walk the directory tree */ name=it; if(*name=='/')name++; do{ char *next; if(ntfs_init_inode(&file->ino,vol,inum)){ fprintf(stderr,"error finding %s\n",it); return EIO; } if(!name || !*name)break; next=strpbrk(name,NTFS_PATH_SEP); if(next){ *next='\0'; next++; } inum=ntfs_find_file(&file->ino,name); if(inum==-1){ ntfs_inode new_ino; if(next) return ENOENT; error = ntfs_creat(&file->ino, &new_ino, name); if(error) return error; file->ino = new_ino; break; } name=next; }while(1); file->data=ntfs_find_attr(&file->ino,vol->at_data,0); if(!file->data) return EISDIR; *m = m_nt; *f = file; return 0;}intunix_open(char *name,methods m,void **f,int flags){ int *file=malloc(sizeof(int)); *file=open(name,flags,0777); if(*file==-1)return errno; *m = m_unix; *f=file; return 0;}intdo_open(char *name,methods m,void **f,int flags){ int error; if(name[0]=='/' && name[1]=='/') error=ntfs_open(name,m,f,flags); else error=unix_open(name,m,f,flags); if(error == EISDIR && (flags & O_CREAT)) return error; if(error){ fprintf(stderr,"%s:%s\n",name,strerror(error)); exit(1); } return 0;}voidjoin(char* dir, char* file){ char *next; for(next = strpbrk(dir,NTFS_PATH_SEP);next; next = strpbrk(next,NTFS_PATH_SEP)) dir=next=next+1; if(*dir != '\0') { dir += strlen(dir); *dir = '/'; dir++; } for(next = strpbrk(file, NTFS_PATH_SEP); next; next = strpbrk(next, NTFS_PATH_SEP)) file = next = next+1; strcpy(dir,file);}int main(int argc,char *argv[]){ int c; extern int opterr,optind; extern char* optarg; struct _methods m1,m2; void *f1,*f2; opterr=1; while((c=getopt_long(argc,argv,short_opts,options,NULL))>0) switch(c) { case 'V': printf("ntcat " NTFS_VERSION "\n");exit(0);break; case 'h': usage();exit(0);break; } if(optind+2!=argc){ usage(); exit(1); } do_open(argv[optind], &m1, &f1, O_RDONLY); if(do_open(argv[optind+1], &m2, &f2, O_WRONLY|O_CREAT) == EISDIR) { char newname[NAME_MAX]; strcpy(newname, argv[optind+1]); join(newname,argv[optind]); if(do_open(newname, &m2, &f2, O_WRONLY|O_CREAT) == EISDIR) { fprintf(stderr,"%s:%s\n",newname,strerror(EISDIR)); exit(1); } } copy(&m1,f1,&m2,f2); return 0;}/* * Local variables: * c-file-style: "linux" * End: */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -