#include "util.h"
#include "strv.h"
-int write_string_file(const char *fn, const char *line) {
- _cleanup_fclose_ FILE *f = NULL;
-
- assert(fn);
- assert(line);
-
- f = fopen(fn, "we");
- if (!f)
- return -errno;
-
+int write_string_to_file(FILE *f, const char *line) {
errno = 0;
fputs(line, f);
if (!endswith(line, "\n"))
return 0;
}
+int write_string_file(const char *fn, const char *line) {
+ _cleanup_fclose_ FILE *f = NULL;
+
+ assert(fn);
+ assert(line);
+
+ f = fopen(fn, "we");
+ if (!f)
+ return -errno;
+
+ return write_string_to_file(f, line);
+}
+
int write_string_file_atomic(const char *fn, const char *line) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *p = NULL;
void *userdata) {
_cleanup_free_ char *contents = NULL, *key = NULL;
- size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_whitespace = (size_t) -1;
+ size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_value_whitespace = (size_t) -1, last_key_whitespace = (size_t) -1;
char *p, *value = NULL;
int r;
enum {
PRE_KEY,
KEY,
- PRE_EQUAL,
PRE_VALUE,
VALUE,
VALUE_ESCAPE,
state = COMMENT;
else if (!strchr(WHITESPACE, c)) {
state = KEY;
+ last_key_whitespace = (size_t) -1;
+
if (!greedy_realloc((void**) &key, &key_alloc, n_key+2)) {
r = -ENOMEM;
goto fail;
if (strchr(newline, c)) {
state = PRE_KEY;
n_key = 0;
- } else if (strchr(WHITESPACE, c))
- state = PRE_EQUAL;
- else if (c == '=')
+ } else if (c == '=') {
state = PRE_VALUE;
- else {
+ last_value_whitespace = (size_t) -1;
+ } else {
+ if (!strchr(WHITESPACE, c))
+ last_key_whitespace = (size_t) -1;
+ else if (last_key_whitespace == (size_t) -1)
+ last_key_whitespace = n_key;
+
if (!greedy_realloc((void**) &key, &key_alloc, n_key+2)) {
r = -ENOMEM;
goto fail;
break;
- case PRE_EQUAL:
- if (strchr(newline, c)) {
- state = PRE_KEY;
- n_key = 0;
- } else if (c == '=')
- state = PRE_VALUE;
- else if (!strchr(WHITESPACE, c)) {
- n_key = 0;
- state = COMMENT;
- }
-
- break;
-
case PRE_VALUE:
if (strchr(newline, c)) {
state = PRE_KEY;
if (value)
value[n_value] = 0;
+ /* strip trailing whitespace from key */
+ if (last_key_whitespace != (size_t) -1)
+ key[last_key_whitespace] = 0;
+
r = push(key, value, userdata);
if (r < 0)
goto fail;
n_key = 0;
value = NULL;
value_alloc = n_value = 0;
+
} else if (c == '\'')
state = SINGLE_QUOTE_VALUE;
else if (c == '\"')
case VALUE:
if (strchr(newline, c)) {
state = PRE_KEY;
+
key[n_key] = 0;
if (value)
value[n_value] = 0;
- /* Chomp off trailing whitespace */
- if (last_whitespace != (size_t) -1)
- value[last_whitespace] = 0;
+ /* Chomp off trailing whitespace from value */
+ if (last_value_whitespace != (size_t) -1)
+ value[last_value_whitespace] = 0;
+
+ /* strip trailing whitespace from key */
+ if (last_key_whitespace != (size_t) -1)
+ key[last_key_whitespace] = 0;
r = push(key, value, userdata);
if (r < 0)
n_key = 0;
value = NULL;
value_alloc = n_value = 0;
+
} else if (c == '\\') {
state = VALUE_ESCAPE;
- last_whitespace = (size_t) -1;
+ last_value_whitespace = (size_t) -1;
} else {
if (!strchr(WHITESPACE, c))
- last_whitespace = (size_t) -1;
- else if (last_whitespace == (size_t) -1)
- last_whitespace = n_value;
+ last_value_whitespace = (size_t) -1;
+ else if (last_value_whitespace == (size_t) -1)
+ last_value_whitespace = n_value;
if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
r = -ENOMEM;
if (value)
value[n_value] = 0;
+ if (state == VALUE)
+ if (last_value_whitespace != (size_t) -1)
+ value[last_value_whitespace] = 0;
+
+ /* strip trailing whitespace from key */
+ if (last_key_whitespace != (size_t) -1)
+ key[last_key_whitespace] = 0;
+
r = push(key, value, userdata);
if (r < 0)
goto fail;
p++;
fwrite(v, 1, p-v, f);
- if (string_has_cc(p) || chars_intersect(p, WHITESPACE "\'\"\\")) {
+ if (string_has_cc(p) || chars_intersect(p, WHITESPACE "\'\"\\`$")) {
fputc('\"', f);
for (; *p; p++) {
- if (strchr("\'\"\\", *p))
+ if (strchr("\'\"\\`$", *p))
fputc('\\', f);
fputc(*p, f);
int write_env_file(const char *fname, char **l) {
char **i;
- char _cleanup_free_ *p = NULL;
- FILE _cleanup_fclose_ *f = NULL;
+ _cleanup_free_ char *p = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
int r;
r = fopen_temporary(fname, &f, &p);
return r;
}
+
+int executable_is_script(const char *path, char **interpreter) {
+ int r;
+ char _cleanup_free_ *line = NULL;
+ int len;
+ char *ans;
+
+ assert(path);
+
+ r = read_one_line_file(path, &line);
+ if (r < 0)
+ return r;
+
+ if (!startswith(line, "#!"))
+ return 0;
+
+ ans = strstrip(line + 2);
+ len = strcspn(ans, " \t");
+
+ if (len == 0)
+ return 0;
+
+ ans = strndup(ans, len);
+ if (!ans)
+ return -ENOMEM;
+
+ *interpreter = ans;
+ return 1;
+}