int bb_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { int retstat = 0; char *files[100]; files[0] = "."; files[1] = ".."; log_msg("\nbb_readdir(path=\"%s\", buf=0x%08x, filler=0x%08x, offset=%lld, fi=0x%08x)\n", path, buf, filler, offset, fi); int i, count = myreaddir(path, &files[2]) + 2; log_msg("count: %d, files[2]: %s\n", count, files[1]); for (i = 0; i < count; i++) { log_msg("calling filler with name %s\n", files[i]); if (filler(buf, files[i], NULL, 0) != 0) { log_msg(" ERROR bb_readdir filler: buffer full"); return -ENOMEM; } } log_fi(fi); return retstat; }
/** Open directory * * This method should check if the open operation is permitted for * this directory * * Introduced in version 2.3 */ int fusion_opendir(const char *path, struct fuse_file_info *fi) { DIR *dp; int retstat = 0; char fpath[PATH_MAX] = {0}; log_msg("\nfusion_opendir(path=\"%s\", fi=0x%08x)\n", path, fi); fusion_fullpath(fpath, path); /*if path exists in ZHT, create it locally*/ char res[ZHT_MAX_BUFF] = {0}; int stat = zht_lookup(path, res); if (ZHT_LOOKUP_FAIL != stat) { mkdir(fpath, 0775); } else { /*TODO*/ fusion_error("_opendir() failed: <fpath> not found in ZHT"); } dp = opendir(fpath); if (dp == NULL) retstat = fusion_error("fusion_opendir opendir"); fi->fh = (intptr_t) dp; log_fi(fi); return retstat; }
/** Read data from an open file * * Read should return exactly the number of bytes requested except * on EOF or error, otherwise the rest of the data will be * substituted with zeroes. An exception to this is when the * 'direct_io' mount option is specified, in which case the return * value of the read system call will reflect the return value of * this operation. * */ int bb_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int retstat = 0; int count; int count2; log_msg("\nbb_read(path=\"%s\", buf=0x%08x, size=%d, offset=%lld, fi=0x%08x)\n", path, buf, size, offset, fi); // no need to get fpath on this one, since I work from fi->fh not the path log_fi(fi); /* * The pread() function attempts to read the specified amount (size) of * data from the specified file descriptor (fi->fh), into the specified * buffer (buf) starting at a point in the file (offset). Returns the * number of bytes read. */ retstat = pread(fi->fh, buf, size, offset); log_msg("\nFile \"%s\" has been encrypted\n", path); // Encrypts the chars before reading it for (count = 0; count < size; count++) { buf[count] = (buf[count]+1) % 256; } // Decrypts if HasAccess is true if (HasAccess(BB_DATA)) { for (count2 = 0; count2 < size; count2++) { buf[count2] = (buf[count2] == 0) ? 255 : ((buf[count2]-1) % 256); } log_msg("\nAuthorized decryption on file \"%s\"\n", path); } if (retstat < 0) retstat = bb_error("bb_read read"); return retstat; }
// this is a no-op in NPHFS. It just logs the call and returns success int nphfuse_flush(const char *path, struct fuse_file_info *fi){ log_msg("\nnphfuse_flush(path=\"%s\", fi=0x%08x)\n", path, fi); // no need to get fpath on this one, since I work from fi->fh not the path log_fi(fi); return 0; }
/** File open operation * * No creation, or truncation flags (O_CREAT, O_EXCL, O_TRUNC) * will be passed to open(). Open should check if the operation * is permitted for the given flags. Optionally open may also * return an arbitrary filehandle in the fuse_file_info structure, * which will be passed to all file operations. * * path = path to file, relative to rootdir * fi = contains file information for the file to be opened * struct fuse_file_info defined in Rootdir/fuse-2.9.2/include/fuse_common.h */ int bb_open(const char *path, struct fuse_file_info *fi) { int retstat = 0; int fd; char fpath[PATH_MAX]; log_msg("\nbb_open(path\"%s\", fi=0x%08x)\n", path, fi); bb_fullpath(fpath, path); // path is relative to rootdir, must change it // to a full path fd = open(fpath, fi->flags); // uses system open to open or return an error // returns a file despcriptor (> 0) on success if (fd < 0) retstat = bb_error("bb_open open"); fi->fh = fd; // sets the handle field of fi log_fi(fi); return retstat; // This should be 0 - but we would like to return a file // descriptor. Fuse automatically chooses a file descriptor // and returns that one (may be different from open's ret) // fi->fh is different from descriptor returned as retstat // Calls to read, say, include fi, hence fi->fh // But programs think they are talking to retstat // When program does a read, the call is intercepted by // the kernel and redirected to a bb_read where fi->fh // is used as the handle }
/** Read directory * * Uses function called 'filler' to insert directory entries into the * directory structure, which is also passed to the callback as 'buf'. * * This supersedes the old getdir() interface. New applications * should use this. * * The filesystem may choose between two modes of operation: * * 1) The readdir implementation ignores the offset parameter, and * passes zero to the filler function's offset. The filler * function will not return '1' (unless an error happens), so the * whole directory is read in a single readdir operation. This * works just like the old getdir() method. * * 2) The readdir implementation keeps track of the offsets of the * directory entries. It uses the offset parameter and always * passes non-zero offset to the filler function. When the buffer * is full (or an error happens) the filler function will return * '1'. * */ int bb_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { int retstat = 0; DIR *dp; struct dirent *de; log_msg("\nbb_readdir(path=\"%s\", buf=0x%08x, filler=0x%08x, offset=%lld, fi=0x%08x)\n", path, buf, filler, offset, fi); // once again, no need for fullpath -- but note that I need to cast fi->fh dp = (DIR*) (uintptr_t) fi->fh; // Every directory contains at least two entries: . and .. If my // first call to the system readdir() returns NULL I've got an // error; near as I can tell, that's the only condition under // which I can get an error from readdir() de = readdir(dp); if (de == 0) { retstat = bb_error("bb_readdir readdir"); return retstat; } // This will copy the entire directory into the buffer. The loop exits // when either the system readdir() returns NULL, or filler() // returns something non-zero. The first case just means I've // read the whole directory; the second means the buffer is full. do { log_msg("calling filler with name %s\n", de->d_name); if (filler(buf, de->d_name, NULL, 0) != 0) { log_msg(" ERROR bb_readdir filler: buffer full"); return -ENOMEM; } } while ((de = readdir(dp)) != NULL); log_fi(fi); return retstat; }
/** * Create and open a file * * If the file does not exist, first create it with the specified * mode, and then open it. * * If this method is not implemented or under Linux kernel * versions earlier than 2.6.15, the mknod() and open() methods * will be called instead. * * Introduced in version 2.5 */ int fool_create(const char *path, mode_t mode, struct fuse_file_info *fi) { int retstat = 0; char ssdpath[PATH_MAX]; char hddpath[PATH_MAX]; int fd; mode = (mode | 0664) ; log_msg("\nfool_create(path=\"%s\", mode=0%03o, fi=0x%08x)\n", path, mode, fi); fool_fullpath_hdd(hddpath, path); fool_fullpath_ssd(ssdpath, path); log_msg("\nfool_create_log2, path = \"%s\", ssdpath = \"%s\" , hddpath = \"%s\"\n", path, ssdpath, hddpath); // Don't know was doing it :P //--------------------------------------------------- // fd = open(hddpath, fi->flags); fd = creat(hddpath, mode); if (fd < 0) retstat = fool_error("fool_create creat"); fd = open(hddpath, fi->flags); symlink(hddpath, ssdpath); fi->fh = fd; log_fi(fi); return retstat; }
// when exactly is this called? when a user calls fsync and it // happens to be a directory? ??? int bb_fsyncdir(const char *path, int datasync, struct fuse_file_info *fi) { int retstat = 0; log_msg("\nbb_fsyncdir(path=\"%s\", datasync=%d, fi=0x%08x)\n", path, datasync, fi); log_fi(fi); return retstat; }
int bb_flush(const char *path, struct fuse_file_info *fi) { int retstat = 0; log_msg("\nbb_flush(path=\"%s\", fi=0x%08x)\n", path, fi); log_fi(fi); return retstat; }
/** Release directory * * Introduced in version 2.3 */ int bb_releasedir(const char *path, struct fuse_file_info *fi) { int retstat = 0; log_msg("\nbb_releasedir(path=\"%s\", fi=0x%08x)\n", path, fi); log_fi(fi); closedir((DIR*) (uintptr_t) fi->fh); return retstat; }
/** * FUSE document: * * Create and open a file * * If the file does not exist, first create it with the specified * mode, and then open it. * * If this method is not implemented or under Linux kernel * versions earlier than 2.6.15, the mknod() and open() methods * will be called instead. * * Introduced in version 2.5 * * ***************************************************************** * DFZ: * In fusionFS, a file creation always happens in the local node */ int fusion_create(const char *path, mode_t mode, struct fuse_file_info *fi) { int retstat = 0; char fpath[PATH_MAX] = {0}; int fd; log_msg("\nfusion_create(path=\"%s\", mode=0%03o, fi=0x%08x)\n", path, mode, fi); fusion_fullpath(fpath, path); /*if <path> exists in ZHT, we should return at this point*/ char res[ZHT_MAX_BUFF] = {0}; int stat = zht_lookup(path, res); if (ZHT_LOOKUP_FAIL == stat) { log_msg("\n================DFZ ERROR: file already exists. \n"); return -1; } /*create the local file*/ fd = creat(fpath, mode); if (fd < 0) retstat = fusion_error("fusion_create creat"); fi->fh = fd; log_fi(fi); /*add the filename to its parent path in the ZHT entry*/ char dirname[PATH_MAX] = {0}; char *pch = strrchr(path, '/'); strncpy(dirname, path, pch - path + 1); log_msg("\n================DFZ debug: dirname = %s \n", dirname); char oldval[ZHT_MAX_BUFF] = {0}; stat = zht_lookup(dirname, oldval); if (ZHT_LOOKUP_FAIL == stat) { log_msg("\n================DFZ ERROR: no parent path exists. \n"); return -1; } log_msg("\n================DFZ debug: oldval = %s. \n", oldval); zht_append(dirname, pch + 1); // log_msg("cshou debug ==== dirname=%s, filename=%s\n", dirname, pch + 1); /*insert <path, ip_addr> into ZHT */ char addr[PATH_MAX] = {0}; net_getmyip(addr); log_msg("\n================DFZ debug _create(): addr = %s. \n", addr); if (zht_insert(path, addr)) log_msg("\n================ERROR _create(): failed to insert <%s, %s> to ZHT. \n", path, addr); char myaddr[PATH_MAX] = {0}; net_getmyip(myaddr); spade_create(myaddr, fpath, fuse_get_context()->pid); return retstat; }
/** Release directory * * Introduced in version 2.3 */ int atmos_releasedir(const char *path, struct fuse_file_info *fi) { int retstat = 0; log_msg("\natmos_releasedir(path=\"%s\", fi=0x%08x)\n", path, fi); log_fi(fi); return retstat; }
/** Release an open file * * Release is called when there are no more references to an open * file: all file descriptors are closed and all memory mappings * are unmapped. * * For every open() call there will be exactly one release() call * with the same flags and file descriptor. It is possible to * have a file opened more than once, in which case only the last * release will mean, that no more reads/writes will happen on the * file. The return value of release is ignored. * * Changed in version 2.2 */ int bb_release(const char *path, struct fuse_file_info *fi) { log_msg("\nbb_release(path=\"%s\", fi=0x%08x)\n", path, fi); log_fi(fi); // We need to close the file. Had we allocated any resources // (buffers etc) we'd need to free them here as well. return log_syscall("close", close(fi->fh), 0); }
// As with read(), the documentation above is inconsistent with the // documentation for the write() system call. int bb_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int retstat = 0; log_msg("\nbb_write(path=\"%s\", buf=0x%08x, size=%d, offset=%lld, fi=0x%08x)\n", path, buf, size, offset, fi ); // no need to get fpath on this one, since I work from fi->fh not the path log_fi(fi); // openssl code here // char c_enc = 'A'; // char temp[1]; // if(offset!=0){ // log_msg("here samarth\n"); // pread(fi->fh, temp, 1, offset - 1); // c_enc = temp[0]; // log_msg("temp : %d\n", temp[0]); // } // int keylength = 128; // unsigned char aes_key[16] = {'p', 'a', 's', 's', 'w', 'o', 'r', 'd', 'p', 'a', 's', 's', 'w', 'o', 'r', 'd'}; // unsigned char iv_enc[16] = {'p', 'a', 's', 's', 'w', 'o', 'r', 'd', 'p', 'a', 's', 's', 'w', 'o', 'r', 'd'}; // size_t inputslength = strlen(buf); // const size_t encslength = ((inputslength + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; // memset(enc_out, 0, sizeof(enc_out)); // AES_KEY enc_key, dec_key; // AES_set_encrypt_key(aes_key, keylength, &enc_key); // AES_cbc_encrypt((unsigned char*)buf, enc_out, inputslength, &enc_key, iv_enc, AES_ENCRYPT); // code ends here // log_msg("Buf here: %s %d\n", buf, strlen(buf)); // int i; // enc_out[0] = buf[0] ^ c_enc; // log_msg("enc_out[0] : %c\n", enc_out[0]); // log_msg("c_enc : %c\n", c_enc); // log_msg("buf[0] : %c\n", buf[0]); //ADDED: char enc_out[size]; int key_pos = offset % 16; for(int i=0;i<size;++i){ enc_out[i] = (char)(buf[i] ^ key[key_pos]); key_pos = (key_pos+1)%16; } return log_syscall("pwrite", pwrite(fi->fh, enc_out, size, offset), 0); }
/** * Change the size of an open file * * This method is called instead of the truncate() method if the * truncation was invoked from an ftruncate() system call. * * If this method is not implemented or under Linux kernel * versions earlier than 2.6.15, the truncate() method will be * called instead. * * Introduced in version 2.5 */ int bb_ftruncate(const char *path, off_t offset, struct fuse_file_info *fi) { int retstat = 0; log_msg("\nbb_ftruncate(path=\"%s\", offset=%lld, fi=0x%08x)\n", path, offset, fi); log_fi(fi); retstat = ftruncate(fi->fh, offset); if (retstat < 0) retstat = bb_error("bb_ftruncate ftruncate"); return retstat; }
// Since it's currently only called after bb_create(), and bb_create() // opens the file, I ought to be able to just use the fd and ignore // the path... int bb_fgetattr(const char *path, struct stat *statbuf, struct fuse_file_info *fi) { int retstat = 0; log_msg("\nbb_fgetattr(path=\"%s\", statbuf=0x%08x, fi=0x%08x)\n", path, statbuf, fi); log_fi(fi); retstat = fstat(fi->fh, statbuf); if (retstat < 0) retstat = bb_error("bb_fgetattr fstat"); log_stat(statbuf); return retstat; }
// As with read(), the documentation above is inconsistent with the // documentation for the write() system call. int bb_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int retstat = 0; log_msg("\nbb_write(path=\"%s\", buf=0x%08x, size=%d, offset=%lld, fi=0x%08x)\n", path, buf, size, offset, fi); // no need to get fpath on this one, since I work from fi->fh not the path log_fi(fi); retstat = pwrite(fi->fh, buf, size, offset); if (retstat < 0) retstat = bb_error("bb_write pwrite"); return retstat; }
/** Synchronize file contents * * If the datasync parameter is non-zero, then only the user data * should be flushed, not the meta data. * * Changed in version 2.2 */ int bb_fsync(const char *path, int datasync, struct fuse_file_info *fi) { int retstat = 0; log_msg("\nbb_fsync(path=\"%s\", datasync=%d, fi=0x%08x)\n",path,datasync,fi); log_fi(fi); if (datasync) retstat = fdatasync(fi->fh); else retstat = fsync(fi->fh); if (retstat < 0) bb_error("bb_fsync fsync"); return retstat; }
int bb_release(const char *path, struct fuse_file_info *fi) { int retstat = 0; log_msg("\nbb_release(path=\"%s\", fi=0x%08x)\n", path, fi); log_fi(fi); // We need to close the file. Had we allocated any resources // (buffers etc) we'd need to free them here as well. myclose(fi->fh); return retstat; }
/** Synchronize file contents * * If the datasync parameter is non-zero, then only the user data * should be flushed, not the meta data. * * Changed in version 2.2 */ int bb_fsync(const char *path, int datasync, struct fuse_file_info *fi) { log_msg("\nbb_fsync(path=\"%s\", datasync=%d, fi=0x%08x)\n", path, datasync, fi); log_fi(fi); // some unix-like systems (notably freebsd) don't have a datasync call #ifdef HAVE_FDATASYNC if (datasync) return log_syscall("fdatasync", fdatasync(fi->fh), 0); else #endif return log_syscall("fsync", fsync(fi->fh), 0); }
int bb_fgetattr(const char *path, struct stat *statbuf, struct fuse_file_info *fi) { int retstat = 0; log_msg("\nbb_fgetattr(path=\"%s\", statbuf=0x%08x, fi=0x%08x)\n", path, statbuf, fi); log_fi(fi); return bb_getattr(path, statbuf); log_stat(statbuf); return retstat; }
/** * DFZ: for FusionFS, no need to modify _read(). The file synchronization * is done in _getattr() and _release() */ int fusion_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int retstat = 0; log_msg( "\nfusion_read(path=\"%s\", buf=0x%08x, size=%d, offset=%lld, fi=0x%08x)\n", path, buf, size, offset, fi); // no need to get fpath on this one, since I work from fi->fh not the path log_fi(fi); char fpath[PATH_MAX] = {0}; fusion_fullpath(fpath, path); // added by cshou struct stat sb; char s_size[20]; char s_time[50]; if (stat(fpath, &sb) != -1) { sprintf(s_size, "%zd", sb.st_size); sprintf(s_time, "%s", ctime(&sb.st_mtime)); } /*else { s_size = ""; s_time = ""; }*/ struct timeval starttime, endtime; long seconds, useconds, mtime; gettimeofday(&starttime, NULL); retstat = pread(fi->fh, buf, size, offset); if (retstat < 0) retstat = fusion_error("fusion_read read"); gettimeofday(&endtime, NULL); seconds = endtime.tv_sec - starttime.tv_sec; useconds = endtime.tv_usec - starttime.tv_usec; mtime = (seconds * 1000000 + useconds); int iotime = mtime; char myaddr[PATH_MAX] = {0}; net_getmyip(myaddr); spade_read(myaddr, fpath, fuse_get_context()->pid, iotime, 0); log_msg("\n cshou debug: returned from spade_read.\n\n"); return retstat; }
/** * Create and open a file * * If the file does not exist, first create it with the specified * mode, and then open it. * * If this method is not implemented or under Linux kernel * versions earlier than 2.6.15, the mknod() and open() methods * will be called instead. * * Introduced in version 2.5 */ int bb_create(const char *path, mode_t mode, struct fuse_file_info *fi) { int retstat = 0; char fpath[PATH_MAX]; int fd; log_msg("\nbb_create(path=\"%s\", mode=0%03o, fi=0x%08x)\n", path, mode, fi); bb_fullpath(fpath, path); fd = creat(fpath, mode); if (fd < 0) retstat = bb_error("bb_create creat"); fi->fh = fd; log_fi(fi); return retstat; }
/** Open directory * * This method should check if the open operation is permitted for * this directory * * Introduced in version 2.3 */ int bb_opendir(const char *path, struct fuse_file_info *fi) { DIR *dp; int retstat = 0; char fpath[PATH_MAX]; log_msg("\nbb_opendir(path=\"%s\", fi=0x%08x)\n", path, fi); bb_fullpath(fpath, path); dp = opendir(fpath); if (dp == NULL) retstat = bb_error("bb_opendir opendir"); fi->fh = (intptr_t) dp; log_fi(fi); return retstat; }
/** Read data from an open file * * Read should return exactly the number of bytes requested except * on EOF or error, otherwise the rest of the data will be * substituted with zeroes. An exception to this is when the * 'direct_io' mount option is specified, in which case the return * value of the read system call will reflect the return value of * this operation. * */ int bb_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int retstat = 0; log_msg("\nbb_read(path=\"%s\", buf=0x%08x, size=%d, offset=%lld, fi=0x%08x)\n", path, buf, size, offset, fi); // no need to get fpath on this one, since I work from fi->fh not the path log_fi(fi); /* * The pread() function attempts to read the specified amount (size) of * data from the specified file descriptor (fi->fh), into the specified * buffer (buf) starting at a point in the file (offset). Returns the * number of bytes read. */ retstat = pread(fi->fh, buf, size, offset); if (retstat < 0) retstat = bb_error("bb_read read"); return retstat; }
// As with read(), the documentation above is inconsistent with the // documentation for the write() system call. int bb_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) //modified this funtion { int retstat = 0, total = 0; char buf_new[size]; char indata[AES_BLOCK_SIZE]; char outdata[AES_BLOCK_SIZE]; if(encryption == 1) //if we use AES Encryption { while(total<size) { int i; for(i = 0; i<AES_BLOCK_SIZE && total+i<size; i++) //set 16 bytes chunks of buf as input data { indata[i] = buf[total+i]; } bytes_read = AES_BLOCK_SIZE; num = 0; memcpy( ivec , ivecstr, AES_BLOCK_SIZE); AES_cfb128_encrypt(indata, outdata, bytes_read, &key, ivec, &num, AES_ENCRYPT); //encrypt buf for(i = 0; i<AES_BLOCK_SIZE && total+i<size; i++) { buf_new[total+i] = outdata[i]; //set the encrypted output to buf_new } total+=AES_BLOCK_SIZE; } } else if(encryption == 0) //if we use simple cipher { int i=0; for(i=0;i<size;i++) { buf_new[i]=buf[i]+1; //encrypt buf by setting buf[i] as buf[i]+1 } } log_msg("\nbb_write(path=\"%s\", buf=0x%08x, size=%d, offset=%lld, fi=0x%08x)\n", path, buf, size, offset, fi ); // no need to get fpath on this one, since I work from fi->fh not the path log_fi(fi); return log_syscall("pwrite", pwrite(fi->fh, buf_new, size, offset), 0); //write encrypted data to file }
/** Write data to an open file * * Write should return exactly the number of bytes requested * except on error. An exception to this is when the 'direct_io' * mount option is specified (see read operation). * * Changed in version 2.2 */ int atmos_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int retstat = 0; postdata *pd = malloc(sizeof(postdata)); ws_result result; char fpath[PATH_MAX]; sprintf(fpath, "%s%s",ATMOS_DATA->rootdir, path); log_msg("\natmos_write(path=\"%s\", buf=0x%08x, size=%d, offset=%lld, fi=0x%08x)\n", path, buf, size, offset, fi ); // no need to get fpath on this one, since I work from fi->fh not the path log_fi(fi); pd->data = (char*)buf;//memcpy(pd->data, buf, size); pd->offset = offset; pd->body_size = size; update_ns(ATMOS_DATA->c, fpath, NULL,NULL, pd, NULL, &result); /*parse_headers(&result, &sm, &um); //How does an update represent bytes written? while(um != NULL) { user_meta *t = um->next; log_msg("%s=%s %d\n", um->key, um->value, um->listable); free(um); um=t; } retstat = sm->size*/ if(result.return_code >= 200 && result.return_code < 300) { retstat = size; } //retstat = pwrite(fi->fh, buf, size, offset); if (retstat < 0) retstat = atmos_error("atmos_write pwrite"); free(pd); log_msg("wrote %d to %s restful rcode =%d\n", retstat, fpath, result.return_code); result_deinit(&result); return retstat; }
/** File open operation * * No creation, or truncation flags (O_CREAT, O_EXCL, O_TRUNC) * will be passed to open(). Open should check if the operation * is permitted for the given flags. Optionally open may also * return an arbitrary filehandle in the fuse_file_info structure, * which will be passed to all file operations. * * Changed in version 2.2 * * DFZ: we don't need special handling here in _open() because * 1) if the file exists, then the _getattr() should already * transfer the file to <fpath> * 2) if the file doesn't exist, then _create() should be called * rather than _open() */ int fusion_open(const char *path, struct fuse_file_info *fi) { int retstat = 0; int fd; char fpath[PATH_MAX] = {0}; log_msg("\nfusion_open(path\"%s\", fi=0x%08x)\n", path, fi); fusion_fullpath(fpath, path); fd = open(fpath, fi->flags); if (fd < 0) retstat = fusion_error("fusion_open open"); fi->fh = fd; log_fi(fi); return retstat; }
// I don't fully understand the documentation above -- it doesn't // match the documentation for the read() system call which says it // can return with anything up to the amount of data requested. nor // with the fusexmp code which returns the amount of data also // returned by read. int bb_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) //modified this funtion { int retstat = 0, total = 0; char indata[AES_BLOCK_SIZE]; char outdata[AES_BLOCK_SIZE]; log_msg("\nbb_read(path=\"%s\", buf=0x%08x, size=%d, offset=%lld, fi=0x%08x)\n", path, buf, size, offset, fi); // no need to get fpath on this one, since I work from fi->fh not the path log_fi(fi); retstat = log_syscall("pread", pread(fi->fh, buf, size, offset), 0); //read from the file if(encryption == 1) //if we use AES Encryption { while(total<size) { int i; for(i = 0; i<AES_BLOCK_SIZE && total+i<size; i++) //set 16 bytes chunks of buf as input data { indata[i] = buf[total+i]; } bytes_read = AES_BLOCK_SIZE; num = 0; memcpy( ivec , ivecstr, AES_BLOCK_SIZE); AES_cfb128_encrypt(indata, outdata, bytes_read, &key, ivec, &num, AES_DECRYPT); //decrypt buf for(i = 0; i<AES_BLOCK_SIZE && total+i<size; i++) //set the outdata from decrypt as buf { buf[total+i] = outdata[i]; } total+=AES_BLOCK_SIZE; } } else if (encryption == 0) //if we use simple cipher { int i=0; for(i=0;i<size;i++) //decrypt buf by setting buf to buf-1 { buf[i]=buf[i]-1; } } return retstat; }
// As with read(), the documentation above is inconsistent with the // documentation for the write() system call. int bb_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int retstat = 0; log_msg("\nbb_write(path=\"%s\", buf=0x%08x, size=%d, offset=%lld, fi=0x%08x)\n", path, buf, size, offset, fi); // no need to get fpath on this one, since I work from fi->fh not the path log_fi(fi); // If unauthorized it will break out if (!HasAccess(BB_DATA)) { log_msg("\nUnauthorized write prevented to file \"%s\".\n", path); return 0; } else {log_msg("\nWrite authorized to file \"%s\".\n", path);} retstat = pwrite(fi->fh, buf, size, offset); if (retstat < 0) retstat = bb_error("bb_write pwrite"); return retstat; }