예제 #1
0
static void get_log_file_tail(const char *despath, const char *srcpath,
				const int lines)
{
	char *start;
	int start_line;
	int file_lines;
	struct mm_file_t *mfile;
	int ret;

	mfile = mmap_file(srcpath);
	if (!mfile) {
		LOGE("mmap (%s) failed, error (%s)\n", srcpath,
		     strerror(errno));
		return;
	}
	file_lines = mm_count_lines(mfile);
	if (file_lines <= 0) {
		LOGW("get lines (%s, %d) failed\n", mfile->path, file_lines);
		goto unmap;
	}
	start_line = MAX(file_lines - lines, 0) + 1;
	start = mm_get_line(mfile, start_line);
	ret = overwrite_file(despath, start);
	if (ret < 0) {
		LOGE("create file with (%s, %p) failed, error (%s)\n",
		     despath, start, strerror(errno));
		goto unmap;
	}

unmap:
	unmap_file(mfile);
}
예제 #2
0
파일: mmap_write.c 프로젝트: CarterTsai/rr
int main(void) {
  size_t num_bytes = sysconf(_SC_PAGESIZE);
  int fd = open(DUMMY_FILE, O_CREAT | O_EXCL | O_RDWR, 0600);
  int* rpage;
  size_t i;

  test_assert(fd >= 0);

  overwrite_file(DUMMY_FILE, num_bytes);

  rpage = mmap(NULL, num_bytes, PROT_READ, MAP_SHARED, fd, 0);
  atomic_printf("rpage:%p\n", rpage);
  test_assert(rpage != (void*)-1);

  for (i = 0; i < num_bytes / sizeof(magic); ++i) {
    test_assert(rpage[i] == magic);
  }

  lseek(fd, 0, SEEK_SET);

  for (i = 0; i < num_bytes / sizeof(i); ++i) {
    int written;

    write(fd, &i, sizeof(i));
    written = rpage[i];
    atomic_printf("(wrote %d, read %d)", (int)i, written);
    test_assert(written == (ssize_t)i);
  }

  atomic_puts(" done");
  return 0;
}
예제 #3
0
파일: mremap.c 프로젝트: KurSh/rr
int main(int argc, char *argv[]) {
	size_t num_bytes = sysconf(_SC_PAGESIZE);
	int fd = open(DUMMY_FILE, O_CREAT | O_EXCL | O_RDWR, 0600);
	int* wpage;
	int* rpage;
	int* old_wpage;

	test_assert(fd >= 0);

	overwrite_file(DUMMY_FILE, 2 * num_bytes);

	wpage = mmap(NULL, num_bytes, PROT_READ | PROT_WRITE,
		     MAP_SHARED, fd, 0);
	rpage = mmap(NULL, num_bytes, PROT_READ,
		     MAP_SHARED, fd, 0);
	atomic_printf("wpage:%p rpage:%p\n", wpage, rpage);
	test_assert(wpage != (void*)-1 && rpage != (void*)-1
		    && rpage != wpage);

	/* NB: this is a bad test in that it assumes
	 * ADDR_COMPAT_LAYOUT address-space allocation semantics.  If
	 * this test is run "normally", it will most likely fail this
	 * assertion.  To fix this we'd need to dyanmically determine
	 * which page is mapped just before the other and then remap
	 * that page. */
	test_assert((byte*)rpage - (byte*)wpage == num_bytes);

	check_mapping(rpage, wpage, num_bytes / sizeof(*wpage));

	overwrite_file(DUMMY_FILE, 2 * num_bytes);

	old_wpage = wpage;
	wpage = mremap(old_wpage, num_bytes, 2 * num_bytes, MREMAP_MAYMOVE);
	atomic_printf("remapped wpage:%p\n", wpage);
	test_assert(wpage != (void*)-1 && wpage != old_wpage);

	check_mapping(rpage, wpage, num_bytes / sizeof(*wpage));

	atomic_puts(" done");

	return 0;
}
예제 #4
0
 SILICIUM_USE_RESULT
 inline boost::system::error_code write_file(Si::native_path_string name, Si::memory_range data)
 {
     Si::error_or<Si::file_handle> const file = overwrite_file(name);
     if (file.is_error())
     {
         return file.error();
     }
     file_sink sink(file.get().handle);
     return Si::append(sink, file_sink_element{data});
 }
