Пример #1
0
/*FUNCTION*/
int hook_truncate(pExecuteObject pEo,
                  FILE *fp,
                  long lNewFileSize
  ){
/*noverbatim
CUT*/
  return file_truncate(fp,lNewFileSize);
  }
Пример #2
0
/* convert file using UNIX98 iconv functions
   returns 0 on success, nonzero error code otherwise
   when iconv implementation is not transitive (ICONV_TRANSITIVE is not
   defined), it may help to perform conversion via Unicode, so we try it too
   (probably UCS-2/ISO-10646, but maybe UTF-8---whatever has been detected
   at configure time) */
int
convert_iconv(File *file,
              EncaEncoding from_enc)
{
  static int ascii = ENCA_CS_UNKNOWN;
  File *tempfile = NULL;
  int err;
  iconv_t icd;

  if (!enca_charset_is_known(ascii)) {
    ascii = enca_name_to_charset("ascii");
    assert(enca_charset_is_known(ascii));
  }

  /* When iconv doesn't know the encodings, it can't convert between them.
   * We also don't try conversion to ASCII, it can only damage the files and
   * upset users, nothing else.
   * And fail early on really silly surfaces. */
  if (!enca_charset_name(from_enc.charset, ENCA_NAME_STYLE_ICONV)
      || (enca_charset_is_known(options.target_enc.charset)
          && !enca_charset_name(options.target_enc.charset,
                                ENCA_NAME_STYLE_ICONV))
      || options.target_enc.charset == ascii
      || !acceptable_surface(from_enc)
      || !acceptable_surface(options.target_enc))
    return ERR_CANNOT;

  /* Is the conversion possible? */
  if (do_iconv_open(from_enc, options.target_enc, &icd) != 0)
    return ERR_CANNOT;

  /* Since iconv doesn't recode files in place, we make a temporary file
     and copy contents of file fname to it.
     save the current content first, then copy the rest.
     When the file is stdin, fake-reopen it to stdout. */
  err = ERR_IOFAIL;
  if ((tempfile = file_temporary(file->buffer, 1))
      && file_write(tempfile) != -1
      && copy_and_convert(file, tempfile, NULL) == 0
      && (!file->name || file_seek(file, 0, SEEK_SET) == 0)
      && file_seek(tempfile, 0, SEEK_SET) == 0
      && (!file->name || file_truncate(file, 0) == 0)
      && (file->name || (file_close(file) == 0
                         && file_open(file, "wb") == 0))) {
    /* Create the second buffer when we don't have any yet
      but don't make it unnecessarily large, system default suffices */
    if (!buffer_iconv)
      buffer_iconv = buffer_new(0);
    tempfile->buffer = buffer_iconv;

    err = iconv_one_step(tempfile, file, icd);
  }

  file_free(tempfile);
  do_iconv_close(icd);
  return err;
}
Пример #3
0
int sys_truncate(int fd)
{
	struct file *file = fd_get_file(fd);
	int r = -1;
	if (!file)
		return -1;
	r = file_truncate(file);
	put_file(file);
	return r;
}
Пример #4
0
int dir_truncateat(struct dir *dir, const char *filename, uint64_t size)
{
	struct file *file = file_open_rw(dir, filename);
	if (file == NULL) {
		return -1;
	}
	int r = file_truncate(file, size);
	file_close(file);
	return r;
}
Пример #5
0
static void file_truncate_file(struct file_info *file)
{
	int fd;
	char *path;

	path = dir_path(file->links->parent, file->links->name);
	fd = open(path, O_WRONLY);
	CHECK(fd != -1);
	file_truncate(file, fd);
	CHECK(close(fd) != -1);
	free(path);
}
Пример #6
0
int sys_ftruncate(int fd, off_t len)
{
  int r = -EBADF;
  file_t* f = file_get(fd);

  if (f)
  {
    r = file_truncate(f, len);
    file_decref(f);
  }

  return r;
}
Пример #7
0
/* Randomly select something to do with an open file */
static void operate_on_open_file(struct fd_info *fdi)
{
	size_t r;

	r = tests_random_no(1000);
	if (shrink && r == 0)
		file_truncate(fdi->file, fdi->fd);
	else if (r < 21)
		file_close(fdi);
	else if (shrink && r < 121 && !fdi->file->deleted)
		file_delete(fdi->file);
	else
		file_write(fdi->file, fdi->fd);
}
Пример #8
0
int file_appendv(struct file *file, const struct iovec *iov, int iovcnt,
		 uint64_t file_size)
{
	int i;
	uint64_t len = 0;
	for (i=0; i < iovcnt; i++) {
		len += iov[i].iov_len;
	}

	int r = writev(file->fd, iov, iovcnt);
	FILETRACE(file, r, "writev(\"%s\", %llu)", file->pathname,
		  (unsigned long long)len);
	/* TODO: are we really sure writev won't write in chunks? */
	if (r < 0 || (unsigned)r != len) {
		file_truncate(file, file_size);
		return -1;
	}
	return len;
}
Пример #9
0
/* Randomly select something to do with an open file */
static void operate_on_open_file(struct fd_info *fdi)
{
	size_t r;

	r = tests_random_no(1000);
	if (shrink && r < 5)
		file_truncate(fdi->file, fdi->fd);
	else if (r < 21)
		file_close(fdi);
	else if (shrink && r < 121 && !fdi->file->deleted)
		file_delete(fdi->file);
	else {
		file_write(fdi->file, fdi->fd);
		if (r >= 999) {
			if (tests_random_no(100) >= 50)
				CHECK(fsync(fdi->fd) != -1);
			else
				CHECK(fdatasync(fdi->fd) != -1);
		}
	}
}
Пример #10
0
/*
 * -EINVAL, -EEXIST, -ENOENT, -ENOTDIR, -ENAMETOOLONG, -EISDIR
 */
