/* * This is sample code generated by rpcgen. * These are only templates and you can use them * as a guideline for developing your own functions. */ #include #include #include #include #include #include #include #include #include "nfs.h" #include "ftp.h" #include "dirinfo.h" #include "fhandle.h" #include "mount.h" #include "rpcutil.h" #include "cache.h" #include "fileCache.h" #define MODE_DIR 0x4000 #define MODE_LNK 0x2000 // places the fattr values for the pathname file int getfattr(FtpFh ftpfh, fattr *result, int uid, int gid) { DIRINFO * dirinfo = NULL; char * fname; int index; if (!ftpfh) return 0; printf("\t\tgetfattr: %s\n", ftpfh->fullpath); fname = ftpfh->fullpath; if (strchr(fname, '/')) fname = strrchr(fname, '/')+1; if (ftpfh->root) { dirinfo = CacheDirList2(ftpfh->root); if (!dirinfo) return 0; // return zero if not found } if (dirinfo) { index = DirInfo_Find(dirinfo, fname); if (index == -1) return 0; result->mode = DirInfo_GetMode(dirinfo, index); result->type = (result->mode&MODE_DIR)?NFDIR:((result->mode&MODE_LNK)?NFLNK:NFREG); result->size = DirInfo_GetSize(dirinfo, index); result->mtime.seconds = DirInfo_GetMSeconds(dirinfo, index); } else { result->mode = 0x41ff; result->type = NFDIR; result->size = 0; result->mtime.seconds = time(NULL); } result->uid = uid; //DirInfo_GetUid(dirinfo, index); result->gid = gid; //DirInfo_GetGid(dirinfo, index); result->nlink = 1; result->blocksize = 512; // a guess result->rdev = 0; result->blocks = result->size/512; // another guess result->fsid = rand(); result->fileid = rand(); result->atime.seconds = 0; result->atime.useconds = 0; // don't know the micro seconds result->mtime.useconds = 0; result->ctime.seconds = 0; result->ctime.useconds = 0; return 1; } // NFS Null Proc void * nfsproc_null_2(argp, rqstp) void *argp; struct svc_req *rqstp; { static char * result = NULL; printf("null\n"); return((void *) &result); } // NFS Getattr Proc. Gets the file attributes for a file. attrstat * nfsproc_getattr_2(argp, rqstp) char *argp; struct svc_req *rqstp; { static attrstat result; FH fh = GETFH(argp); FtpFh ftpfh = GetFtpFh(fh); //get the pathname struct authunix_parms *unixstuff = (struct authunix_parms *) rqstp->rq_cred.oa_base; printf("getattr "); printf("\tfh: %d\n", fh); if (ftpfh) printf("\tPath name: %s\n", ftpfh->fullpath); // Go ahead and get the fattr if (getfattr(ftpfh, &(result.attrstat_u.attributes), GETUID(rqstp), GETGID(rqstp))) { printf("\tSuccess\n"); result.status = NFS_OK; } else { printf("\tFailure\n"); result.status = NFSERR_NOENT; } printf("-----------------------\n"); return (&result); } // NFS Lookup Proc. Gets the fhandle from the name diropres * nfsproc_lookup_2(argp, rqstp) diropargs *argp; struct svc_req *rqstp; { static diropres result; FH fh = GETFH (argp->dir); FtpFh ftpfh = GetFtpFh(fh); printf("lookup "); printf("\tfh: %d\n", fh); if (!ftpfh) { // Check for valid fh result.status = NFSERR_STALE; return &result; } printf("\tdirpath: %s\n", ftpfh->fullpath); printf("\tfname: %s\n", argp->name); // Check for dot if (!strcmp(argp->name, ".")) { printf("\tReturning dot.\n"); result.status = NFS_OK; // Get the fattr of the directory if (!getfattr(ftpfh,&(result.diropres_u.diropok.attributes), GETUID(rqstp), GETGID(rqstp))) result.status = NFSERR_NOENT; // Return the file handle of the directory COPYFH (result.diropres_u.diropok.file, argp->dir); } // Check for dot dot else if (!strcmp(argp->name, "..")) { printf("\tReturning dot dot.\n"); // Check for root if (!strcmp("/",ftpfh->fullpath)) result.status=NFSERR_NOENT; else { result.status = NFS_OK; getfattr(ftpfh->root, &(result.diropres_u.diropok.attributes), GETUID(rqstp), GETGID(rqstp)); // get the file handle of .. dir SETFH (result.diropres_u.diropok.file, ftpfh->root->fh); } } // Otherwise create the file handle. else { if (CacheValidPath(ftpfh, argp->name) >= 0) { FtpFh newFtpFh; printf("\tSucess\n"); result.status = NFS_OK; // Create file handle newFtpFh = CreateFtpFh(argp->name, ftpfh); // Get the attributes if (!getfattr(newFtpFh,&(result.diropres_u.diropok.attributes), GETUID(rqstp), GETGID(rqstp))) result.status=NFSERR_NOENT; // Set return file handle. SETFH(result.diropres_u.diropok.file, newFtpFh->fh); } else { printf("\tFailure\n"); result.status = NFSERR_NOENT; } } printf("--------------\n"); return (&result); } //NFS ReadDir Proc. Get the contents of the directory readdirres * nfsproc_readdir_2(argp, rqstp) readdirargs *argp; struct svc_req *rqstp; { static readdirres result; static entry *list = NULL; static char test[] = "test"; int i=0, j=0; DIRINFO *dirlist; FH fh = GETFH(argp->dir); FtpFh ftpfh = GetFtpFh(fh); printf("readdir "); if (ftpfh) printf("\tfullpath: %s\n", ftpfh->fullpath); result.status = NFSERR_NOENT; dirlist = CacheDirList2(ftpfh); if (!dirlist) return (&result); if (list) free(list); list = malloc (DirInfo_GetNum(dirlist) * sizeof (entry)); result.status = NFS_OK; result.readdirres_u.readdirok.entries = list; result.readdirres_u.readdirok.eof = TRUE; // Add in the files for (i=0; i < DirInfo_GetNum(dirlist); i++) { if (i!=0) list[i-1].nextentry = list+i; // set previous pointer list[i].fileid = rand(); // make up the file ids list[i].name = DirInfo_GetName(dirlist, i); // put the names //printf("file: %s\n", list[i].name); list[i].nextentry = NULL; // set the next pointer to null sprintf(list[i].cookie,"%d", rand()%10); } printf("------------------\n"); return (&result); } //NFS Read Proc Read a portion of the file. readres * nfsproc_read_2(argp, rqstp) readargs *argp; struct svc_req *rqstp; { static readres result; FILE *fp; char *fname; FH fh = GETFH(argp->file); FtpFh ftpfh = GetFtpFh(fh); SOCKET socket; printf("read\n"); result.status = NFSERR_IO; if (!ftpfh) { printf("Failure: Null ftpfh\n"); return &result; } printf("Looking up file %s...\n", ftpfh->fullpath); socket = ConnList_GetSocket(ftpfh->connlist, ftpfh->connindex); // Get the file file from the Cache if ( (fname = CheckCache(ftpfh)) == NULL ) { fname = CacheFile(ftpfh); GetFile(socket, ftpfh->fullpath, fname); } //printf("Local File: %s\n", fname); fp = fopen(fname, "rb"); // Open up the file. if (fp != NULL) { //printf("Opened Local File...\n"); result.status = NFS_OK; fseek(fp, argp->offset, SEEK_SET); // seek to the right spot. // Allocate a new block and read in data. result.readres_u.readres_vals.data.nfsdata_val = malloc(argp->count); result.readres_u.readres_vals.data.nfsdata_len = fread(result.readres_u.readres_vals.data.nfsdata_val, 1, argp->count, fp); fclose(fp); // get the file attributes. getfattr(ftpfh, &(result.readres_u.readres_vals.attributes), GETUID(rqstp), GETGID(rqstp)); printf("Success"); } else { result.status = NFSERR_IO; printf("Failure: Null fp"); } printf("Done Read."); printf("-----------------\n"); return (&result); } // NFS Write Proc. Write a portion of the file. attrstat * nfsproc_write_2(argp, rqstp) writeargs *argp; struct svc_req *rqstp; { static attrstat result; char *fname; FILE *fp; FH fh = GETFH(argp->file); FtpFh ftpfh = GetFtpFh(fh); SOCKET socket; printf("write\n"); result.status = NFSERR_IO; if (!ftpfh) { printf("Failure: Null ftpfh\n"); return &result; } printf("Looking up file %s...\n", ftpfh->fullpath); socket = ConnList_GetSocket(ftpfh->connlist, ftpfh->connindex); // Get the file from the cache if ( (fname = CheckCache(ftpfh)) == NULL ) { fname = CacheFile(ftpfh); GetFile(socket, ftpfh->fullpath, fname); } printf("Local File: %s\n", fname); fp = fopen(fname, "rb+"); if (fp != NULL) { printf("Success"); InvalidateCache(); result.status = NFS_OK; printf("Write Offset: %d\n", argp->offset); printf("Write Length: %d\n", argp->data.nfsdata_len); fseek(fp, argp->offset, SEEK_SET); //seek to the right spot fwrite(argp->data.nfsdata_val, 1, //write in the data argp->data.nfsdata_len, fp); fclose(fp); // Put the file back on the FTP server PutFile(socket, ftpfh->fullpath, fname); getfattr(ftpfh, &(result.attrstat_u.attributes), GETUID(rqstp), GETGID(rqstp)); printf("Success"); } else result.status = NFSERR_STALE; printf("Done Write\n"); printf("-----------------\n"); return (&result); } // NFS Create Proc. Create an empty file. diropres * nfsproc_create_2(argp, rqstp) createargs *argp; struct svc_req *rqstp; { static diropres result; char fullname[1024]; FH fh = GETFH(argp->where.dir); FtpFh ftpfh = GetFtpFh(fh); FtpFh newFtpFh; SOCKET socket; int ret; printf("create\n"); result.status = NFSERR_IO; if (!ftpfh) { result.status = NFSERR_STALE; return (&result); } // Build the file path if (ftpfh->fullpath[0]) sprintf(fullname,"%s/%s", ftpfh->fullpath, argp->where.name); else strcpy(fullname, argp->where.name); socket = ConnList_GetSocket(ftpfh->connlist, ftpfh->connindex); // Put a blank file on the FTP Server ret = PutFile (socket, fullname, "c:\\blank.tmp"); if (!ret) { socket = ConnList_Connect(ftpfh->connlist, ftpfh->connindex); if (socket == INVALID_SOCKET || !(ret = PutFile (socket, fullname, "c:\\blank.tmp"))) return (&result); } if (ret == FTP_ERROR) { result.status = NFSERR_PERM; return (&result); } InvalidateCache(); printf("\tSucess\n"); result.status = NFS_OK; // Create file handle newFtpFh = CreateFtpFh(argp->where.name, ftpfh); // Get the attributes if (!getfattr(newFtpFh,&(result.diropres_u.diropok.attributes), GETUID(rqstp), GETGID(rqstp))) result.status = NFSERR_PERM; // Set return file handle. SETFH(result.diropres_u.diropok.file, newFtpFh->fh); printf("--------------\n"); return (&result); } // NFS Remove Proc. Remove a file. stat_enum * nfsproc_remove_2(argp, rqstp) diropargs *argp; struct svc_req *rqstp; { static stat_enum result; FH fh = GETFH(argp->dir); FtpFh ftpfh = GetFtpFh(fh); SOCKET socket; char fullname[1024]; int ret; result = NFSERR_IO; printf("remove: %s\n", argp->name); if (!ftpfh) { result = NFSERR_STALE; return (&result); } socket = ConnList_GetSocket(ftpfh->connlist, ftpfh->connindex); if (ftpfh->fullpath[0]) sprintf(fullname,"%s/%s", ftpfh->fullpath, argp->name); else strcpy(fullname, argp->name); // FTP do delete. ret = DoDELE (socket, fullname); if (!ret) { socket = ConnList_Connect(ftpfh->connlist, ftpfh->connindex); if (socket == INVALID_SOCKET || !(ret = DoDELE (socket, fullname))) return (&result); } if (ret == FTP_ERROR) { result = NFSERR_PERM; return (&result); } result = NFS_OK; InvalidateFileCache(); InvalidateCache(); printf("----------\n"); return (&result); } // NFS Rename Proc. Rename a file. stat_enum * nfsproc_rename_2(argp, rqstp) renameargs *argp; struct svc_req *rqstp; { static stat_enum result; FtpFh fromftpfh = GetFtpFh(GETFH(argp->from.dir)); FtpFh toftpfh = GetFtpFh(GETFH(argp->to.dir)); char frompath[2048]; char topath[2048]; SOCKET socket; int ret; result = NFSERR_IO; if (!fromftpfh || !toftpfh) { result = NFSERR_STALE; return (&result); } printf("rename\n"); // Build the file paths if (fromftpfh->fullpath[0]) sprintf(frompath, "%s/%s", fromftpfh->fullpath, argp->from.name); else sprintf(frompath, "%s%s", fromftpfh->fullpath, argp->from.name); if (toftpfh->fullpath[0]) sprintf(topath, "%s/%s", toftpfh->fullpath, argp->to.name); else sprintf(topath, "%s%s", toftpfh->fullpath, argp->to.name); socket = ConnList_GetSocket(fromftpfh->connlist, fromftpfh->connindex), // Do the ftp file rename ret = DoRename(socket, topath, frompath); if (!ret) { socket = ConnList_Connect(fromftpfh->connlist, fromftpfh->connindex); if (socket == INVALID_SOCKET || !(ret = DoRename(socket, topath, frompath))) return (&result); } if (ret == FTP_ERROR) { result = NFSERR_PERM; return (&result); } result = NFS_OK; fromftpfh->valid = 0; InvalidateFileCache(); InvalidateCache(); return (&result); } // NFS MakeDir Proc. Make a directory. diropres * nfsproc_mkdir_2(argp, rqstp) createargs *argp; struct svc_req *rqstp; { static diropres result; char fullname[2048]; FH fh = GETFH(argp->where.dir); FtpFh ftpfh = GetFtpFh(fh); FtpFh newFtpFh; SOCKET socket; int ret; printf("mkdir\n"); result.status = NFSERR_IO; if (!ftpfh) { result.status = NFSERR_STALE; return (&result); } if (ftpfh->fullpath[0]) sprintf(fullname,"%s/%s", ftpfh->fullpath, argp->where.name); else strcpy(fullname, argp->where.name); socket = ConnList_GetSocket(ftpfh->connlist, ftpfh->connindex), // Do the Makedir FTP command ret = DoMKD (socket, fullname); if (!ret) { socket = ConnList_Connect(ftpfh->connlist, ftpfh->connindex); if (socket == INVALID_SOCKET || !(ret = DoMKD (socket, fullname))) return (&result); } if (ret == FTP_ERROR) { result.status = NFSERR_PERM; return (&result); } InvalidateCache(); printf("\tSucess\n"); result.status = NFS_OK; // Create file handle newFtpFh = CreateFtpFh(argp->where.name, ftpfh); // Get the attributes if (!getfattr(newFtpFh,&(result.diropres_u.diropok.attributes), GETUID(rqstp), GETGID(rqstp))) result.status = NFSERR_PERM; // Set return file handle. SETFH(result.diropres_u.diropok.file, newFtpFh->fh); printf("--------------\n"); return (&result); } // NFS Remove Directory Proc. Removes a directory stat_enum * nfsproc_rmdir_2(argp, rqstp) diropargs *argp; struct svc_req *rqstp; { static stat_enum result; FH fh = GETFH(argp->dir); FtpFh ftpfh = GetFtpFh(fh); char fullname[2048]; int ret; SOCKET socket; result = NFSERR_IO; printf("rmdir: %s\n", argp->name); if (ftpfh->fullpath[0]) sprintf(fullname,"%s/%s", ftpfh->fullpath, argp->name); else strcpy(fullname, argp->name); socket = ConnList_GetSocket(ftpfh->connlist, ftpfh->connindex), // Do the ftp command for remove directory ret = DoRMD (socket, fullname); if (!ret) { socket = ConnList_Connect(ftpfh->connlist, ftpfh->connindex); if (socket == INVALID_SOCKET || !(ret = DoRMD (socket, fullname))) return (&result); } if (ret == FTP_ERROR) { result = NFSERR_PERM; return (&result); } result = NFS_OK; InvalidateCache(); printf("----------\n"); return (&result); } // NFS Stat Filesystem. Get the file system values statfsres * nfsproc_statfs_2(argp, rqstp) char *argp; struct svc_req *rqstp; { static statfsres result; printf("statfs\n"); result.status = NFS_OK; result.statfsres_u.info.tsize = 8192; // Set by MAXDATA // These are made up. result.statfsres_u.info.bsize = 512; result.statfsres_u.info.blocks = 10000; result.statfsres_u.info.bfree = 1000; result.statfsres_u.info.bavail = 100; return (&result); } /***********************************************/ // These function always fail.... void * nfsproc_writecache_2(argp, rqstp) void *argp; struct svc_req *rqstp; { static char * result; printf("writecache\n"); return((void *) &result); } attrstat * nfsproc_setattr_2(argp, rqstp) sattrargs *argp; struct svc_req *rqstp; { static attrstat result; printf("setattr\n"); result.status = NFS_OK; // Let chmod fail silently. return (&result); } void * nfsproc_root_2(argp, rqstp) void *argp; struct svc_req *rqstp; { static char * result; printf("root\n"); return((void *) &result); } readlinkres * nfsproc_readlink_2(argp, rqstp) char *argp; struct svc_req *rqstp; { static readlinkres result; FH fh = GETFH(argp); FtpFh ftpfh = GetFtpFh(fh); DIRINFO * dirinfo; int index; char *fname; fname = ftpfh->fullpath; if (strchr(fname, '/')) fname = strrchr(fname, '/') + 1; printf("readlink\n"); result.status = NFSERR_IO; if (ftpfh->root) { dirinfo = CacheDirList2(ftpfh); if (!dirinfo) return (&result); index = DirInfo_Find(dirinfo, fname); if (index != -1) { result.status = NFS_OK; result.readlinkres_u.data = DirInfo_GetLink(dirinfo, index); } } return (&result); } stat_enum * nfsproc_link_2(argp, rqstp) linkargs *argp; struct svc_req *rqstp; { static stat_enum result; printf("link\n"); result = NFSERR_IO; return (&result); } stat_enum * nfsproc_symlink_2(argp, rqstp) symlinkargs *argp; struct svc_req *rqstp; { static stat_enum result; printf("symlink\n"); result = NFSERR_IO; return (&result); }