Beispiel #1
0
static boolean_t
contains_valid_dirs(char *dirs_str)
{
	boolean_t	rc = B_FALSE;
	boolean_t	rc_validate_path = B_TRUE;
	char		*tok_ptr;
	char		*tok_lasts;

	if (dirs_str == NULL) {
		return (rc);
	}

	if ((tok_ptr = strtok_r(dirs_str, ",", &tok_lasts)) != NULL) {
		if (validate_path(tok_ptr)) {
			rc = B_TRUE;
		} else {
			rc_validate_path = B_FALSE;
		}
		while ((tok_ptr = strtok_r(NULL, ",", &tok_lasts)) != NULL) {
			if (validate_path(tok_ptr)) {
				rc = B_TRUE;
			} else {
				rc_validate_path = B_FALSE;
			}
		}
	}

	if (rc && !rc_validate_path) {
		(void) fprintf(stderr, gettext("%s: at least one valid "
		    "directory path found\n"), progname);
	}

	return (rc);
}
Beispiel #2
0
gchar *
cockpit_package_resolve (GHashTable *listing,
                         const gchar *package,
                         const gchar *path)
{
  CockpitPackage *mod;

  /*
   * This is *not* a security check. We're accessing files as the user.
   * What this does is prevent package authors from drawing outside the
   * lines. Keeps everyone honest.
   */
  if (strstr (path, "../") || strstr (path, "/..") || !validate_path (path))
    {
      g_message ("invalid 'path' used as a resource: %s", path);
      return NULL;
    }

  if (!validate_checksum (package) && !validate_package (package))
    {
      g_message ("invalid 'package' name: %s", package);
      return NULL;
    }

  mod = g_hash_table_lookup (listing, package);
  if (mod == NULL)
    {
      g_debug ("resource package was not found: %s", package);
      return NULL;
    }

  return g_build_filename (mod->directory, path, NULL);
}
Beispiel #3
0
static void fn_open(l4fdx_srv_obj srv_obj, struct internal_request *r)
{
    struct file *f;
    struct l4fdx_result_t ret;
    struct l4fdx_client *c = srv_obj->client;
    int err, fid = -1;
    char const *path = r->open.path;

    if (c->basepath) {
        unsigned l = strlen(path);
        char *s = kmalloc(c->basepath_len + l + 1, GFP_KERNEL);
        if (!s) {
            err = -ENOMEM;
            goto out;
        }
        strncpy(s, c->basepath, c->basepath_len);
        strncpy(s + c->basepath_len, path, l);
        s[c->basepath_len + l] = 0;

        if (!validate_path(s, c->basepath_len + l)) {
            kfree(s);
            err = -EINVAL;
            goto out;
        }

        path = s;
    }

    call_fdx_event(c, "pre-open", path, UMH_WAIT_PROC);

    f = filp_open(path, r->open.flags & c->openflags_mask, r->open.mode);
    if (IS_ERR(f)) {
        err = PTR_ERR(f);
    } else {
        fid = set_free_fdxslot(c, f);
        if (fid == -1) {
            filp_close(f, NULL);
            err = -ENOMEM;
        } else
            err = 0;
    }

    if (c->flag_nogrow && err == 0) {
        struct kstat stat;
        int r = vfs_getattr(&f->f_path, &stat);
        c->max_file_size = r ? 0 : stat.size;
    }

    call_fdx_event(c, "post-open", path, UMH_WAIT_EXEC);

    if (c->basepath)
        kfree(path);

out:
    ret.payload.fid = fid;
    ret.payload.ret = err;
    res_event(srv_obj, &ret, r->client_req_id);

    kfree(r);
}
Beispiel #4
0
int
cmd_renew(int argc, char **argv)
{
    long long ts = renew_timeout();
    off_t offset = 0;
    int opt, fd, r;

    optind = 0;
    while ((opt = getopt(argc, argv, "+hdr:o:t:")) != -1) {
        switch (opt) {
        case 'h':
            usage();
            break;
        case 'd':
            debug++;
            break;
        case 'r':
            request = optarg;
            break;
        case 'o':
            offset = strtoul(optarg, 0, 0);
            break;
        case 't':
            ts = strtoll(optarg, 0, 0);
            break;
        }
    }
    if (argc - optind < 4)
        usage();

    path = argv[optind++];
    validate_path(path);
    id = argv[optind++];
    validate_id(id);
    lease_ms = strtoul(argv[optind++], 0, 0);
    op_max_ms = strtoul(argv[optind++], 0, 0);
    validate_lease_params(lease_ms, op_max_ms);

    DEBUG("path '%s' offset %ld id '%s' lease_ms %ld op_max_ms %ld",
        path, offset, id, lease_ms, op_max_ms);

    if ((fd = open(path, O_RDWR | O_DIRECT)) < 0)
        panic("can't open '%s'", path);

    r = renew(fd, offset, id, &ts);

    close(fd);

    /* print out the last successful renewal timestamp, or zero for don't renew */
    printf("%lld\n", ts);

    if (r == 1) {
        DEBUG("Succeeded");
        return 0;
    }

    DEBUG("%s (%s)", "Failed", strerror(r));
    return 1;
}
static void
do_cd (void)
{
	char *p;

	p = arg_data [arg_cur++];

	if (!p) {
		fprintf (vfserr, "Takes a directory argument\n");
		return;
	}

	if (!g_ascii_strcasecmp (p, "..")) {
		guint lp;
		char **tmp;
		GString *newp = g_string_new ("");
		const char *ptr = g_path_skip_root (cur_dir);

		g_string_append_len (newp, cur_dir, ptr - cur_dir);

		tmp = g_strsplit_set (ptr, DIR_SEPARATORS, -1);
		lp  = 0;
		if (!tmp [lp])
			return;

		while (tmp [lp + 1] && strlen (tmp [lp + 1]) > 0) {
			g_string_append_printf (newp, "%s" G_DIR_SEPARATOR_S, tmp [lp]);
			lp++;
		}
		cur_dir = newp->str;
		g_string_free (newp, FALSE);
	} else if (!g_ascii_strcasecmp (p, ".")) {
	} else {
		char *newpath;

		if (g_path_is_absolute (p)) {
			if (!G_IS_DIR_SEPARATOR (p [strlen (p) - 1]))
				newpath = g_strconcat (p, G_DIR_SEPARATOR_S, NULL);
			else
				newpath = g_strdup (p);
		} else {
			char *ptr;
			
			ptr = get_regexp_name (p, cur_dir, TRUE);
			if (!ptr) {
				fprintf (vfserr, "Can't find '%s'\n", p);
				return;
			}

			newpath = g_strconcat (cur_dir, ptr, G_DIR_SEPARATOR_S, NULL);
		}

		if (validate_path (newpath)) {
			cur_dir = newpath;
		} else
			fprintf (vfserr, "Invalid path %s\n", newpath);
	}
}
Beispiel #6
0
int
cmd_acquire(int argc, char **argv)
{
    int opt, fd, r, b = 0;
    off_t offset = 0;
    long long ts;

    optind = 0;
    while ((opt = getopt(argc, argv, "+hdr:bo:")) != -1) {
        switch (opt) {
        case 'h':
            usage();
            break;
        case 'd':
            debug++;
            break;
        case 'r':
            request = optarg;
            break;
        case 'b':
            b = 1;
            break;
        case 'o':
            offset = strtoul(optarg, 0, 0);
            break;
        }
    }
    if (argc - optind < 4)
        usage();

    path = argv[optind++];
    validate_path(path);
    id = argv[optind++];
    validate_id(id);
    lease_ms = strtoul(argv[optind++], 0, 0);
    op_max_ms = strtoul(argv[optind++], 0, 0);
    validate_lease_params(lease_ms, op_max_ms);

    DEBUG("path '%s' offset %ld id '%s' lease_ms %ld op_max_ms %ld",
        path, offset, id, lease_ms, op_max_ms);

    if ((fd = open(path, O_RDWR | O_DIRECT)) < 0)
        panic("can't open '%s'", path);

    r = acquire(fd, offset, id, b, &ts);

    close(fd);

    if (r == 1) {
        /* print last successful timestamp == aquire time */
        printf("%lld", ts);
        DEBUG("Succeeded");
        return 0;
    } else
        DEBUG("%s (%s)", "Failed", strerror(r));

    return 1;
}
Beispiel #7
0
/* vxdb.mount.get(string name[, string dst]) */
xmlrpc_value *m_vxdb_mount_get(xmlrpc_env *env, xmlrpc_value *p, void *c)
{
	xmlrpc_value *params, *response = NULL;
	char *name, *dst;
	int rc;
	xid_t xid;

	params = method_init(env, p, c, VCD_CAP_MOUNT, M_OWNER);
	method_return_if_fault(env);

	xmlrpc_decompose_value(env, params,
			"{s:s,s:s,*}",
			"name", &name,
			"dst", &dst);
	method_return_if_fault(env);

	method_empty_params(1, &dst);

	if (dst && !validate_path(dst))
		method_return_faultf(env, MEINVAL,
				"invalid dst value: %s", dst);

	if (!(xid = vxdb_getxid(name)))
		method_return_fault(env, MENOVPS);

	if (dst)
		rc = vxdb_prepare(&dbr,
				"SELECT src,dst,type,opts FROM mount "
				"WHERE xid = %d AND dst = '%s'",
				xid, dst);

	else
		rc = vxdb_prepare(&dbr,
				"SELECT src,dst,type,opts FROM mount "
				"WHERE xid = %d ORDER BY dst ASC",
				xid);

	if (rc != VXDB_OK)
		method_return_vxdb_fault(env);

	response = xmlrpc_array_new(env);

	vxdb_foreach_step(rc, dbr)
		xmlrpc_array_append_item(env, response, xmlrpc_build_value(env,
				"{s:s,s:s,s:s,s:s}",
				"src",  vxdb_column_text(dbr, 0),
				"dst",  vxdb_column_text(dbr, 1),
				"type", vxdb_column_text(dbr, 2),
				"opts", vxdb_column_text(dbr, 3)));

	if (rc != VXDB_DONE)
		method_set_vxdb_fault(env);

	vxdb_finalize(dbr);

	return response;
}
Beispiel #8
0
/*
 * Name:    dir_help
 * Purpose: To prompt the user and list the directory contents
 * Date:    February 13, 1992
 * Passed:  window:  pointer to current window
 */