int sys_open(const char *path, int flags, __unused mode_t mode)
{
	int64_t parent_inum, inum, fd;
	struct file *file;
	const char *child;

	if ((flags & O_ACCMODE) == 0)
		return -EINVAL;
	if ((flags & O_TRUNC) &&
	    (flags & O_APPEND || (flags & O_WRONLY) == 0))
		return -EINVAL;

	inum = name_i(path);
	if (flags & O_CREAT) {
		if (inum > 0 && (flags & O_EXCL))
			return -EEXIST;
		if (inum == -ENOENT) {
			parent_inum = path_parent_child(path, &child, NO_DIR);
			inum = (parent_inum < 0) ? parent_inum :
				file_new(parent_inum, child, EXT2_FT_REG_FILE);
		}
	}
	if (inum < 0)
		return inum;
	if (is_dir(inum))
		return -EISDIR;

	file = kmalloc(sizeof(*file));
	file_init(file, inum, flags);
	fd = unrolled_insert(&current->fdtable, file);
	if (flags & O_TRUNC)
		file_truncate(inum);
	if (flags & O_APPEND)
		assert(sys_lseek(fd, 0, SEEK_END) > 0);
	return fd;
}
Пример #11
0
int net_delroute_ipv6(net_ipv6addr_t target, net_ipv6addr_t netmask)
{
  struct route_match_ipv6_s match;
  struct net_route_ipv6_s route;
  struct file fshandle;
  off_t filesize;
  ssize_t nwritten;
  ssize_t nread;
  off_t pos;
  int nentries;
  int index;
  int ret;

  /* We must lock out other accesses to the routing table while we remove
   * entry
   */

  ret = net_lockroute_ipv6();
  if (ret < 0)
    {
       nerr("ERROR: net_lockroute_ipv6 failed: %d\n", ret);
       return ret;
    }

  /* Get the size of the routing table (in entries) */

  nentries = net_routesize_ipv6();
  if (nentries < 0)
    {
      ret = nentries;
      goto errout_with_lock;
    }
  else if (nentries == 0)
    {
      ret = -ENOENT;
      goto errout_with_lock;
    }

  /* Set up the comparison structure */

  net_ipv6addr_copy(match.target, target);
  net_ipv6addr_copy(match.netmask, netmask);
  match.index = 0;

  /* Then find the index into the routing table where the match can be found */

  ret = net_foreachroute_ipv6(net_match_ipv6, &match);
  if (ret < 0)
    {
      /* And error occurred */

      ret = ret;
      goto errout_with_lock;
    }
  else if (ret == 0)
    {
      /* No match found */

      ret = -ENOENT;
      goto errout_with_lock;
    }

  /* Open the routing table for read/write access */

  ret = net_openroute_ipv6(O_RDWR, &fshandle);
  if (ret < 0)
    {
      nerr("ERROR: Could not open IPv6 routing table: %d\n", ret);
      goto errout_with_lock;
    }

#ifdef CONFIG_ROUTE_IPv6_CACHEROUTE
  /* We are committed to modifying the routing table.  Flush the in-memory
   * routing table cache.
   */

  net_flushcache_ipv6();
#endif

  /* Loop, copying each entry, to the previous entry thus removing the entry
   * to be deleted.
   */

  for (index = match.index + 1; index < nentries; index++)
    {
      /* Seek to the current entry to be moved */

      pos = net_seekroute_ipv6(&fshandle, index);
      if (pos < 0)
        {
          nerr("ERROR: net_readroute_ipv6 failed: %ld\n", (long)pos);
          ret =(int)pos;
          goto errout_with_fshandle;
        }

      /* Read the routing table entry at this position */

      nread = net_readroute_ipv6(&fshandle, &route);
      if (nread < 0)
        {
          nerr("ERROR: net_readroute_ipv6 failed: %ld\n", (long)nread);
          ret = (int)nread;
          goto errout_with_fshandle;
        }
      else if (nread == 0)
        {
          nerr("ERROR: Unexpected end of file\n");
          ret = -EINVAL;
          goto errout_with_fshandle;
        }

      /* Seek to the previous entry to be replaced */

      pos = net_seekroute_ipv6(&fshandle, index - 1);
      if (pos < 0)
        {
          nerr("ERROR: net_readroute_ipv6 failed: %ld\n", (long)pos);
          ret =(int)pos;
          goto errout_with_fshandle;
        }

      /* Now write the record to its new location */

      nwritten = net_writeroute_ipv6(&fshandle, &route);
      if (nwritten < 0)
        {
          nerr("ERROR: net_readroute_ipv6 failed: %ld\n", (long)nwritten);
          ret = (int)nwritten;
          goto errout_with_fshandle;
        }
    }

  /* Now truncate the one duplicate entry at the end of the file.  This may
   * result in a zero length file.
   */

  filesize = (nentries - 1) * sizeof(struct net_route_ipv6_s);
  ret = file_truncate(&fshandle, filesize);

errout_with_fshandle:
  (void)net_closeroute_ipv6(&fshandle);

errout_with_lock:
  (void)net_unlockroute_ipv6();
  return ret;
}
Пример #12
0
/* convert file using GNU recode library
   returns 0 on success, nonzero error code otherwise */