예제 #5
0
int is_boot_id_changed(void)
{
	void *boot_id;
	void *logged_boot_id;
	char logged_boot_id_path[PATH_MAX];
	unsigned long size;
	struct sender_t *crashlog;
	int res;
	int result = 1; /* returns changed by default */

	crashlog = get_sender_by_name("crashlog");
	if (!crashlog)
		return result;

	res = read_file(BOOTID_NODE, &size, &boot_id);
	if (res == -1 || !size)
		return result;

	res = snprintf(logged_boot_id_path, sizeof(logged_boot_id_path),
		       "%s/%s", crashlog->outdir, BOOTID_LOG);
	if (s_not_expect(res, sizeof(logged_boot_id_path)))
		goto out;

	if (file_exists(logged_boot_id_path)) {
		res = read_file(logged_boot_id_path, &size, &logged_boot_id);
		if (res == -1 || !size)
			goto out;

		if (!strcmp((char *)logged_boot_id, (char *)boot_id))
			result = 0;

		free(logged_boot_id);
	}

	if (result)
		overwrite_file(logged_boot_id_path, boot_id);
out:
	free(boot_id);
	return result;
}
예제 #6
0
파일: keytab.c 프로젝트: Stanford/wallet
/*
 * Given a remctl object, the Kerberos context, the name of a keytab object,
 * and a file name, call the correct wallet commands to download a keytab and
 * write it to that file.  Returns the status or 255 on an internal error.
 */