int  dir_help( WINDOW *window )
{
char dname[MAX_COLS+2]; /* directory search pattern */
char stem[MAX_COLS+2];  /* directory stem */
char drive[_MAX_DRIVE]; /* splitpath drive buff */
char dir[_MAX_DIR];     /* splitpath dir buff */
char fname[_MAX_FNAME]; /* splitpath fname buff */
char ext[_MAX_EXT];     /* splitpath ext buff */
int  rc;
int  file_mode;
int  bin_length;
int  prompt_line;

   if (window != NULL) {
      entab_linebuff( );
      if (un_copy_line( window->ll, window, TRUE ) == ERROR)
         return( ERROR );
      prompt_line = window->bottom_line;
   } else
      prompt_line = g_display.nlines;

   /*
    * search path or pattern
    */
   dname[0] = '\0';
   rc = get_name( dir1, prompt_line, dname, g_display.message_color );

   if (rc == OK) {
      if (validate_path( dname, stem ) == OK) {
         rc = list_and_pick( dname, stem, window );

         /*
          * if everything is everything, load in the file selected by user.
          */
         if (rc == OK) {
            file_mode = TEXT;
            bin_length = 0;
            _splitpath( dname, drive, dir, fname, ext );
            if (stricmp( ext, ".exe" ) == 0  ||  stricmp( ext, ".com" ) == 0) {
               file_mode = BINARY;
               bin_length = g_status.file_chunk;
            }
            if (window != NULL)
               attempt_edit_display( dname, LOCAL, file_mode, bin_length );
            else
               attempt_edit_display( dname, GLOBAL, file_mode, bin_length );
         }
      } else
         /*
          * invalid path or file name
          */
         error( WARNING,
                window != NULL ? window->bottom_line : g_display.nlines, dir2 );
   }
   return( rc );
}
Beispiel #9
0
/*
 * The function vfs_read provides the ability to read data from 
 * an absolute path 'path,' which should specify an existing file.
 * It will attempt to read 'size' bytes starting at the specified
 * offset (offset) from the specified file (path)
 * on your filesystem into the memory address 'buf'. The return 
 * value is the amount of bytes actually read; if the file is 
 * smaller than size, vfs_read will simply return the most amount
 * of bytes it could read. 
 *
 * HINT: You should be able to ignore 'fi'
 *
 */
