1 /*
2 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17 /** \file
18 * \brief Path name manipulation utilities
19 *
20 * Implement the legacy path name utility functions.
21 */
22
23 #include "legacy-util-api.h"
24 #include <stddef.h>
25 #include <string.h>
26 #include <unistd.h> /* access() */
27
28 void
basenam(const char * orig_path,const char * optional_suffix,char * basename)29 basenam(const char *orig_path, const char *optional_suffix, char *basename)
30 {
31 const char *fn = strrchr(orig_path, '/');
32 size_t length;
33
34 if (fn == NULL)
35 fn = orig_path;
36 else
37 ++fn;
38 length = strlen(fn);
39
40 if (optional_suffix != NULL) {
41 size_t suffix_length = strlen(optional_suffix);
42 if (suffix_length >= length &&
43 strcmp(fn + length - suffix_length, optional_suffix) == 0)
44 length -= suffix_length;
45 }
46
47 memcpy(basename, fn, length);
48 basename[length] = '\0';
49 }
50
51 void
dirnam(const char * orig_path,char * dirname)52 dirnam(const char *orig_path, char *dirname)
53 {
54 const char *slash = strrchr(orig_path, '/');
55 if (slash == NULL) {
56 strcpy(dirname, "./");
57 } else if (slash == orig_path) {
58 strcpy(dirname, "/");
59 } else {
60 size_t length = slash - orig_path;
61 memcpy(dirname, orig_path, length);
62 dirname[length] = '\0';
63 }
64 }
65
66 int
fndpath(const char * target,char * path,size_t max_length,const char * dirlist)67 fndpath(const char *target, char *path, size_t max_length, const char *dirlist)
68 {
69 size_t target_length = target ? strlen(target) : 0;
70 if (target_length == 0)
71 return -1;
72
73 /* The legacy fndpath supplies a default dirlist of '.', which seems
74 * unsafe.
75 */
76 if (dirlist == NULL || !*dirlist)
77 dirlist = ".";
78
79 while (*dirlist != '\0') {
80 const char *end = strchr(dirlist, ':');
81 size_t component_length = end ? end - dirlist : strlen(dirlist);
82 while (component_length > 1 &&
83 dirlist[component_length - 1] == '/') {
84 /* ignore trailing '/', unless it's the only character */
85 --component_length;
86 }
87 if (component_length > 0 &&
88 component_length + 1 /* '/' */ + target_length + 1 <= max_length) {
89 char *p = path;
90 memcpy(p, dirlist, component_length);
91 p += component_length;
92 *p++ = '/';
93 memcpy(p, target, target_length);
94 p[target_length] = '\0';
95 if (access(path, 0) == 0)
96 return 0; /* path exists */
97 }
98 if (end == NULL)
99 break;
100 dirlist = end + 1;
101 }
102
103 return -1;
104 }
105
106 FILE *
tmpf(char * ignored)107 tmpf(char *ignored)
108 {
109 return tmpfile();
110 }
111
112 char *
mkperm(char * pattern,const char * oldext,const char * newext)113 mkperm(char *pattern, const char *oldext, const char *newext)
114 {
115 size_t length = strlen(pattern), ext_length = strlen(oldext);
116 if (ext_length <= length) {
117 char *at = pattern + length - ext_length;
118 if (memcmp(at, oldext, ext_length) == 0)
119 strcpy(at, newext);
120 }
121 return pattern;
122 }
123