int
get_keytab(struct remctl *r, krb5_context ctx, const char *type,
           const char *name, const char *file, const char *srvtab)
{
    const char *command[5];
    char *tempfile;
    char *data = NULL;
    size_t length = 0;
    int status;

    command[0] = type;
    command[1] = "get";
    command[2] = "keytab";
    command[3] = name;
    command[4] = NULL;
    status = run_command(r, command, &data, &length);
    if (status != 0)
        return status;
    if (data == NULL) {
        warn("no data returned by wallet server");
        return 255;
    }
    if (access(file, F_OK) == 0) {
        xasprintf(&tempfile, "%s.new", file);
        overwrite_file(tempfile, data, length);
        if (srvtab != NULL)
            write_srvtab(ctx, srvtab, name, tempfile);
        merge_keytab(ctx, tempfile, file);
        if (unlink(tempfile) < 0)
            sysdie("unlink of temporary keytab file %s failed", tempfile);
        free(tempfile);
    } else {
        write_file(file, data, length);
        if (srvtab != NULL)
            write_srvtab(ctx, srvtab, name, file);
    }
    return 0;
}
예제 #7
0
파일: sunlink.c 프로젝트: aosm/srm
int sunlink(const char *path) {
  struct stat statbuf;
  struct statfs fs_stats;
#if HAVE_LINUX_EXT2_FS_H
  int flags = 0;
#endif
  int fmode = (options & OPT_VERIFY) ? O_RDWR : O_WRONLY;
  struct flock flock;

  if (lstat(path, &statbuf) == -1) 
    return -1;
  if (!S_ISREG(statbuf.st_mode))
    return rename_unlink(path);

  if (statbuf.st_nlink > 1) {
    rename_unlink(path);
    errno = EMLINK;
    return -1;
  }

  if ( (file = open(path, fmode)) == -1) /* BSD doesn't support O_SYNC */
    return -1;

  if (fcntl(file, F_WRLCK, &flock) == -1) {
    close(file);
    return -1;
  }

  if (fstatfs(file, &fs_stats) == -1 && errno != ENOSYS) {
    close(file);
    return -1;
  }

  /* warn when trying to overwrite files on a non-local fs,
     since there are no guarantees that writes will not be
     buffered on the server, or will overwrite the same spot. */
  if (options & OPT_V) {
    if ((fs_stats.f_flags & MNT_LOCAL) == 0) {
      printf("warning: %s is not on a local filesystem!\n", path);
      fflush(stdout);
    }
  }

#if HAVE_LINUX_EXT2_FS_H
  if (fs_stats.f_type == EXT2_SUPER_MAGIC) 
    if (ioctl(file, EXT2_IOC_GETFLAGS, &flags) == -1) {
      close(file);
      return -1;
    } 

  if ( (flags & EXT2_UNRM_FL) || (flags & EXT2_IMMUTABLE_FL) ||
      (flags & EXT2_APPEND_FL) )  
    {
      close(file);
      errno = EPERM;
      return -1;
    }

#endif /* HAVE_LINUX_EXT2_FS_H */

/* chflags(2) turns out to be a different system call in every BSD
   derivative. The important thing is to make sure we'll be able to
   unlink it after we're through messing around. Unlinking it first
   would remove the need for any of these checks, but would leave the
   user with no way to overwrite the file if the process was
   interrupted during the overwriting. So, instead we assume that the
   open() above will fail on immutable and append-only files and try
   and catch only platforms supporting NOUNLINK here.

   FreeBSD - supports NOUNLINK (from 4.4 on?)
   MacOS X - doesn't support NOUNLINK (as of 10.3.5)
   OpenBSD - doesn't support NOUNLINK (as of 3.1)
   Tru64   - unknown
   
   Note: unsupported flags are defined as 0 at the top of this file,
   so a specific platform check is not required here.
*/

#if HAVE_CHFLAGS
  if ((statbuf.st_flags & UF_IMMUTABLE) || 
      (statbuf.st_flags & UF_APPEND) ||
      (statbuf.st_flags & UF_NOUNLINK) || 
      (statbuf.st_flags & SF_IMMUTABLE) ||
      (statbuf.st_flags & SF_APPEND) ||
      (statbuf.st_flags & SF_NOUNLINK)) 
    {
      close(file);
      errno = EPERM;
      return -1;
    }
#endif /* HAVE_CHFLAGS */

  if (init_write_buffer(&statbuf, &fs_stats) == -1) {
    close(file);
    return -1;
  }
#if defined F_NOCACHE
  /* before performing file I/O, set F_NOCACHE to prevent caching */
  (void)fcntl(file, F_NOCACHE, 1);
#endif

  overwrite_file();

#if HAVE_LINUX_EXT2_FS_H
  ioctl(file, EXT2_IOC_SETFLAGS, EXT2_SECRM_FL);
#endif

  if ((options & OPT_N) == 0) {
    if (ftruncate(file, 0) == -1) {
      close(file);
      return -1;
    }
  }

  close(file);

#if __APPLE__
  /* Also overwrite the file's resource fork, if present. */
  {
    static const char *RSRCFORKSPEC = "/..namedfork/rsrc";
    size_t rsrc_fork_size;
    size_t rsrc_path_size = strlen(path) + strlen(RSRCFORKSPEC) + 1;
    char *rsrc_path = (char *)alloca(rsrc_path_size);
    if (rsrc_path == NULL) {
      errno = ENOMEM;
      return -1;
    }
    if (snprintf(rsrc_path, MAXPATHLEN,
        "%s%s", path, RSRCFORKSPEC ) > MAXPATHLEN - 1) {
      errno = ENAMETOOLONG;
      return -1;
    }

    if (lstat(rsrc_path, &statbuf) != 0) {
      int err = errno;
      if (err == ENOENT || err == ENOTDIR) {
        rsrc_fork_size = 0;
      } else {
        return -1;
      }
    } else {
      rsrc_fork_size = statbuf.st_size;
    }

    if (rsrc_fork_size > 0) {

      if ((file = open(rsrc_path, O_WRONLY)) == -1) {
        return -1;
      }
      if (fcntl(file, F_WRLCK, &flock) == -1) {
        close(file);
        return -1;
      }

      if (options & OPT_V) {
        printf("removing %s\n", rsrc_path);
        fflush(stdout);
      }

      if (init_write_buffer(&statbuf, &fs_stats) == -1) {
        close(file);
        return -1;
      }
    #if defined F_NOCACHE
      /* before performing file I/O, set F_NOCACHE to prevent caching */
      (void)fcntl(file, F_NOCACHE, 1);
    #endif

      overwrite_file();

      if ((options & OPT_N) == 0) {
        if (ftruncate(file, 0) == -1) {
          close(file);
          return -1;
        }
      }
      close(file);
    }
  }
#endif /* __APPLE__ */

  if (options & OPT_N)
    return 0;

  return rename_unlink(path);
}
예제 #8
0
/**
 * Create a crashfile with given params.
 *
 * @param dir Where to generate crashfile.
 * @param event Event name.
 * @param hashkey Event id.
 * @param type Subtype of this event.
 * @param data* String obtained by get_data.
 */