static int vfs_read(const char *path, char *buf, size_t size, off_t offset,
                    struct fuse_file_info *fi)
{
  if(validate_path(path) != 0)
    return -1;
  
  // Function variables
  char block[BLOCKSIZE];
  memset(&block,0,BLOCKSIZE);
  int bytesread = 0;
  vcb vb = getvcb();
  path++;
 
  // Parse offset into block and "into" block
  int offset_block = (int) (offset / 512); 
  int offset_into_block = offset % 512;
  int buffer_offset = 0;
  
  // Read offset datablock into memory
  dread(offset_block + vb.db_start, block);
  // Memcpy the rest of the block or size amount, whichever bounds first
  while(size > 0 && offset_into_block < BLOCKSIZE){
    buf[buffer_offset] = block[offset_into_block];
    size--;
    offset_into_block++;
    buffer_offset++;
    bytesread++;
  }

  // The rest of the first block has been read,
  // size bytes remain to be read
  while(size > 0){
    if(offset_into_block == BLOCKSIZE){
      // Get next fat entry / data block offset
      offset_block = getfe(offset_block).next;
      
      // Read in next datablock to block
      memset(&block,0,BLOCKSIZE);
      dread(offset_block + vb.db_start, block);
    
      // Reset pointers
      offset_into_block = 0;
    }
    else{
      // Read byte into buffer
      buf[buffer_offset] = block[offset_into_block];
      size--;
      offset_into_block++;
      buffer_offset++;
      bytesread++;
    }
  }
  return bytesread;
}
Beispiel #10
0
/*
 * Given an absolute path to a file (for example /a/b/myFile), vfs_create 
 * will create a new file named myFile in the /a/b directory.
 *
 */
static int vfs_create(const char *path, mode_t mode, struct fuse_file_info *fi) {
  vcb vb = getvcb(); // Get our VCB, used to find start/end points of dirents.

  if(validate_path(path) != 0) // If the path is invalid, return an error.
    return -1;
  path++; // Increment path, getting rid of the leading /.

  int first_free = -1; // Index of first free dirent. 

  // To create a file, we need to first read used dirents and search for a duplicate.
  for(int i = vb.de_start; i < vb.de_start+vb.de_length && first_free < 0; i++){
    dirent de = getdirent(i);
 
    if(de.valid == 1){
      if(strcmp(de.name, path) == 0)
        return -EEXIST;
    } 
    else{
        first_free = i;
    }
  }

  // File doesn't already exist. Next, check for free spaces. If free_flag != 0 first_free == idx of first free dirent.
  if(first_free >= 0){ // If free dirents exist...
    dirent new_file; // Creating a new dirent, and assign its fields.
    new_file.valid = 1;
    new_file.first_block = -1; // Used to indicate a file with no data.
    new_file.size = 0;
    new_file.userid = getuid();
    new_file.groupid = getgid();
    new_file.mode = mode;

    struct timespec newtime;
    clock_gettime(CLOCK_REALTIME, &newtime);

    new_file.access_time = newtime;
    new_file.modify_time = newtime;
    new_file.create_time = newtime;

    memset(new_file.name,0,sizeof(new_file.name));

    //char file_name[27];
    //memset(file_name,0,27);
    char file_name[512 - (3*sizeof(struct timespec)) - 24]; // Build the name string...
    memset(file_name,0,sizeof(file_name));
    strcpy(file_name,path); // Save path in to filename. Note: path has already been incrimented, so we're good.
    strcpy(new_file.name, file_name);

    setdirent(first_free,new_file); // Finally, we write our new dirent to disk at the index of first_free.
    return 0;
  }
  return -1; // If we reached here, free_flag == 0, meaning no free dirents exist.
}
Beispiel #11
0
static int
build_path(ftp_session_t *session,
           const char    *args)
{
  int  rc;
  char *p;

  memset(session->buffer, 0, sizeof(session->buffer));

  if(validate_path(args) != 0)
  {
    errno = EINVAL;
    return -1;
  }

  if(args[0] == '/')
  {
    if(strlen(args) > sizeof(session->buffer)-1)
    {
      errno = ENAMETOOLONG;
      return -1;
    }
    strncpy(session->buffer, args, sizeof(session->buffer));
  }
  else
  {
    if(strcmp(session->cwd, "/") == 0)
      rc = snprintf(session->buffer, sizeof(session->buffer), "/%s",
                    args);
    else
      rc = snprintf(session->buffer, sizeof(session->buffer), "%s/%s",
                    session->cwd, args);

    if(rc >= sizeof(session->buffer))
    {
      errno = ENAMETOOLONG;
      return -1;
    }
  }

  p = session->buffer + strlen(session->buffer);
  while(p > session->buffer && *--p == '/')
    *p = 0;

  if(strlen(session->buffer) == 0)
    strcpy(session->buffer, "/");

  return 0;
}
Beispiel #12
0
int
cmd_release(int argc, char **argv)
{
    int opt, fd, r;
    int force = 0;
    off_t offset = 0;

    optind = 0;
    while ((opt = getopt(argc, argv, "+hdfo:")) != -1) {
        switch (opt) {
        case 'h':
            usage();
            break;
        case 'd':
            debug++;
            break;
        case 'f':
            force++;
            break;
        case 'o':
            offset = strtoul(optarg, 0, 0);
            break;
        }
    }
    if (argc - optind < 2)
        usage();

    path = argv[optind++];
    validate_path(path);
    id = argv[optind++];
    validate_id(id);

    DEBUG("path '%s' offset %ld id '%s' force %d", path, offset, id, force);

    if ((fd = open(path, O_RDWR | O_DIRECT)) < 0)
        panic("can't open '%s'", path);

    r = release(fd, offset, id, force);

    close(fd);

    if (r == 1) {
        DEBUG("Succeeded");
        return 0;
    } else
        DEBUG("%s (%s)", "Failed", strerror(r));

    return 1;
}
Beispiel #13
0
/*
 * The function rename will rename a file or directory named by the
 * string 'oldpath' and rename it to the file name specified by 'newpath'.
 *
 * HINT: Renaming could also be moving in disguise
 *
 */
