Exemple #1
0
static void test_sc_string_init__normal()
{
	char buf[1] = { 0xFF };

	sc_string_init(buf, sizeof buf);
	g_assert_cmpint(buf[0], ==, 0);
}
Exemple #2
0
const char *sc_umount_cmd(char *buf, size_t buf_size, const char *target,
			  int flags)
{
	sc_string_init(buf, buf_size);
	sc_string_append(buf, buf_size, "umount");

	if (flags & MNT_FORCE) {
		sc_string_append(buf, buf_size, " --force");
	}

	if (flags & MNT_DETACH) {
		sc_string_append(buf, buf_size, " --lazy");
	}
	if (flags & MNT_EXPIRE) {
		// NOTE: there's no real command line option for MNT_EXPIRE
		sc_string_append(buf, buf_size, " --expire");
	}
	if (flags & UMOUNT_NOFOLLOW) {
		// NOTE: there's no real command line option for UMOUNT_NOFOLLOW
		sc_string_append(buf, buf_size, " --no-follow");
	}
	if (target != NULL) {
		sc_string_append(buf, buf_size, " ");
		sc_string_append(buf, buf_size, target);
	}

	return buf;
}
Exemple #3
0
static void test_sc_string_init__NULL_buf()
{
	if (g_test_subprocess()) {
		sc_string_init(NULL, 1);

		g_test_message("expected sc_string_init not to return");
		g_test_fail();
		return;
	}
	g_test_trap_subprocess(NULL, 0, 0);
	g_test_trap_assert_failed();
	g_test_trap_assert_stderr("cannot initialize string, buffer is NULL\n");
}
Exemple #4
0
static void test_sc_string_append_char_pair__normal()
{
	char buf[16];
	size_t len;
	sc_string_init(buf, sizeof buf);

	len = sc_string_append_char_pair(buf, sizeof buf, 'h', 'e');
	g_assert_cmpstr(buf, ==, "he");
	g_assert_cmpint(len, ==, 2);
	len = sc_string_append_char_pair(buf, sizeof buf, 'l', 'l');
	g_assert_cmpstr(buf, ==, "hell");
	g_assert_cmpint(len, ==, 4);
	len = sc_string_append_char_pair(buf, sizeof buf, 'o', '!');
	g_assert_cmpstr(buf, ==, "hello!");
	g_assert_cmpint(len, ==, 6);
}
Exemple #5
0
static void test_sc_string_init__empty_buf()
{
	if (g_test_subprocess()) {
		char buf[1] = { 0xFF };

		sc_string_init(buf, 0);

		g_test_message("expected sc_string_init not to return");
		g_test_fail();
		return;
	}
	g_test_trap_subprocess(NULL, 0, 0);
	g_test_trap_assert_failed();
	g_test_trap_assert_stderr
	    ("cannot initialize string, buffer is too small\n");
}
Exemple #6
0
const char *sc_mount_opt2str(char *buf, size_t buf_size, unsigned long flags)
{
	unsigned long used = 0;
	sc_string_init(buf, buf_size);

#define F(FLAG, TEXT) do {                                         \
    if (flags & (FLAG)) {                                          \
      sc_string_append(buf, buf_size, #TEXT ","); flags ^= (FLAG); \
    }                                                              \
  } while (0)

	F(MS_RDONLY, ro);
	F(MS_NOSUID, nosuid);
	F(MS_NODEV, nodev);
	F(MS_NOEXEC, noexec);
	F(MS_SYNCHRONOUS, sync);
	F(MS_REMOUNT, remount);
	F(MS_MANDLOCK, mand);
	F(MS_DIRSYNC, dirsync);
	F(MS_NOATIME, noatime);
	F(MS_NODIRATIME, nodiratime);
	if (flags & MS_BIND) {
		if (flags & MS_REC) {
			sc_string_append(buf, buf_size, "rbind,");
			used |= MS_REC;
		} else {
			sc_string_append(buf, buf_size, "bind,");
		}
		flags ^= MS_BIND;
	}
	F(MS_MOVE, move);
	// The MS_REC flag handled separately by affected flags (MS_BIND,
	// MS_PRIVATE, MS_SLAVE, MS_SHARED)
	// XXX: kernel has MS_VERBOSE, glibc has MS_SILENT, both use the same constant
	F(MS_SILENT, silent);
	F(MS_POSIXACL, acl);
	F(MS_UNBINDABLE, unbindable);
	if (flags & MS_PRIVATE) {
		if (flags & MS_REC) {
			sc_string_append(buf, buf_size, "rprivate,");
			used |= MS_REC;
		} else {
			sc_string_append(buf, buf_size, "private,");
		}
		flags ^= MS_PRIVATE;
	}
	if (flags & MS_SLAVE) {
		if (flags & MS_REC) {
			sc_string_append(buf, buf_size, "rslave,");
			used |= MS_REC;
		} else {
			sc_string_append(buf, buf_size, "slave,");
		}
		flags ^= MS_SLAVE;
	}
	if (flags & MS_SHARED) {
		if (flags & MS_REC) {
			sc_string_append(buf, buf_size, "rshared,");
			used |= MS_REC;
		} else {
			sc_string_append(buf, buf_size, "shared,");
		}
		flags ^= MS_SHARED;
	}
	flags ^= used;		// this is just for MS_REC
	F(MS_RELATIME, relatime);
	F(MS_KERNMOUNT, kernmount);
	F(MS_I_VERSION, iversion);
	F(MS_STRICTATIME, strictatime);
#ifndef MS_LAZYTIME
#define MS_LAZYTIME (1<<25)
#endif
	F(MS_LAZYTIME, lazytime);
#ifndef MS_NOSEC
#define MS_NOSEC (1 << 28)
#endif
	F(MS_NOSEC, nosec);
#ifndef MS_BORN
#define MS_BORN (1 << 29)
#endif
	F(MS_BORN, born);
	F(MS_ACTIVE, active);
	F(MS_NOUSER, nouser);
#undef F
	// Render any flags that are unaccounted for.
	if (flags) {
		char of[128] = { 0 };
		sc_must_snprintf(of, sizeof of, "%#lx", flags);
		sc_string_append(buf, buf_size, of);
	}
	// Chop the excess comma from the end.
	size_t len = strnlen(buf, buf_size);
	if (len > 0 && buf[len - 1] == ',') {
		buf[len - 1] = 0;
	}
	return buf;
}
Exemple #7
0
const char *sc_mount_cmd(char *buf, size_t buf_size, const char *source, const char
			 *target, const char *fs_type, unsigned long mountflags, const
			 void *data)
{
	sc_string_init(buf, buf_size);
	sc_string_append(buf, buf_size, "mount");

	// Add filesysystem type if it's there and doesn't have the special value "none"
	if (fs_type != NULL && strncmp(fs_type, "none", 5) != 0) {
		sc_string_append(buf, buf_size, " -t ");
		sc_string_append(buf, buf_size, fs_type);
	}
	// Check for some special, dedicated options, that aren't represented with
	// the generic mount option argument (mount -o ...), by collecting those
	// options that we will display as command line arguments in
	// used_special_flags. This is used below to filter out these arguments
	// from mount_flags when calling sc_mount_opt2str().
	int used_special_flags = 0;

	// Bind-ounts (bind)
	if (mountflags & MS_BIND) {
		if (mountflags & MS_REC) {
			sc_string_append(buf, buf_size, " --rbind");
			used_special_flags |= MS_REC;
		} else {
			sc_string_append(buf, buf_size, " --bind");
		}
		used_special_flags |= MS_BIND;
	}
	// Moving mount point location (move)
	if (mountflags & MS_MOVE) {
		sc_string_append(buf, buf_size, " --move");
		used_special_flags |= MS_MOVE;
	}
	// Shared subtree operations (shared, slave, private, unbindable).
	if (MS_SHARED & mountflags) {
		if (mountflags & MS_REC) {
			sc_string_append(buf, buf_size, " --make-rshared");
			used_special_flags |= MS_REC;
		} else {
			sc_string_append(buf, buf_size, " --make-shared");
		}
		used_special_flags |= MS_SHARED;
	}

	if (MS_SLAVE & mountflags) {
		if (mountflags & MS_REC) {
			sc_string_append(buf, buf_size, " --make-rslave");
			used_special_flags |= MS_REC;
		} else {
			sc_string_append(buf, buf_size, " --make-slave");
		}
		used_special_flags |= MS_SLAVE;
	}

	if (MS_PRIVATE & mountflags) {
		if (mountflags & MS_REC) {
			sc_string_append(buf, buf_size, " --make-rprivate");
			used_special_flags |= MS_REC;
		} else {
			sc_string_append(buf, buf_size, " --make-private");
		}
		used_special_flags |= MS_PRIVATE;
	}

	if (MS_UNBINDABLE & mountflags) {
		if (mountflags & MS_REC) {
			sc_string_append(buf, buf_size, " --make-runbindable");
			used_special_flags |= MS_REC;
		} else {
			sc_string_append(buf, buf_size, " --make-unbindable");
		}
		used_special_flags |= MS_UNBINDABLE;
	}
	// If regular option syntax exists then use it.
	if (mountflags & ~used_special_flags) {
		char opts_buf[1000] = { 0 };
		sc_mount_opt2str(opts_buf, sizeof opts_buf, mountflags &
				 ~used_special_flags);
		sc_string_append(buf, buf_size, " -o ");
		sc_string_append(buf, buf_size, opts_buf);
	}
	// Add source and target locations
	if (source != NULL && strncmp(source, "none", 5) != 0) {
		sc_string_append(buf, buf_size, " ");
		sc_string_append(buf, buf_size, source);
	}
	if (target != NULL && strncmp(target, "none", 5) != 0) {
		sc_string_append(buf, buf_size, " ");
		sc_string_append(buf, buf_size, target);
	}

	return buf;
}
void sc_string_quote(char *buf, size_t buf_size, const char *str)
{
	if (str == NULL) {
		die("cannot quote string: string is NULL");
	}
	const char *hex = "0123456789abcdef";
	// NOTE: this also checks buf/buf_size sanity so that we don't have to.
	sc_string_init(buf, buf_size);
	sc_string_append_char(buf, buf_size, '"');
	for (unsigned char c; (c = *str) != 0; ++str) {
		switch (c) {
			// Pass ASCII letters and digits unmodified.
		case '0' ... '9':
		case 'A' ... 'Z':
		case 'a' ... 'z':
			// Pass most of the punctuation unmodified.
		case ' ':
		case '!':
		case '#':
		case '$':
		case '%':
		case '&':
		case '(':
		case ')':
		case '*':
		case '+':
		case ',':
		case '-':
		case '.':
		case '/':
		case ':':
		case ';':
		case '<':
		case '=':
		case '>':
		case '?':
		case '@':
		case '[':
		case '\'':
		case ']':
		case '^':
		case '_':
		case '`':
		case '{':
		case '|':
		case '}':
		case '~':
			sc_string_append_char(buf, buf_size, c);
			break;
			// Escape special whitespace characters.
		case '\n':
			sc_string_append_char_pair(buf, buf_size, '\\', 'n');
			break;
		case '\r':
			sc_string_append_char_pair(buf, buf_size, '\\', 'r');
			break;
		case '\t':
			sc_string_append_char_pair(buf, buf_size, '\\', 't');
			break;
		case '\v':
			sc_string_append_char_pair(buf, buf_size, '\\', 'v');
			break;
			// Escape the escape character.
		case '\\':
			sc_string_append_char_pair(buf, buf_size, '\\', '\\');
			break;
			// Escape double quote character.
		case '"':
			sc_string_append_char_pair(buf, buf_size, '\\', '"');
			break;
			// Escape everything else as a generic hexadecimal escape string.
		default:
			sc_string_append_char_pair(buf, buf_size, '\\', 'x');
			sc_string_append_char_pair(buf, buf_size, hex[c >> 4],
						   hex[c & 15]);
			break;
		}
	}
	sc_string_append_char(buf, buf_size, '"');
}