lttng-crash: clean-up: fix alignment of format string
[lttng-tools.git] / src / bin / lttng-crash / lttng-crash.c
index 13d136da96e845e8c78e23870caa507b7e708f3e..262cd7cc0d7af67dd4b38b19cc3f6d7b7af79b11 100644 (file)
@@ -2,18 +2,8 @@
  * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
  * Copyright (C) 2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2 only,
- * as published by the Free Software Foundation.
+ * SPDX-License-Identifier: GPL-2.0-only
  *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #include <getopt.h>
                0xF1 ^ 0xFF, 0x77 ^ 0xFF, 0xBF ^ 0xFF, 0x17 ^ 0xFF,     \
        }
 
+static const char *help_msg =
+#ifdef LTTNG_EMBED_HELP
+#include <lttng-crash.1.h>
+#else
+NULL
+#endif
+;
+
 /*
  * Non-static to ensure the compiler does not optimize away the xor.
  */
@@ -182,9 +180,9 @@ struct lttng_crash_layout {
 };
 
 /* Variables */
-static char *progname,
-       *opt_viewer_path = NULL,
-       *opt_output_path = NULL;
+static const char *progname;
+static char *opt_viewer_path = NULL;
+static char *opt_output_path = NULL;
 
 static char *input_path;
 
@@ -207,10 +205,10 @@ static struct option long_options[] = {
 
 static void usage(void)
 {
-       int ret = utils_show_man_page(1, "lttng-crash");
+       int ret = utils_show_help(1, "lttng-crash", help_msg);
 
        if (ret) {
-               ERR("Cannot view man page lttng-crash(1)");
+               ERR("Cannot show --help for `lttng-crash`");
                perror("exec");
                exit(EXIT_FAILURE);
        }
@@ -219,9 +217,10 @@ static void usage(void)
 static void version(FILE *ofp)
 {
        fprintf(ofp, "%s (LTTng Crash Trace Viewer) " VERSION " - " VERSION_NAME
-"%s\n",
+                       "%s%s\n",
                        progname,
-                       GIT_VERSION[0] == '\0' ? "" : " - " GIT_VERSION);
+                       GIT_VERSION[0] == '\0' ? "" : " - " GIT_VERSION,
+                       EXTRA_VERSION_NAME[0] == '\0' ? "" : " - " EXTRA_VERSION_NAME);
 }
 
 /*
@@ -297,7 +296,7 @@ static int parse_args(int argc, char **argv)
        }
 
        if (!opt_viewer_path) {
-               opt_viewer_path = DEFAULT_VIEWER;
+               opt_viewer_path = (char *) DEFAULT_VIEWER;
        }
 
        /* No leftovers, or more than one input path, print usage and quit */
@@ -490,7 +489,8 @@ int check_magic(const uint8_t *magic)
 }
 
 static
