From 14fb44b17123b27e562379f51b75ee889982688d Mon Sep 17 00:00:00 2001 From: James Maki Date: Fri, 23 Apr 2010 11:58:20 -0500 Subject: initial commit --- src/utils.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 src/utils.c (limited to 'src/utils.c') diff --git a/src/utils.c b/src/utils.c new file mode 100644 index 0000000..9149319 --- /dev/null +++ b/src/utils.c @@ -0,0 +1,236 @@ +/* + * Utilities + * + * Copyright (C) 2010 by Multi-Tech Systems + * + * Author: James Maki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "log.h" + +int tokcmp(const char *cmd, const char *pattern) +{ + int len = strlen(cmd); + + if (len > strlen(pattern)) { + return -1; + } + + return memcmp(pattern, cmd, len); +} + +char *strrstrip(char *str) +{ + char *end; + char *prev; + + if (!str || !*str) { + return NULL; + } + prev = end = str + strlen(str); + + while (end > str && isspace(*(end - 1))) { + end--; + } + *end = '\0'; + + return prev == end ? NULL : str; +} + +ssize_t safe_read(int fd, void *buf, size_t count) +{ + ssize_t n; + + do { + n = read(fd, buf, count); + } while (n < 0 && errno == EINTR); + + return n; +} + +ssize_t safe_readn(int fd, void *buf, size_t len) +{ + ssize_t cc; + ssize_t total; + + total = 0; + + while (len) { + cc = safe_read(fd, buf, len); + + if (cc < 0) { + if (total) { + return total; + } + return cc; + } + + total += cc; + buf = buf + cc; + len -= cc; + } + + return total; +} + +ssize_t safe_write(int fd, const void *buf, size_t count) +{ + ssize_t n; + + do { + n = write(fd, buf, count); + } while (n < 0 && errno == EINTR); + + return n; +} + +ssize_t full_write(int fd, const void *buf, size_t len) +{ + ssize_t cc; + ssize_t total; + + total = 0; + + while (len) { + cc = safe_write(fd, buf, len); + + if (cc < 0) { + if (total) { + return total; + } + return cc; + } + + total += cc; + buf = ((const char *)buf) + cc; + len -= cc; + } + + return total; +} + +int user_yesno(int def, const char *fmt, ...) +{ + char buf[128]; + char *line; + va_list ap; + + while (1) { + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + + printf("? [%c/%c] ", + def == USER_YESNO_YES ? 'Y' : 'y', + def == USER_YESNO_NO ? 'N' : 'n'); + + line = fgets(buf, sizeof(buf), stdin); + if (!line) { + return -1; + } + + switch (toupper(*line)) { + case '\n': + return def; + case 'Y': + return USER_YESNO_YES; + case 'N': + return USER_YESNO_NO; + } + } + + return -1; +} + +int systemf(const char *fmt, ...) +{ + int err; + va_list ap; + char *buf; + + va_start(ap, fmt); + err = vasprintf(&buf, fmt, ap); + va_end(ap); + if (err < 0) { + log_error("out of memory"); + return -1; + } + + err = system(buf); + free(buf); + + return err; +} + +FILE *popenf(const char *mode, const char *fmt, ...) +{ + int err; + va_list ap; + char *buf; + FILE *pipe; + + va_start(ap, fmt); + err = vasprintf(&buf, fmt, ap); + va_end(ap); + if (err < 0) { + log_error("out of memory"); + return NULL; + } + + pipe = popen(buf, mode); + free(buf); + + return pipe; +} + +char *shell_path_expand(const char *path) +{ + char buf[PATH_MAX + 1]; + FILE *file; + char *line; + + file = popenf("r", "echo -n \"%s\"", path); + if (!file) { + log_error("popen failed"); + return NULL; + } + + line = fgets(buf, sizeof(buf), file); + + pclose(file); + + if (!line) { + log_error("no line read"); + return NULL; + } + + return strdup(line); +} -- cgit v1.2.3