int
convert_recode(File *file,
               EncaEncoding from_enc)
{
  RECODE_REQUEST request;
  RECODE_TASK task;
  File *tempfile = NULL;
  bool success;
  const char *encreq;

  /* Allocate librecode outer if we are called first time. */
  if (outer == NULL) {
    if ((outer = recode_new_outer(false)) == NULL) {
      fprintf(stderr, "%s: recode library doesn't like us\n",
                      program_name);
      return ERR_LIBCOM;
    }
  }

  /* Construct recode request string,
     try to mimic surfaceless converter now. */
  {
    EncaEncoding enc;

    enc.charset = from_enc.charset;
    enc.surface = from_enc.surface | ENCA_SURFACE_REMOVE;
    encreq = format_request_string(enc, options.target_enc,
                                   ENCA_SURFACE_EOL_LF);
  }
  /* Create a recode request from it. */
  request = get_recode_request(encreq);
  if (request == NULL)
    return ERR_CANNOT;

  /* Now we have to distinguish between file and stdin, namely because
   * in case of stdin, it's first part is already loaded in the buffer. */
  if (file->name != NULL) {
    /* File is a regular file.
       Since recode doesn't recode files in place, we make a temporary file
       and copy contents of file fname to it. */
    if (file_seek(file, 0, SEEK_SET) != 0)
      return ERR_IOFAIL;
    file->buffer->pos = 0;

    if ((tempfile = file_temporary(file->buffer, 1)) == NULL
        || copy_and_convert(file, tempfile, NULL) != 0
        || file_seek(file, 0, SEEK_SET) != 0
        || file_seek(tempfile, 0, SEEK_SET) != 0
        || file_truncate(file, 0) != 0) {
      file_free(tempfile);
      return ERR_IOFAIL;
    }

    /* Create a task from the request. */
    task = recode_new_task(request);
    task->fail_level = enca_recode_fail_level;
    task->abort_level = RECODE_SYSTEM_ERROR;
    task->input.name = NULL;
    task->input.file = tempfile->stream;
    task->output.name = NULL;
    task->output.file = file->stream;

    /* Now run conversion temporary file -> original. */
    success = recode_perform_task(task);

    /* If conversion wasn't successfull, original file is probably damaged
       (damned librecode!) try to restore it from the temporary copy. */
    if (!success) {
      if (task->error_so_far >= RECODE_SYSTEM_ERROR) {
        fprintf(stderr, "%s: librecode probably damaged file `%s'. "
                        "Trying to recover... ",
                        program_name,
                        file->name);
        tempfile->buffer->pos = 0;
        if (file_seek(tempfile, 0, SEEK_SET) != -1
            && file_seek(file, 0, SEEK_SET) != -1
            && file_truncate(file, file->size) == 0
            && copy_and_convert(tempfile, file, NULL) == 0)
          fprintf(stderr, "succeeded.\n");
        else
          fprintf(stderr, "failed\n");
      }
      else
        print_recode_warning(task->error_so_far, file->name);
    }

    recode_delete_task(task);
    file_free(tempfile);
  }
  else {
    /* File is stdin.
       First recode begining saved in io_buffer, then append rest of stdin. */
    enum recode_error errmax = RECODE_NO_ERROR;

    /* Create a task from the request.
     * Set it up for buffer -> stdout conversion */
    task = recode_new_task(request);
    task->fail_level = enca_recode_fail_level;
    task->abort_level = RECODE_SYSTEM_ERROR;
    task->input.name = NULL;
    task->input.file = NULL;
    task->input.buffer = (char*)file->buffer->data;
    task->input.cursor = (char*)file->buffer->data;
    task->input.limit = (char*)file->buffer->data + file->buffer->pos;
    task->output.name = NULL;
    task->output.file = stdout;

    success = recode_perform_task(task);
    if (!success) {
      if (task->error_so_far >= RECODE_SYSTEM_ERROR) {
        fprintf(stderr, "%s: librecode probably damaged `%s'. "
                        "No way to recover in a pipe.\n",
                        program_name,
                        ffname_r(NULL));
        recode_delete_task(task);
        return ERR_IOFAIL;
      }
      else
        errmax = task->error_so_far;
    }
    recode_delete_task(task);

    /* Create a task from the request.
     * Set it up for stdin -> stdout conversion */
    task = recode_new_task(request);
    task->fail_level = enca_recode_fail_level;
    task->abort_level = RECODE_SYSTEM_ERROR;
    task->input.name = NULL;
    task->input.file = stdin;
    task->output.name = NULL;
    task->output.file = stdout;

    success = recode_perform_task(task);
    if (!success) {
      if (task->error_so_far >= RECODE_SYSTEM_ERROR) {
        fprintf(stderr, "%s: librecode probably damaged `%s'. "
                        "No way to recover in a pipe.\n",
                        program_name,
                        ffname_r(NULL));
        recode_delete_task(task);
        return ERR_IOFAIL;
      }
      else {
        if (errmax < task->error_so_far)
          errmax = task->error_so_far;
      }
    }
    if (errmax >= enca_recode_fail_level)
      print_recode_warning(errmax, ffname_r(NULL));

    recode_delete_task(task);
  }

  /* return ERR_IOFAIL on failure since it means file-related problems */
  return success ? ERR_OK : ERR_IOFAIL;
}
Пример #13
0
/* perform one conversion step using conversion descriptor icd
   reading for file_from and putting result to file_to */