-int get_crash_layout(struct lttng_crash_layout *layout, int fd)
+int get_crash_layout(struct lttng_crash_layout *layout, int fd,
+               const char *input_file)
 {
        char *map;
        int ret = 0, unmapret;
@@ -501,7 +501,21 @@ int get_crash_layout(struct lttng_crash_layout *layout, int fd)
        const struct crash_abi_unknown *abi;
        uint16_t endian;
        enum lttng_crash_type layout_type;
+       struct stat stat;
 
+       ret = fstat(fd, &stat);
+       if (ret < 0) {
+               PERROR("Failed to fstat '%s'", input_file);
+               return -1;
+       }
+       if (stat.st_size < RB_CRASH_DUMP_ABI_LEN) {
+               ERR("File '%s' truncated: file length of %" PRIi64
+                               " bytes does not meet the minimal expected "
+                               "length of %d bytes",
+                               input_file, (int64_t) stat.st_size,
+                               RB_CRASH_DUMP_ABI_LEN);
+               return -1;
+       }
        map = mmap(NULL, RB_CRASH_DUMP_ABI_LEN, PROT_READ, MAP_PRIVATE,
                fd, 0);
        if (map == MAP_FAILED) {
@@ -830,7 +844,7 @@ int extract_file(int output_dir_fd, const char *output_file,
        }
 
        /* Query the crash ABI layout */
-       ret = get_crash_layout(&layout, fd_src);
+       ret = get_crash_layout(&layout, fd_src, input_file);
        if (ret) {
                goto close_src;
        }
@@ -965,6 +979,7 @@ int extract_trace_recursive(const char *output_path,
        DIR *dir;
        int dir_fd, ret = 0, closeret;
        struct dirent *entry;
+       size_t path_len;
        int has_warning = 0;
 
        /* Open directory */
@@ -973,6 +988,9 @@ int extract_trace_recursive(const char *output_path,
                PERROR("Cannot open '%s' path", input_path);
                return -1;
        }
+
+       path_len = strlen(input_path);
+
        dir_fd = dirfd(dir);
        if (dir_fd < 0) {
                PERROR("dirfd");
@@ -980,13 +998,34 @@ int extract_trace_recursive(const char *output_path,
        }
 
        while ((entry = readdir(dir))) {
+               struct stat st;
+               size_t name_len;
+               char filename[PATH_MAX];
+
                if (!strcmp(entry->d_name, ".")
                                || !strcmp(entry->d_name, "..")) {
                        continue;
                }
-               switch (entry->d_type) {
-               case DT_DIR:
-               {
+
+               name_len = strlen(entry->d_name);
+               if (path_len + name_len + 2 > sizeof(filename)) {
+                       ERR("Failed to remove file: path name too long (%s/%s)",
+                               input_path, entry->d_name);
+                       continue;
+               }
+
+               if (snprintf(filename, sizeof(filename), "%s/%s",
+                               input_path, entry->d_name) < 0) {
+                       ERR("Failed to format path.");
+                       continue;
+               }
+
+               if (stat(filename, &st)) {
+                       PERROR("stat");
+                       continue;
+               }
+
+               if (S_ISDIR(st.st_mode)) {
                        char output_subpath[PATH_MAX];
                        char input_subpath[PATH_MAX];
 
@@ -1018,10 +1057,7 @@ int extract_trace_recursive(const char *output_path,
                        if (ret) {
                                has_warning = 1;
                        }
-                       break;
-               }
-               case DT_REG:
-               case DT_LNK:
+               } else if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
                        if (!strcmp(entry->d_name, "metadata")) {
                                ret = extract_one_trace(output_path,
                                        input_path);
@@ -1031,9 +1067,7 @@ int extract_trace_recursive(const char *output_path,
                                        has_warning = 1;
                                }
                        }
-                       /* Ignore other files */
-                       break;
-               default:
+               } else {
                        has_warning = 1;
                        goto end;
                }
@@ -1051,6 +1085,7 @@ int delete_dir_recursive(const char *path)
 {
        DIR *dir;
        int dir_fd, ret = 0, closeret;
+       size_t path_len;
        struct dirent *entry;
 
        /* Open trace directory */
@@ -1058,8 +1093,11 @@ int delete_dir_recursive(const char *path)
        if (!dir) {
                PERROR("Cannot open '%s' path", path);
                ret = -errno;
-               goto end;
+               goto end_no_closedir;
        }
+
+       path_len = strlen(path);
+
        dir_fd = dirfd(dir);
        if (dir_fd < 0) {
                PERROR("dirfd");
@@ -1068,13 +1106,34 @@ int delete_dir_recursive(const char *path)
        }
 
        while ((entry = readdir(dir))) {
+               struct stat st;
+               size_t name_len;
+               char filename[PATH_MAX];
+
                if (!strcmp(entry->d_name, ".")
                                || !strcmp(entry->d_name, "..")) {
                        continue;
                }
-               switch (entry->d_type) {
-               case DT_DIR:
-               {
+
+               name_len = strlen(entry->d_name);
+               if (path_len + name_len + 2 > sizeof(filename)) {
+                       ERR("Failed to remove file: path name too long (%s/%s)",
+                               path, entry->d_name);
+                       continue;
+               }
+
+               if (snprintf(filename, sizeof(filename), "%s/%s",
+                               path, entry->d_name) < 0) {
+                       ERR("Failed to format path.");
+                       continue;
+               }
+
+               if (stat(filename, &st)) {
+                       PERROR("stat");
+                       continue;
+               }
+
+               if (S_ISDIR(st.st_mode)) {
                        char *subpath = zmalloc(PATH_MAX);
 
                        if (!subpath) {
@@ -1092,19 +1151,16 @@ int delete_dir_recursive(const char *path)
                        ret = delete_dir_recursive(subpath);
                        free(subpath);
                        if (ret) {
-                               /* Error occured, abort traversal. */
+                               /* Error occurred, abort traversal. */
                                goto end;
                        }
-                       break;
-               }
-               case DT_REG:
+               } else if (S_ISREG(st.st_mode)) {
                        ret = unlinkat(dir_fd, entry->d_name, 0);
                        if (ret) {
                                PERROR("Unlinking '%s'", entry->d_name);
                                goto end;
                        }
-                       break;
-               default:
+               } else {
                        ret = -EINVAL;
                        goto end;
                }
@@ -1120,6 +1176,7 @@ end:
        if (closeret) {
                PERROR("closedir");
        }
+end_no_closedir:
        return ret;
 }
 
This page took 0.026736 seconds and 4 git commands to generate.