static int vfs_rename(const char *from, const char *to)
{
  vcb vb = getvcb();

  if(validate_path(from) != 0)
    return -1;

  from++;
  for(int i = vb.de_start; i < vb.de_start+vb.de_length;i++){
    dirent de = getdirent(i);
    if(strcmp(de.name,from) == 0){
      strcpy(de.name, to);
      return 0;
    }
  }
  return -1;
}
Beispiel #14
0
/*
 * This function will update the file's last accessed time to
 * be ts[0] and will update the file's last modified time to be ts[1].
 */
static int vfs_utimens(const char *file, const struct timespec ts[2])
{
  vcb vb = getvcb();
  
  if(validate_path(file) != 0)
    return -1; // Invalid path.
  
  file++;
  for(int i = vb.de_start; i < vb.de_start+vb.de_length; i++){
    dirent de = getdirent(i);
    if(strcmp(de.name,file)==0){
      de.access_time = ts[0];
      de.modify_time = ts[1];
      setdirent(i,de);
      return 0; // Success
    }
  }
  return -1; // File not found.
}
Beispiel #15
0
/*
 * This function will change the user and group of the file
 * to be uid and gid.  This should only update the file's owner
 * and group.
 */
static int vfs_chown(const char *file, uid_t uid, gid_t gid)
{
  vcb vb = getvcb();
  
  if(validate_path(file) != 0)
    return -1; // Invalid path.
  
  file++;
  for(int i = vb.de_start; i < vb.de_start+vb.de_length; i++){
    dirent de = getdirent(i);
    if(strcmp(de.name,file)==0){
      de.userid = uid;
      de.groupid = gid;
      setdirent(i,de);
      return 0; // Success
    }
  }
  return -1; // File not found.
}
Beispiel #16
0
/*
 * This function will change the permissions on the file
 * to be mode.  This should only update the file's mode.  
 * Only the permission bits of mode should be examined 
 * (basically, the last 16 bits).  You should do something like
 * 
 * fcb->mode = (mode & 0x0000ffff);
 *
 */
static int vfs_chmod(const char *file, mode_t mode)
{
  vcb vb = getvcb();
  
  if(validate_path(file) != 0)
    return -1; // Invalid path.
  
  file++;
  for(int i = vb.de_start; i < vb.de_start+vb.de_length; i++){
    dirent de = getdirent(i);
    if(strcmp(de.name,file)==0){
      //de.mode = (mode & 0x0000ffff);
      de.mode = mode;
      setdirent(i,de);
      return 0; // Success
    }
  }
  return -1; // File not found.
}
Beispiel #17
0
/**
 * This function deletes the last component of the path (e.g., /a/b/c you 
 * need to remove the file 'c' from the directory /a/b).
 */
static int vfs_delete(const char *path)
{
  vcb vb = getvcb(); // Get our VCB, used to find start/end points of dirents.

  if(validate_path(path) != 0) // If the path is invalid, return an error.
    return -1;
  path++; // Increment path, getting rid of the leading /.

  // To create a file, we need to first read used dirents and search for a duplicate.
  for(int i = vb.de_start; i < vb.de_start+vb.de_length; i++){
    dirent de = getdirent(i); 
    if(strcmp(de.name, path) == 0){
      de.valid = 0;
      setdirent(i,de);
      return 0;
    }
  }
   return -EEXIST;
 
  /* 3600: NOTE THAT THE BLOCKS CORRESPONDING TO THE FILE SHOULD BE MARKED
           AS FREE, AND YOU SHOULD MAKE THEM AVAILABLE TO BE USED WITH OTHER FILES */
  // TODO: Mark blocks as free.
}
Beispiel #18
0
/*
 * This function will truncate the file at the given offset
 * (essentially, it should shorten the file to only be offset
 * bytes long).
 */
static int vfs_truncate(const char *file, off_t offset)
{
  // First, we ensure thepath is valid.
  if(validate_path(file) != 0)
    return -1;

  file++; 
  vcb vb = getvcb();

  dirent de;
  int dirent_index = -1;

  for(int i = vb.de_start; i < vb.de_start + vb.de_length && dirent_index == -1; i++){ // Get matching dirent.
    de = getdirent(i);
    if(strcmp(de.name,file) == 0)
      dirent_index = i;
  }
/*
   3600: NOTE THAT ANY BLOCKS FREED BY THIS OPERATION SHOULD
           BE AVAILABLE FOR OTHER FILES TO USE.
*/
  return 0;
}
Beispiel #19
0
/*
 * Name:    load_strokes
 * Purpose: load strokes from a file
 * Date:    April 1, 1992
 * Passed:  window:  pointer to current window
 * Notes:   show the user a file pick list.  I can never remember macro
 *           file names or the directory in which they hide.  might as well
 *           give the user a file pick list.
 */