static int
iconv_one_step(File *file_from,
               File *file_to,
               iconv_t icd)
{
  size_t size_from, size_to, n;
  char *p_from, *p_to;
  int hit_eof;

  /* convert */
  do {
    /* read to io_buffer */
    if (file_read(file_from) == -1)
      return ERR_IOFAIL;

    p_from = (char*)file_from->buffer->data;
    size_from = file_from->buffer->pos;
    hit_eof = (ssize_t)file_from->buffer->size > file_from->buffer->pos;
    /* convert without reading more data until io_buffer is exhausted or some
       error occurs */
    do {
      p_to = (char*)file_to->buffer->data;
      size_to = file_to->buffer->size;
      n = iconv(icd,
                (ICONV_CONST char**)&p_from, &size_from,
                &p_to, &size_to);
      file_to->buffer->pos = file_to->buffer->size - size_to;
      if (n != (size_t)-1 || errno != E2BIG)
        break;

      if (file_write(file_to) == -1)
        return ERR_IOFAIL;

    } while (1);

    if (n == (size_t)-1) {
      /* EINVAL means some multibyte sequence has been splitted---that's ok,
         move it to the begining and go on */
      if (errno == EINVAL && !hit_eof) {
        memmove(file_from->buffer->data, p_from, size_from);
        file_from->buffer->pos = size_from;
      }
      else {
        /* but other errors are critical, conversion and try to recover  */
        fprintf(stderr, "%s: Iconv conversion error on `%s': %s\n",
                        program_name,
                        ffname_r(file_from->name),
                        strerror(errno));
        if (file_from->name && file_to->name) {
          Buffer *buf;
          int err;

          /* regular file */
          fprintf(stderr, "Trying to recover... ");
          if (file_seek(file_from, 0, SEEK_SET) != 0
              || file_seek(file_to, 0, SEEK_SET) != 0
              || file_truncate(file_to, file_to->size) != 0) {
            fprintf(stderr, "failed\n");
            return ERR_IOFAIL;
          }
          file_from->buffer->pos = 0;
          buf = file_to->buffer;
          file_to->buffer = file_from->buffer;
          err = copy_and_convert(file_from, file_to, NULL);
          file_to->buffer = buf;

          if (err != 0) {
            fprintf(stderr, "failed\n");
            return ERR_IOFAIL;
          }
          fprintf(stderr, "succeeded.\n");
        }
        else {
          fprintf(stderr, "No way to recover in a pipe.\n");
          return ERR_IOFAIL;
        }

        return ERR_MALFORM;
      }
    }
    else file_from->buffer->pos = 0;

    /* write the remainder */
    if (file_write(file_to) == -1)
      return ERR_IOFAIL;

  } while (!hit_eof);

  /* file might end with an unfinished multibyte sequence */
  if (size_from > 0) {
    fprintf(stderr, "%s: File `%s' seems to be truncated, "
                    "the trailing incomplete multibyte sequence "
                    "has been lost\n",
                    program_name,
                    ffname_r(file_from->name));
    return ERR_MALFORM;
  }

  return ERR_OK;
}
Пример #14
0
bool filesys_remove (const char *path){
	struct block *d = NULL;
	struct ext2_meta_data *meta = NULL;
	char *parent = NULL, *name = NULL;
	struct directory *parent_dir = NULL;
	struct file *parent_file = NULL, *file = NULL;
	struct directory *directory_data = NULL;
	struct directory *file_entry = NULL, *last_entry = NULL;
	uint32_t file_size = 0, bytes_read = 0;
	bool success = false;

	ASSERT(path != NULL && strlen(path) > 0);

	// Get device
	d = block_get_role (BLOCK_FILESYS);
	ASSERT(d != NULL);
	meta = ext2_get_meta(d);
	ASSERT(meta != NULL && meta->sb != NULL);

	// open file
	file = filesys_open(path);
	if(file == NULL){ // file does not exists
		printf("filesys_remove: %s does not exist!.\n",path);
		goto cleanup;
	}
	
	//Check file type
	if(file->dir->file_type != EXT2_FT_REG_FILE){
		printf("filesys_remove %s is not a regular file.\n",path);
		goto cleanup;
	}

	// Split path
	filesys_split_path(path, &parent, &name);
	ASSERT(parent != NULL && name != NULL);

	// Get parent directory
	parent_dir = dir_lookup(d,parent);
	if(parent_dir == NULL){
		printf("Directory %s does not exist.\n",parent);
		goto cleanup;
	}
	// Check parent type
	if(parent_dir -> file_type != EXT2_FT_DIR){
		printf("Path %s is not a directory.\n",parent);
		goto cleanup;
	}

	// Get directory file
	parent_file = filesys_open(parent);
	if(parent_file == NULL) goto cleanup;

	// Get parent directory data
	file_size = parent_file->inode->i_size;
	directory_data = kmalloc(file_size);
	bytes_read = file_read(parent_file,directory_data,file_size);
	if(bytes_read != file_size) goto cleanup;
	
	// Get file directory entry
	file_entry = directory_data;
	while (file_entry != NULL 
		&& memcmp(file_entry->name,name,file_entry->name_len) != 0
		&& (uint8_t*)file_entry+file_entry->rec_len < (uint8_t*)directory_data+file_size){
		last_entry = file_entry;
		file_entry = dir_get_next(file_entry);
	}

	// check if file entry if found.
	if( (uint8_t*)file_entry >= (uint8_t*)directory_data+file_size
		|| memcmp(file_entry->name,name,file_entry->name_len) != 0 )
		goto cleanup;

	// Truncate file to zero length
	// Aka. Free blocks
	file_truncate(file,0);

	// Zero inode
	memset(file->inode,0,sizeof(struct inode));
	ext2_write_inode(d,file->dir->inode,file->inode);

	// Free inode
	freemap_free_inode(file_entry->inode);
	
	// Delete directory record
	// Use last entry record length to skip file entry
	if(last_entry->inode != 0)
		last_entry->rec_len += file_entry->rec_len;

	// Write directory file
	file_write_at(parent_file,directory_data,file_size,0);
	
	// file deleted successfully.
	success = true;

cleanup:
	// close file
	if(file != NULL) file_close(file);
	if(parent_file != NULL) file_close(parent_file);
	// release memory
	if(parent != NULL) kfree(parent);
	if(name != NULL) kfree(name);
	if(parent_dir != NULL) kfree(parent_dir);
	if(directory_data != NULL) kfree(directory_data);
	
	return success;
}
Пример #15
0
int
config_write(struct config *conf,
             const char    *filename)
{
   struct file_descriptor *fd;
   struct KeyValuePair *e;
   uint64 offset;
   int res;

   res = 0;
   fd = NULL;
   ASSERT(conf);
   if (filename == NULL) {
      ASSERT(conf->fileName);
   } else {
      free(conf->fileName);
      conf->fileName = safe_strdup(filename);
   }
   res = file_open(conf->fileName, FALSE, FALSE, &fd);
   if (res != 0) {
      Log(LGPFX" Failed to open config '%s': %s (%d)\n",
          filename, strerror(res), res);
      return res;
   }

   res = file_truncate(fd, 0);
   if (res != 0) {
      Log(LGPFX" Failed to truncate '%s': %s (%d)\n",
          filename, strerror(res), res);
      goto exit;
   }

   e = conf->list;
   offset = 0;

   while (e) {
      size_t numBytes;
      char *s = NULL;

      if (e->save == 0) {
         Log(LGPFX" not writing key '%s'\n", e->key);
         e = e->next;
         continue;
      }

      switch (e->type) {
      case CONFIG_KV_INT64:
         s = safe_asprintf("%s = \"%lld\"\n", e->key, e->u.val);
         break;
      case CONFIG_KV_BOOL:
         s = safe_asprintf("%s = \"%s\"\n", e->key, e->u.trueOrFalse ? "TRUE" : "FALSE");
         break;
      default:
         ASSERT(e->type == CONFIG_KV_UNKNOWN || e->type == CONFIG_KV_STRING);
         if (e->u.str) {
            s = safe_asprintf("%s = \"%s\"\n", e->key, e->u.str);
         }
      }

      if (s) {
         numBytes = 0;
         res = file_pwrite(fd, offset, s, strlen(s), &numBytes);
         if (res != 0 || numBytes != strlen(s)) {
            Log(LGPFX" Failed to pwrite %zd bytes: %s (%d)\n",
                strlen(s), strerror(res), res);
            free(s);
            goto exit;
         }
         offset += numBytes;
         free(s);
      }
      e = e->next;
   }

exit:
   if (res != 0) {
      // XXX: consider cleaning-up.
   }
   if (fd) {
      file_close(fd);
   }
   return res;
}
Пример #16
0
int gsiftp_truncate(int handle, LONGLONG filesize)
{
  return file_truncate(handle, filesize);
}