systemd: merge branch systemd into master
This commit is contained in:
@@ -1062,6 +1062,8 @@ bool string_is_safe(const char *p) {
|
||||
if (!p)
|
||||
return false;
|
||||
|
||||
/* Checks if the specified string contains no quotes or control characters */
|
||||
|
||||
for (t = p; *t; t++) {
|
||||
if (*t > 0 && *t < ' ') /* no control characters */
|
||||
return false;
|
||||
@@ -1083,4 +1085,122 @@ char* string_erase(char *x) {
|
||||
explicit_bzero_safe(x, strlen(x));
|
||||
return x;
|
||||
}
|
||||
|
||||
int string_truncate_lines(const char *s, size_t n_lines, char **ret) {
|
||||
const char *p = s, *e = s;
|
||||
bool truncation_applied = false;
|
||||
char *copy;
|
||||
size_t n = 0;
|
||||
|
||||
assert(s);
|
||||
|
||||
/* Truncate after the specified number of lines. Returns > 0 if a truncation was applied or == 0 if
|
||||
* there were fewer lines in the string anyway. Trailing newlines on input are ignored, and not
|
||||
* generated either. */
|
||||
|
||||
for (;;) {
|
||||
size_t k;
|
||||
|
||||
k = strcspn(p, "\n");
|
||||
|
||||
if (p[k] == 0) {
|
||||
if (k == 0) /* final empty line */
|
||||
break;
|
||||
|
||||
if (n >= n_lines) /* above threshold */
|
||||
break;
|
||||
|
||||
e = p + k; /* last line to include */
|
||||
break;
|
||||
}
|
||||
|
||||
assert(p[k] == '\n');
|
||||
|
||||
if (n >= n_lines)
|
||||
break;
|
||||
|
||||
if (k > 0)
|
||||
e = p + k;
|
||||
|
||||
p += k + 1;
|
||||
n++;
|
||||
}
|
||||
|
||||
/* e points after the last character we want to keep */
|
||||
if (isempty(e))
|
||||
copy = strdup(s);
|
||||
else {
|
||||
if (!in_charset(e, "\n")) /* We only consider things truncated if we remove something that
|
||||
* isn't a new-line or a series of them */
|
||||
truncation_applied = true;
|
||||
|
||||
copy = strndup(s, e - s);
|
||||
}
|
||||
if (!copy)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret = copy;
|
||||
return truncation_applied;
|
||||
}
|
||||
|
||||
int string_extract_line(const char *s, size_t i, char **ret) {
|
||||
const char *p = s;
|
||||
size_t c = 0;
|
||||
|
||||
/* Extract the i'nth line from the specified string. Returns > 0 if there are more lines after that,
|
||||
* and == 0 if we are looking at the last line or already beyond the last line. As special
|
||||
* optimization, if the first line is requested and the string only consists of one line we return
|
||||
* NULL, indicating the input string should be used as is, and avoid a memory allocation for a very
|
||||
* common case. */
|
||||
|
||||
for (;;) {
|
||||
const char *q;
|
||||
|
||||
q = strchr(p, '\n');
|
||||
if (i == c) {
|
||||
/* The line we are looking for! */
|
||||
|
||||
if (q) {
|
||||
char *m;
|
||||
|
||||
m = strndup(p, q - p);
|
||||
if (!m)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret = m;
|
||||
return !isempty(q + 1); /* more coming? */
|
||||
} else {
|
||||
if (p == s)
|
||||
*ret = NULL; /* Just use the input string */
|
||||
else {
|
||||
char *m;
|
||||
|
||||
m = strdup(p);
|
||||
if (!m)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret = m;
|
||||
}
|
||||
|
||||
return 0; /* The end */
|
||||
}
|
||||
}
|
||||
|
||||
if (!q) {
|
||||
char *m;
|
||||
|
||||
/* No more lines, return empty line */
|
||||
|
||||
m = strdup("");
|
||||
if (!m)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret = m;
|
||||
return 0; /* The end */
|
||||
}
|
||||
|
||||
p = q + 1;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
Reference in New Issue
Block a user