int  load_strokes( WINDOW *window )
{
register FILE *fp;      /* file to be read */
char dname[MAX_COLS];   /* directory search pattern */
char stem[MAX_COLS];    /* directory stem */
register int rc;

   dname[0] = '\0';
   /*
    * search path for macro file
    */
   if (get_name( main21, window->bottom_line, dname,
                 g_display.message_color ) == OK  &&  *dname != '\0') {
      if (validate_path( dname, stem ) == OK) {
         rc = list_and_pick( dname, stem, window );

         /*
          * if everything is everything, load in the file selected by user.
          */
         if (rc == OK) {
            if ((fp = fopen( dname, "rb" )) != NULL && ceh.flag != ERROR) {
               fwrite( &macro.first_stroke[0], sizeof(int), MAX_KEYS, fp );
               fwrite( &macro.strokes[0], sizeof(STROKES), STROKE_LIMIT, fp );
               fclose( fp );
            }
            if (ceh.flag == OK)
               connect_macros( );
         }
      } else
         /*
          * invalid path or file name
          */
         error( WARNING, window->bottom_line, main22 );
   }
   return( OK );
}
Beispiel #20
0
/*
 * The function vfs_write will attempt to write 'size' bytes from 
 * memory address 'buf' into a file specified by an absolute 'path'.
 * It should do so starting at the specified offset 'offset'.  If
 * offset is beyond the current size of the file, you should pad the
 * file with 0s until you reach the appropriate length.
 *
 * You should return the number of bytes written.
 *
 * HINT: Ignore 'fi'
 */
static int vfs_write(const char *path, const char *buf, size_t size,
                     off_t offset, struct fuse_file_info *fi)
{
  // First, we ensure thepath is valid.
  if(validate_path(path) != 0)
    return -1;
  
  vcb vb = getvcb();
  path++;               // Get rid of leading slash in path
  int byteswritten = 0; // Amount of bytes we've written to disk from buffer
  int num_pad = 0;      // Amount of 0s we need to pad between EOF and offset
  int write_offset = 0; // variable to hold an offset for vfs_write.

  dirent de;
  int found_dirent = 0;
  int dirent_index = -1;
  
  for(int i = vb.de_start; i < vb.de_start + vb.de_length, found_dirent == 0; i++){
    de = getdirent(i);
    if(de.valid == 1)
      if(strcmp(path,de.name)==0){
        found_dirent = 1;
        dirent_index = i;
      }
  }

  if(found_dirent){	// Begin writing to disk.
    if(offset > de.size){ // Check for padding.
      num_pad = (offset - de.size); // Number of 0's to add.
    }
    if((size + offset) > de.size){
      de.size = (size + offset);    // Set the new size of the file.
    }
    
    // Update access modify times of file
    struct timespec newtime;
    clock_gettime(CLOCK_REALTIME, &newtime);
    
    de.access_time = newtime;
    de.modify_time = newtime;
    
    /* Next, since we have our dirent to write to, we must:
       - Check to see if the dirent has a FAT entry allocated.
       - Attempt to allocate one if necessary.
       x If the dirent has at least one FAT entry, begin writing:
       x Begin traversing offset, decrementing it as necessary until offset == 0.
       x Attempt to create new FAT entries if necessary.
       x Begin padding the file with zeros, if necessary, decrementing num_pad until it == 0.
       x Attempt to create new FAT entries if necessary.
       x Begin appending buf to file, decrementing size while doing so.
       x Attempt to create new FAT entries if necessary.
       x If, in any of the above cases, creating a new FAT entry fails, return -ENOSPC.
    */    
   
    

 
    // Check if found dirent has allocated FAT. If not, attempt to allocate one.
    if((int) de.first_block == -1){
      char block[BLOCKSIZE];
      int found_free = 0;
      
      for(int i = vb.fat_start;(i < vb.fat_start + ((int) (vb.fat_length/128))) && found_free == 0; i++){ // For each fat block...
	int block_index = (i-vb.fat_start)*128;
	
	memset(block,0,BLOCKSIZE); // Reset block.
	dread(i, block); // Read FAT Block into block.
	
	for(int j = 0; j < 128 && found_free == 0; j++){
	  fatent fe = getfe( block_index + j);
	  if(fe.used == 0){
	    de.first_block = block_index + j;
	    fe.used = 1;
	    fe.eof = 1;
	    fe.next = 0;
	    found_free = 1;
	  }
	}
      }
      if(found_free != 1){
        return -ENOSPC;
      }
    }
    
    
    
    fatent fe = getfe(de.first_block);
    
    char block[BLOCKSIZE];
    memset(block,0,BLOCKSIZE);
      
    // Expand file and pad 0's, if necessary.
    if(num_pad > 0){
      
      int eof_fat_idx = get_eof_fe(&fe) + vb.db_start;// find index of eof 
      dread(eof_fat_idx,block);
	
      int eof_data_idx;
	
      for(int i = 0; block[i] != EOF; i++)
        eof_data_idx++;

      eof_data_idx++; // Increment counter so block[eof_data_idx] == EOF.
	
	while(num_pad > 0){
          if(eof_data_idx < BLOCKSIZE){
	    memset(&block[eof_data_idx],0,1);
	    eof_data_idx++;
	    num_pad--;
	    if(num_pad == 0){
		dwrite(eof_data_idx,block);
		memset(block,0,BLOCKSIZE);
	    }
          } 
	  else{
	    dwrite(eof_fat_idx,block);
	    memset(block,0,BLOCKSIZE);
	    if(allocate_fat(&fe) != 0){
		return -ENOSPC;
	    }
	    eof_fat_idx = get_eof_fe(&fe) + vb.db_start;
	    eof_data_idx = 0;
	  }
	}
    }    
        
    // Now, we need to start writing size chars from buf into the file, starting at offset
    
    // Start by finding where offset is in the datablock.
    int offset_block = (int)(offset/512);
    int offset_into_block = offset % 512;
    int buffer_offset = 0;
    
    // Read in offset block, write at offset into block
    memset(block,0,BLOCKSIZE);
    dread(offset_block + vb.db_start, block);
    
    // Memcpy the rest of the block, or size bytes, whichever bounds first
    while(offset_into_block < BLOCKSIZE && size > 0){
      memcpy(&block[offset_into_block], buf, 1);
      size--;
      buf++;
      buffer_offset++;
      offset_into_block++;
      byteswritten++;
    }

    // Write block rest of block
    dwrite(offset_block + vb.db_start, block);
    
    // While there remains bytes to be written...
    while(size > 0){
      if(offset_into_block == BLOCKSIZE){
	// Write block
	dwrite(offset_block + vb.db_start, block);
	
	// Allocate new fat/data block
	if(allocate_fat(&fe) != 0){
	  return -ENOSPC;
	}
	
	// reset offset_into_block
	offset_into_block = 0;
	offset_block = get_eof_fe(&fe);
        memset(block,0,BLOCKSIZE);
      }
      
      memcpy(&block[offset_into_block], &buf[buffer_offset], 1);
      
      size--;
      buffer_offset++;
      offset_into_block++;
      byteswritten++;
    }

    // Write the rest of size bytes
    dwrite(offset_block + vb.db_start, block);
    setdirent(dirent_index,de);
    return byteswritten;
  }
  else{
    // No free dirents found
    return -1;
  }
  
}
Beispiel #21
0
    const fs::path&
    module_runtime_path(const std::string& dtype)
    {
      path_map& paths(module_paths());
      path_map::iterator ipath(paths.find(dtype));

      // Is this a valid dtype?
      if (ipath == paths.end())
        {
          boost::format fmt("Invalid runtime path type “%1%”");
          fmt % dtype;
          throw std::logic_error(fmt.str());
        }

      Module& module = ipath->second;

      // Return cached result if previously determined.
      if(!module.realpath.empty())
        return module.realpath;

      // dtype set explicitly in environment.
      if (getenv(module.envvar.c_str()))
        {
          fs::path dir(getenv(module.envvar.c_str()));
          if (validate_path(dir))
            {
              module.realpath = boost::filesystem::canonical(dir);
              return module.realpath;
            }
        }

      // Full module path in environment + relative component
      if (getenv(module.module_envvar.c_str()))
        {
          fs::path home(getenv(module.module_envvar.c_str()));
          home /= module.relpath;
          if (validate_path(home))
            {
              module.realpath = boost::filesystem::canonical(home);
              return module.realpath;
            }
        }

      // Full root path in environment + relative component
      if (getenv(module.root_envvar.c_str()))
        {
          fs::path home(getenv(module.root_envvar.c_str()));
          home /= module.relpath;
          if (validate_path(home))
            {
              module.realpath = boost::filesystem::canonical(home);
              return module.realpath;
            }
        }

      // Full prefix is available only when configured explicitly.
      if (validate_path(module.install_prefix))
        {
          // Full specific path.
          if (validate_path(module.abspath))
            {
              module.realpath = boost::filesystem::canonical(module.abspath);
              return module.realpath;
            }

          // Full root path + relative component
          fs::path home(module.install_prefix);
          home /= module.relpath;
          if (validate_path(home))
            {
              module.realpath = boost::filesystem::canonical(home);
              return module.realpath;
            }
        }
      else
        {
          fs::path module_lib_path;
          if (module.module_path)
            {
              module_lib_path = module.module_path();
            }
          if (module_lib_path.has_parent_path())
            {
              fs::path moduledir(module_lib_path.parent_path());
              bool match = true;

              fs::path libdir(module.shlibpath);

              while(!libdir.empty())
                {
                  if (libdir.filename() == moduledir.filename())
                    {
                      libdir = libdir.parent_path();
                      moduledir = moduledir.parent_path();
                    }
                  else
                    {
                      match = false;
                      break;
                    }
                }
              if (match && validate_path(moduledir))
                {
                  moduledir /= module.relpath;
                  if (validate_path(moduledir))
                    {
                      module.realpath = boost::filesystem::canonical(moduledir);
                      return module.realpath;
                    }
                }
            }
        }
      boost::format fmt("Could not determine Bio-Formats runtime path for “%1%” directory");
      fmt % dtype;
      throw std::runtime_error(fmt.str());
    }
