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