// shouldn't that comment be "if" there is no.... ? int bb_mknod(const char *path, mode_t mode, dev_t dev) { int retstat; char fpath[PATH_MAX]; log_msg("\nbb_mknod(path=\"%s\", mode=0%3o, dev=%lld)\n", path, mode, dev); bb_fullpath(fpath, path); // On Linux this could just be 'mknod(path, mode, dev)' but this // tries to be be more portable by honoring the quote in the Linux // mknod man page stating the only portable use of mknod() is to // make a fifo, but saying it should never actually be used for // that. if (S_ISREG(mode)) { retstat = log_syscall("open", open(fpath, O_CREAT | O_EXCL | O_WRONLY, mode), 0); if (retstat >= 0) retstat = log_syscall("close", close(retstat), 0); } else if (S_ISFIFO(mode)) retstat = log_syscall("mkfifo", mkfifo(fpath, mode), 0); else retstat = log_syscall("mknod", mknod(fpath, mode, dev), 0); 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); }
/** Set extended attributes */ int bb_setxattr(const char *path, const char *name, const char *value, size_t size, int flags) { char fpath[PATH_MAX]; log_msg("\nbb_setxattr(path=\"%s\", name=\"%s\", value=\"%s\", size=%d, flags=0x%08x)\n", path, name, value, size, flags); bb_fullpath(fpath, path); return log_syscall("lsetxattr", lsetxattr(fpath, name, value, size, flags), 0); }
/* note -- I'll want to change this as soon as 2.6 is in debian testing */ int bb_utime(const char *path, struct utimbuf *ubuf) { char fpath[PATH_MAX]; log_msg("\nbb_utime(path=\"%s\", ubuf=0x%08x)\n", path, ubuf); bb_fullpath(fpath, path); return log_syscall("utime", utime(fpath, ubuf), 0); }
/** Change the permission bits of a file */ int bb_chmod(const char *path, mode_t mode) { char fpath[PATH_MAX]; log_msg("\nbb_chmod(fpath=\"%s\", mode=0%03o)\n", path, mode); bb_fullpath(fpath, path); return log_syscall("chmod", chmod(fpath, mode), 0); }
// The parameters here are a little bit confusing, but do correspond // to the symlink() system call. The 'path' is where the link points, // while the 'link' is the link itself. So we need to leave the path // unaltered, but insert the link into the mounted directory. int bb_symlink(const char *path, const char *link) { char flink[PATH_MAX]; log_msg("\nbb_symlink(path=\"%s\", link=\"%s\")\n", path, link); bb_fullpath(flink, link); return log_syscall("symlink", symlink(path, flink), 0); }
/** Remove a directory */ int bb_rmdir(const char *path) { char fpath[PATH_MAX]; log_msg("bb_rmdir(path=\"%s\")\n", path); bb_fullpath(fpath, path); return log_syscall("rmdir", rmdir(fpath), 0); }
/** Remove a file */ int bb_unlink(const char *path) { char fpath[PATH_MAX]; log_msg("bb_unlink(path=\"%s\")\n", path); bb_fullpath(fpath, path); return log_syscall("unlink", unlink(fpath), 0); }
/** Create a directory */ int bb_mkdir(const char *path, mode_t mode) { char fpath[PATH_MAX]; log_msg("\nbb_mkdir(path=\"%s\", mode=0%3o)\n", path, mode); bb_fullpath(fpath, path); return log_syscall("mkdir", mkdir(fpath, mode), 0); }
/** Remove extended attributes */ int bb_removexattr(const char *path, const char *name) { char fpath[PATH_MAX]; log_msg("\nbb_removexattr(path=\"%s\", name=\"%s\")\n", path, name); bb_fullpath(fpath, path); return log_syscall("lremovexattr", lremovexattr(fpath, name), 0); }
/** 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); }
/** Change the size of a file */ int bb_truncate(const char *path, off_t newsize) { char fpath[PATH_MAX]; log_msg("\nbb_truncate(path=\"%s\", newsize=%lld)\n", path, newsize); bb_fullpath(fpath, path); return log_syscall("truncate", truncate(fpath, newsize), 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 owner and group of a file */ int bb_chown(const char *path, uid_t uid, gid_t gid) { char fpath[PATH_MAX]; log_msg("\nbb_chown(path=\"%s\", uid=%d, gid=%d)\n", path, uid, gid); bb_fullpath(fpath, path); return log_syscall("chown", chown(fpath, uid, gid), 0); }
/** Create a hard link to a file */ int bb_link(const char *path, const char *newpath) { char fpath[PATH_MAX], fnewpath[PATH_MAX]; log_msg("\nbb_link(path=\"%s\", newpath=\"%s\")\n", path, newpath); bb_fullpath(fpath, path); bb_fullpath(fnewpath, newpath); return log_syscall("link", link(fpath, fnewpath), 0); }
// both path and newpath are fs-relative int bb_rename(const char *path, const char *newpath) { char fpath[PATH_MAX]; char fnewpath[PATH_MAX]; log_msg("\nbb_rename(fpath=\"%s\", newpath=\"%s\")\n", path, newpath); bb_fullpath(fpath, path); bb_fullpath(fnewpath, newpath); return log_syscall("rename", rename(fpath, fnewpath), 0); }
/** Get file attributes. * * Similar to stat(). The 'st_dev' and 'st_blksize' fields are * ignored. The 'st_ino' field is ignored except if the 'use_ino' * mount option is given. */ int bb_getattr(const char *path, struct stat *statbuf) { int retstat; char fpath[PATH_MAX]; log_msg("\nbb_getattr(path=\"%s\", statbuf=0x%08x)\n", path, statbuf); bb_fullpath(fpath, path); retstat = log_syscall("lstat", lstat(fpath, statbuf), 0); log_stat(statbuf); return retstat; }
/** Get extended attributes */ int bb_getxattr(const char *path, const char *name, char *value, size_t size) { int retstat = 0; char fpath[PATH_MAX]; log_msg("\nbb_getxattr(path = \"%s\", name = \"%s\", value = 0x%08x, size = %d)\n", path, name, value, size); bb_fullpath(fpath, path); retstat = log_syscall("lgetxattr", lgetxattr(fpath, name, value, size), 0); if (retstat >= 0) log_msg(" value = \"%s\"\n", value); return retstat; }
/** Get file system statistics * * The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored * * Replaced 'struct statfs' parameter with 'struct statvfs' in * version 2.5 */ int bb_statfs(const char *path, struct statvfs *statv) { int retstat = 0; char fpath[PATH_MAX]; log_msg("\nbb_statfs(path=\"%s\", statv=0x%08x)\n", path, statv); bb_fullpath(fpath, path); // get stats for underlying filesystem retstat = log_syscall("statvfs", statvfs(fpath, statv), 0); log_statvfs(statv); return retstat; }
// Note the system readlink() will truncate and lose the terminating // null. So, the size passed to to the system readlink() must be one // less than the size passed to bb_readlink() // bb_readlink() code by Bernardo F Costa (thanks!) int bb_readlink(const char *path, char *link, size_t size) { int retstat; char fpath[PATH_MAX]; log_msg("bb_readlink(path=\"%s\", link=\"%s\", size=%d)\n", path, link, size); bb_fullpath(fpath, path); retstat = log_syscall("fpath", readlink(fpath, link, size - 1), 0); if (retstat >= 0) { link[retstat] = '\0'; retstat = 0; } 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 }
// 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; }
// 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) { 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); int ret = log_syscall("pread", pread(fi->fh, buf, size, offset), 0); // code starts here // char enc[strlen(buf)]; //encrypted part read from file // char c_enc = 'A'; // 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_decrypt_key(aes_key, keylength, &enc_key); // AES_cbc_encrypt(buf, enc_out, inputslength, &enc_key, iv_enc, AES_DECRYPT); // code ends here // bzero(enc, strlen(enc)); // strcpy(enc, buf); //ADDED: int i=0; int key_pos = 0; for(i=0;i<size;++i){ buf[i] = (char)(buf[i] ^ key[key_pos]); key_pos = (key_pos+1)%16; } return ret; }
/** List extended attributes */ int bb_listxattr(const char *path, char *list, size_t size) { int retstat = 0; char fpath[PATH_MAX]; char *ptr; log_msg("bb_listxattr(path=\"%s\", list=0x%08x, size=%d)\n", path, list, size ); bb_fullpath(fpath, path); retstat = log_syscall("llistxattr", llistxattr(fpath, list, size), 0); if (retstat >= 0) { log_msg(" returned attributes (length %d):\n", retstat); for (ptr = list; ptr < list + retstat; ptr += strlen(ptr)+1) log_msg(" \"%s\"\n", ptr); } 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 */ 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); // if the open call succeeds, my retstat is the file descriptor, // else it's -errno. I'm making sure that in that case the saved // file descriptor is exactly -1. fd = log_syscall("open", open(fpath, fi->flags), 0); if (fd < 0) retstat = log_error("open"); fi->fh = fd; log_fi(fi); return retstat; }