Beispiel #22
0
static gboolean
package_checksum_file (GChecksum *checksum,
                       GHashTable *depends,
                       const gchar *root,
                       const gchar *filename)
{
  gchar *path = NULL;
  const gchar *string;
  GError *error = NULL;
  GChecksum *inner = NULL;
  GMappedFile *mapped = NULL;
  gboolean ret = FALSE;
  GList *output = NULL;
  GBytes *bytes;
  GList *l;

  if (!validate_path (filename))
    {
      g_warning ("package has an invalid path name: %s", filename);
      goto out;
    }

  path = g_build_filename (root, filename, NULL);
  if (g_file_test (path, G_FILE_TEST_IS_DIR))
    {
      ret = package_checksum_directory (checksum, depends, root, filename);
      goto out;
    }

  mapped = g_mapped_file_new (path, FALSE, &error);
  if (error)
    {
      g_warning ("couldn't open file: %s: %s", path, error->message);
      g_error_free (error);
      goto out;
    }

  bytes = g_mapped_file_get_bytes (mapped);
  output = cockpit_template_expand (bytes, gather_depends, depends);
  g_bytes_unref (bytes);

  inner = g_checksum_new (G_CHECKSUM_SHA1);

  for (l = output; l != NULL; l = g_list_next (l))
    {
      g_checksum_update (inner,
                         g_bytes_get_data (l->data, NULL),
                         g_bytes_get_size (l->data));
    }

  string = g_checksum_get_string (inner);

  /*
   * Place file name and hex checksum into checksum,
   * include the null terminators so these values
   * cannot be accidentally have a boundary discrepancy.
   */
  g_checksum_update (checksum, (const guchar *)filename,
                     strlen (filename) + 1);
  g_checksum_update (checksum, (const guchar *)string,
                     strlen (string) + 1);
  ret = TRUE;

out:
  g_list_free_full (output, (GDestroyNotify)g_bytes_unref);
  g_checksum_free (inner);
  if (mapped)
    g_mapped_file_unref (mapped);
  g_free (path);
  return ret;
}
Beispiel #23
0
/* 
 *
 * Given an absolute path to a file/directory (i.e., /foo ---all
 * paths will start with the root directory of the CS3600 file
 * system, "/"), you need to return the file attributes that is
 * similar stat system call.
 *
 * HINT: You must implement stbuf->stmode, stbuf->st_size, and
 * stbuf->st_blocks correctly.
 *
 */
