clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name pathsub.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/nss/coreconf/nsinstall -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/nss/coreconf/nsinstall -resource-dir /usr/lib/llvm-22/lib/clang/22 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -I ../../../dist/Linux6.1_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../dist/public/coreconf -I ../../../dist/private/coreconf -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/15/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-11-18-221358-3012168-1 -x c pathsub.c
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | #if defined(FREEBSD) || defined(BSDI) || defined(DARWIN) |
| 9 | #include <sys/types.h> |
| 10 | #endif /* FREEBSD */ |
| 11 | #include <dirent.h> |
| 12 | #include <errno.h> |
| 13 | #include <stdarg.h> |
| 14 | #include <stdio.h> |
| 15 | #include <stdlib.h> |
| 16 | #include <string.h> |
| 17 | #include <unistd.h> |
| 18 | #include <sys/types.h> |
| 19 | #include <sys/stat.h> |
| 20 | #include "pathsub.h" |
| 21 | #ifdef USE_REENTRANT_LIBC |
| 22 | #include "libc_r.h" |
| 23 | #endif /* USE_REENTRANT_LIBC */ |
| 24 | |
| 25 | char *program; |
| 26 | |
| 27 | void |
| 28 | fail(char *format, ...) |
| 29 | { |
| 30 | int error; |
| 31 | va_list ap; |
| 32 | |
| 33 | #ifdef USE_REENTRANT_LIBC |
| 34 | R_STRERROR_INIT_R(); |
| 35 | #endif |
| 36 | |
| 37 | error = errno; |
| 38 | fprintf(stderr, "%s: ", program); |
| 39 | va_start(ap, format); |
| 40 | vfprintf(stderr, format, ap); |
| 41 | va_end(ap); |
| 42 | if (error) { |
| 43 | |
| 44 | #ifdef USE_REENTRANT_LIBC |
| 45 | R_STRERROR_R(errno); |
| 46 | fprintf(stderr, ": %s", r_strerror_r); |
| 47 | #else |
| 48 | fprintf(stderr, ": %s", strerror(errno)); |
| 49 | #endif |
| 50 | } |
| 51 | |
| 52 | putc('\n', stderr); |
| 53 | abort(); |
| 54 | exit(1); |
| 55 | } |
| 56 | |
| 57 | char * |
| 58 | getcomponent(char *path, char *name) |
| 59 | { |
| 60 | if (*path == '\0') |
| 61 | return 0; |
| 62 | if (*path == '/') { |
| 63 | *name++ = '/'; |
| 64 | } else { |
| 65 | do { |
| 66 | *name++ = *path++; |
| 67 | } while (*path != '/' && *path != '\0'); |
| 68 | } |
| 69 | *name = '\0'; |
| 70 | while (*path == '/') |
| 71 | path++; |
| 72 | return path; |
| 73 | } |
| 74 | |
| 75 | |
| 76 | char * |
| 77 | ino2name(ino_t ino, char *dir) |
| 78 | { |
| 79 | DIR *dp; |
| 80 | struct dirent *ep; |
| 81 | char *name; |
| 82 | |
| 83 | dp = opendir(".."); |
| 84 | if (!dp) |
| 85 | fail("cannot read parent directory"); |
| 86 | for (;;) { |
| 87 | if (!(ep = readdir(dp))) |
| 88 | fail("cannot find current directory"); |
| 89 | if (ep->d_ino == ino) |
| 90 | break; |
| 91 | } |
| 92 | name = xstrdup(ep->d_name); |
| 93 | closedir(dp); |
| 94 | return name; |
| 95 | } |
| 96 | |
| 97 | void * |
| 98 | xmalloc(size_t size) |
| 99 | { |
| 100 | void *p; |
| 101 | |
| 102 | if (size <= 0) |
| 103 | fail("attempted to allocate %u bytes", size); |
| 104 | p = malloc(size); |
| 105 | if (!p) |
| 106 | fail("cannot allocate %u bytes", size); |
| 107 | return p; |
| 108 | } |
| 109 | |
| 110 | char * |
| 111 | xstrdup(char *s) |
| 112 | { |
| 113 | if (!s || !s[0]) |
| 114 | fail("Null pointer or empty string passed to xstrdup()"); |
| 115 | return strcpy((char*)xmalloc(strlen(s) + 1), s); |
| 116 | } |
| 117 | |
| 118 | char * |
| 119 | xbasename(char *path) |
| 120 | { |
| 121 | char *cp; |
| 122 | |
| 123 | if (!path || !path[0]) |
| 124 | fail("Null pointer or empty string passed to xbasename()"); |
| 125 | while ((cp = strrchr(path, '/')) && cp[1] == '\0') |
| 126 | *cp = '\0'; |
| 127 | if (!cp) return path; |
| 128 | return cp + 1; |
| 129 | } |
| 130 | |
| 131 | void |
| 132 | xchdir(char *dir) |
| 133 | { |
| 134 | if (!dir || !dir[0]) |
| 135 | fail("Null pointer or empty string passed to xchdir()"); |
| 136 | if (chdir(dir) < 0) |
| 137 | fail("cannot change directory to %s", dir); |
| 138 | } |
| 139 | |
| 140 | int |
| 141 | relatepaths(char *from, char *to, char *outpath) |
| 142 | { |
| 143 | char *cp, *cp2; |
| 144 | int len; |
| 145 | char buf[NAME_MAX]; |
| 146 | |
| 147 | if (!from || *from != '/') |
| 148 | fail("relatepaths: from path does not start with /"); |
| 149 | if (!to || *to != '/') |
| 150 | fail("relatepaths: to path does not start with /"); |
| 151 | |
| 152 | for (cp = to, cp2 = from; *cp == *cp2; cp++, cp2++) |
| 153 | if (*cp == '\0') |
| 154 | break; |
| 155 | while (cp[-1] != '/') |
| 156 | cp--, cp2--; |
| 157 | if (cp - 1 == to) { |
| 158 | |
| 159 | len = strlen(strcpy(outpath, to)); |
| 160 | if (outpath[len] != '/') { |
| 161 | outpath[len++] = '/'; |
| 162 | outpath[len] = '\0'; |
| 163 | } |
| 164 | } else { |
| 165 | len = 0; |
| 166 | while ((cp2 = getcomponent(cp2, buf)) != 0) { |
| 167 | strcpy(outpath + len, "../"); |
| 168 | len += 3; |
| 169 | } |
| 170 | while ((cp = getcomponent(cp, buf)) != 0) { |
| 171 | snprintf(outpath + len, PATH_MAX - len, "%s/", buf); |
| 172 | len += strlen(outpath + len); |
| 173 | } |
| 174 | } |
| 175 | return len; |
| 176 | } |
| 177 | |
| 178 | void |
| 179 | reversepath(char *inpath, char *name, int len, char *outpath) |
| 180 | { |
| 181 | char *cp, *cp2; |
| 182 | char buf[NAME_MAX]; |
| 183 | struct stat sb; |
| 184 | |
| 185 | cp = strcpy(outpath + PATH_MAX - (len + 1), name); |
| 186 | cp2 = inpath; |
| 187 | while ((cp2 = getcomponent(cp2, buf)) != 0) { |
| 188 | if (strcmp(buf, ".") == 0) |
| 189 | continue; |
| 190 | if (strcmp(buf, "..") == 0) { |
| 191 | if (stat(".", &sb) < 0) |
| 192 | fail("cannot stat current directory"); |
| 193 | name = ino2name(sb.st_ino, ".."); |
| 194 | len = strlen(name); |
| 195 | cp -= len + 1; |
| 196 | strcpy(cp, name); |
| 197 | cp[len] = '/'; |
| 198 | free(name); |
| 199 | xchdir(".."); |
| 200 | } else { |
| 201 | cp -= 3; |
| 202 | memcpy(cp, "../", 3); |
| 203 | xchdir(buf); |
| 204 | } |
| 205 | } |
| 206 | strcpy(outpath, cp); |
| 207 | } |
| 208 | |
| 209 | void |
| 210 | diagnosePath(const char * path) |
| 211 | { |
| 212 | char * myPath; |
| 213 | char * slash; |
| 214 | int rv; |
| 215 | struct stat sb; |
| 216 | char buf[BUFSIZ]; |
| 217 | |
| 218 | if (!path || !path[0]) |
| |
| 219 | fail("Null pointer or empty string passed to mkdirs()"); |
| 220 | myPath = strdup(path); |
| 2 | | Null pointer passed to 1st parameter expecting 'nonnull' |
|
| 221 | if (!myPath) |
| 222 | fail("strdup() failed!"); |
| 223 | do { |
| 224 | rv = lstat(myPath, &sb); |
| 225 | if (rv < 0) { |
| 226 | perror(myPath); |
| 227 | } else if (S_ISLNK(sb.st_mode)) { |
| 228 | rv = readlink(myPath, buf, sizeof(buf) - 1); |
| 229 | if (rv < 0) { |
| 230 | perror("readlink"); |
| 231 | buf[0] = 0; |
| 232 | } else { |
| 233 | buf[rv] = 0; |
| 234 | } |
| 235 | fprintf(stderr, "%s is a link to %s\n", myPath, buf); |
| 236 | } else if (S_ISDIR(sb.st_mode)) { |
| 237 | fprintf(stderr, "%s is a directory\n", myPath); |
| 238 | rv = access(myPath, X_OK); |
| 239 | if (rv < 0) { |
| 240 | fprintf(stderr, "%s: no search permission\n", myPath); |
| 241 | } |
| 242 | } else { |
| 243 | fprintf(stderr, "%s is a file !?!\n", myPath); |
| 244 | rv = access(myPath, F_OK); |
| 245 | if (rv < 0) { |
| 246 | fprintf(stderr, "%s does not exist\n", myPath); |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | |
| 251 | slash = strrchr(myPath, '/'); |
| 252 | if (!slash) |
| 253 | slash = strrchr(myPath, '\\'); |
| 254 | if (!slash) |
| 255 | slash = myPath; |
| 256 | *slash = 0; |
| 257 | } while (myPath[0]); |
| 258 | free(myPath); |
| 259 | } |