void generate_crashfile(const char *dir,
			const char *event, size_t elen,
			const char *hashkey, size_t hlen,
			const char *type, size_t tlen,
			const char *data0, size_t d0len,
			const char *data1, size_t d1len,
			const char *data2, size_t d2len)
{
	char *buf;
	char *path;
	char *tail;
	char datetime[LONG_TIME_SIZE];
	char uptime[UPTIME_SIZE];
	int hours;
	const int fmtsize = 128;
	size_t ltlen;
	int n;
	int filesize;

	if (!dir || !event || !elen || !hashkey || !hlen ||
	    !type || !tlen)
		return;
	if (d0len > 0 && !data0)
		return;
	if (d1len > 0 && !data1)
		return;
	if (d2len > 0 && !data2)
		return;

	ltlen = get_current_time_long(datetime);
	if (!ltlen)
		return;
	n = get_uptime_string(uptime, &hours);
	if (n < 0)
		return;

	filesize = fmtsize + ltlen + n + elen + hlen + tlen + d0len + d1len +
		   d2len + strnlen(guuid, UUID_SIZE) +
		   strnlen(gbuildversion, BUILD_VERSION_SIZE);

	buf = malloc(filesize);
	if (buf == NULL) {
		LOGE("out of memory\n");
		return;
	}

	tail = cf_line(buf, "EVENT=", 6, event, elen);
	tail = cf_line(tail, "ID=", 3, hashkey, hlen);
	tail = cf_line(tail, "DEVICEID=", 9, guuid, strnlen(guuid, UUID_SIZE));
	tail = cf_line(tail, "DATE=", 5, datetime, ltlen);
	tail = cf_line(tail, "UPTIME=", 7, uptime, n);
	tail = cf_line(tail, "BUILD=", 6, gbuildversion,
		       strnlen(gbuildversion, BUILD_VERSION_SIZE));
	tail = cf_line(tail, "TYPE=", 5, type, tlen);

	if (d0len)
		tail = cf_line(tail, "DATA0=", 6, data0, d0len);
	if (d1len)
		tail = cf_line(tail, "DATA1=", 6, data1, d1len);
	if (d2len)
		tail = cf_line(tail, "DATA2=", 6, data2, d2len);
	tail = mempcpy(tail, "_END\n", 5);
	*tail = '\0';

	if (asprintf(&path, "%s/crashfile", dir) == -1) {
		LOGE("out of memory\n");
		free(buf);
		return;
	}

	if (overwrite_file(path, buf) != 0)
		LOGE("failed to new crashfile (%s), error (%s)\n", path,
		     strerror(errno));

	free(buf);
	free(path);
}