static int vfs_getattr(const char *path, struct stat *stbuf) {
  fprintf(stderr, "vfs_getattr called\n");
  // Do not mess with this code 
  stbuf->st_nlink = 1; // hard links
  stbuf->st_rdev  = 0;
  stbuf->st_blksize = BLOCKSIZE;

  /* 3600: YOU MUST UNCOMMENT BELOW AND IMPLEMENT THIS CORRECTLY */
  
  /*
  if (The path represents the root directory)
    stbuf->st_mode  = 0777 | S_IFDIR;
  else 
    stbuf->st_mode  = <<file mode>> | S_IFREG;

  stbuf->st_uid     = // file uid
  stbuf->st_gid     = // file gid
  stbuf->st_atime   = // access time 
  stbuf->st_mtime   = // modify time
  stbuf->st_ctime   = // create time
  stbuf->st_size    = // file size
  stbuf->st_blocks  = // file size in blocks
    */

  if(strcmp(path, "/") == 0){
    vcb vb = getvcb();
    
    struct tm * tm1;
    struct tm * tm2;
    struct tm * tm3;
    tm1 = localtime(&((vb.access_time).tv_sec));
    tm2 = localtime(&((vb.modify_time).tv_sec));
    tm3 = localtime(&((vb.create_time).tv_sec));
    
    stbuf->st_mode = 0777 | S_IFDIR;
    
    stbuf->st_uid = vb.userid;
    stbuf->st_gid = vb.groupid;
    stbuf->st_atime = mktime(tm1);
    stbuf->st_mtime = mktime(tm2);
    stbuf->st_ctime = mktime(tm3);
    stbuf->st_size = BLOCKSIZE;
    stbuf->st_blocks = 1;
    return 0;
  }
  else{
    if(validate_path(path) != 0) // If the path is valid, we can proceed.
      return -1;
    path++;
    // char *filename = (char *) malloc(512 - (3 * sizeof(timespec)) - 24);
    for(int i = 1; i < 101; i++){
      dirent de = getdirent(i);
      if(de.valid == 1){
	if(strcmp(de.name, path) == 0){
	  struct tm * tm1;
	  struct tm * tm2;
	  struct tm * tm3;
	  tm1 = localtime(&((de.access_time).tv_sec));
	  tm2 = localtime(&((de.modify_time).tv_sec));
	  tm3 = localtime(&((de.create_time).tv_sec));
	  
	  stbuf->st_mode = de.mode | S_IFREG;
	  
	  stbuf->st_uid = de.userid;
	  stbuf->st_gid = de.groupid;
	  stbuf->st_atime = mktime(tm1);
	  stbuf->st_mtime = mktime(tm2);
	  stbuf->st_ctime = mktime(tm3);
	  stbuf->st_size = de.size;
	  stbuf->st_blocks = (de.size / BLOCKSIZE);
	  return 0;
	}// End if
      }// End if
    }// End for loop
    return -ENOENT;
  }
}
Beispiel #24
0
/*
 * Name:    list_and_pick
 * Purpose: To show matching file names and let user pick a file
 * Date:    February 13, 1992
 * Passed:  dname:  directory search pattern
 *          stem:   stem of directory search pattern
 *          window:  pointer to current window
 * Returns: return code from pick.  rc = OK, then edit a new file.
 * Notes:   real work routine of this function.  save the cwd and let the
 *           user search upwards or downwards thru the directory structure.
 *          since we are doing DOS directory functions, we need to check the
 *           return code after each DOS call for critical errors.
 */
int  list_and_pick( char *dname, char *stem, WINDOW *window )
{
int  rc;
DTA  dta;               /* disk transfer address for findfirst */
DIRECTORY dir;          /* contains all info for dir display */
unsigned int cnt;       /* number of matching files */
FTYPE *flist, *p;       /* pointer to list of matching files */
char cwd[MAX_COLS];     /* save the current working directory in this buff */
char dbuff[MAX_COLS];   /* temporary directory buff */
char prefix[MAX_COLS];  /* directory prefix  */
int  change_directory = FALSE;
int  stop;
int  len;
int  drive;

   /*
    * Some algorithms alloc the maximum possible number of files in
    *  a directory, eg. 256 or 512.  Let's count the number of matching
    *  files so we know egxactly how much memory to request from calloc.
    *  Depending on the op system, disk media, disk format, or version of DOS,
    *  the max number of files may vary, anyway, also, additionally.
    */
   rc = my_findfirst( &dta, dname, NORMAL | READ_ONLY | HIDDEN | SYSTEM |
                                SUBDIRECTORY | ARCHIVE );
   if (rc != ERROR) {
      for (cnt=1; (rc = my_findnext( &dta )) == OK;)
         ++cnt;
      flist = (FTYPE *)calloc( cnt, sizeof(FTYPE) );
   } else
      flist = NULL;
   if (rc != ERROR && flist != NULL) {

      stop = FALSE;
      /*
       * If user entered drive name in search pattern, find out the drive and
       *  directory stem.
       */
      if (stem[1] == ':') {

         /*
          * If the second character of the search pattern is a ':', the
          *  the first character of the pattern should be the drive.
          *  Convert drive to lower case and get a numerical representation.
          * CAVEAT:  In DOS v 2.x, there may be up to 63 logical drives.
          *   my algorithm may blow up if the number of logical drives
          *   is greater than 'Z'.
          * For DOS >= 3, the number of drives is limited to 26, I think.
          */
         drive = stem[0];
         if (drive < 'a')
            drive += 32;
         drive = drive - 'a' + 1;
         rc = get_current_directory( dbuff, drive );
         if (rc == ERROR)
            stop = TRUE;
         else {

            /*
             * Put drive letter, ':', and '\' in front of current directory.
             */
            prefix[0] = (char)(drive - 1 + 'a');
            prefix[1] = ':';
            prefix[2] = '\\';
            prefix[3] = '\0';
            assert( strlen( prefix ) + strlen( dbuff ) < MAX_COLS );
            strcpy( cwd, prefix );
            strcat( cwd, dbuff );
         }

      /*
       * else get current directory from default drive
       */
      } else {

         /*
          * 0 = default drive.
          */
         drive = 0;
         rc = get_current_directory( dbuff, drive );
         if (rc == ERROR)
            stop = TRUE;
         else {

            /*
             * Put a '\' in front of the current directory.
             */
            prefix[0] = '\\';
            prefix[1] = '\0';

            assert( strlen( prefix ) + strlen( dbuff ) < MAX_COLS );

            strcpy( cwd, prefix );
            strcat( cwd, dbuff );
         }
      }

      while (stop == FALSE) {
         /*
          * If we had enough memory, find all matching file names.  Append
          *  '\\' at the end of subdirectory names so user will know if
          *  name is a directory.  Might as well find everything, because
          *  i also forget subdirectory names, too.
          *
          * when we get here, we have already done: 1) my_findfirst and
          *  my_findnext, 2) counted the number of matching files, and
          *  3) allocated space.
          */
         p = flist;
         cnt = 0;

         rc = my_findfirst( &dta, dname, NORMAL | READ_ONLY | HIDDEN | SYSTEM |
                                 SUBDIRECTORY | ARCHIVE );
         if (rc != ERROR) {

            /*
             * p is pointer that walks down the file info structure.
             *  save the file name, file size, and directory character,
             *  if needed, for each matching file we find.
             */

            assert( strlen( dta.name ) < 14 );

            strcpy( p->fname, dta.name );
            p->fsize = dta.size;
            if (dta.attrib & SUBDIRECTORY)
               strcat( p->fname, "\\" );
            for (cnt=1; (rc = my_findnext( &dta )) == OK; ) {
               ++p;

               assert( strlen( dta.name ) < 14 );

               strcpy( p->fname, dta.name );
               p->fsize = dta.size;
               if (dta.attrib & SUBDIRECTORY)
                  strcat( p->fname, "\\" );
               cnt++;
            }
         }

         if (rc != ERROR) {
            shell_sort( flist, cnt );

            /*
             * figure out number of rows, cols, etc... then display dir list
             */
            setup_directory_window( &dir, cnt );
            write_directory_list( flist, dir );

            /*
             * Let user select file name or another search directory.
             *  Save the choice in dbuff.  rc == OK if user selected file or dir.
             */
            rc = select_file( flist, stem, &dir );

            assert( strlen( flist[dir.select].fname ) < MAX_COLS );

            strcpy( dbuff, flist[dir.select].fname );
         }

         /*
          *  give memory back.
          */
         free( flist );

         if (rc == ERROR)
            stop = TRUE;
         else {
            len = strlen( dbuff );

            /*
             * If the last character in a file name is '\' then let's
             *  do a dir on selected directory.  See the matching
             *  else when the user selects a file.
             */
            if (dbuff[len-1] == '\\') {

               /*
                * Stem has subdirectory path.  dbuff has selected path.
                * Create a new dname with stem and dbuff.
                */

               assert( strlen( stem ) + strlen( dbuff ) < MAX_COLS );

               strcpy( dname, stem );
               strcat( dname, dbuff );
               len = strlen( dname );
               strcpy( dbuff, dname );

               /*
                * The last character in dbuff is '\', because we append the
                *  '\' to every directory entry in the file list.  Replace
                *  it with a NULL char then we will have a valid path name.
                */
               dbuff[len-1] = '\0';

               /*
                * now let's change to the selected subdirectory.
                */
               rc = set_current_directory( dbuff );
               if (rc == OK) {

                  /*
                   * Every time we change directories, we need to get the
                   *  current directory so we will be sure to have the
                   *  correct path.
                   */
                  rc = get_current_directory( dbuff, drive );
                  if (rc == OK) {

                     assert( strlen( prefix ) + strlen( dbuff ) < MAX_COLS );

                     strcpy( dname, prefix );
                     strcat( dname, dbuff );
                     change_directory = TRUE;
                  }
               }

               /*
                * Validate the new path and allocate memory for the
                *  matching files.
                */
               if (rc == OK)
                  rc = validate_path( dname, stem );
               if (rc == OK) {
                  rc = my_findfirst( &dta, dname, NORMAL | READ_ONLY | HIDDEN |
                                  SYSTEM | SUBDIRECTORY | ARCHIVE );
                  if (rc != ERROR) {
                     for (cnt=1; (rc = my_findnext( &dta )) == OK;)
                        ++cnt;
                     flist = (FTYPE *)calloc( cnt, sizeof(FTYPE) );
                  }
               }
               if (flist == NULL || rc == ERROR) {
                  stop = TRUE;
                  rc = ERROR;
               }
            } else {

               /*
                * user selected a file.  store fname in dname and return.
                */
               rc = OK;
               stop = TRUE;

               assert( strlen( stem ) + strlen( dbuff ) < MAX_COLS );

               strcpy( dname, stem );
               strcat( dname, dbuff );
            }
         }
      }

      /*
       * Go back to the current directory if needed.
       */
      if (change_directory)
         set_current_directory( cwd );
      if (window != NULL)
         redraw_screen( window );
   } else {
      /*
       * out of memory
       */
      error( WARNING,  window != NULL ? window->bottom_line : g_display.nlines,
             dir3 );
      rc = ERROR;
   }
   return( rc );
}