xref: /5.5.2/couchstore/src/file_name_utils.c (revision 13d4a251)
1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 
3 /**
4  * @copyright 2013 Couchbase, Inc.
5  *
6  * @author Filipe Manana  <filipe@couchbase.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
9  * use this file except in compliance with the License. You may obtain a copy of
10  * the License at
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17  * License for the specific language governing permissions and limitations under
18  * the License.
19  **/
20 
21 #if defined(WIN32) || defined(_WIN32)
22 # define WINDOWS
23 # include <io.h>
24 #else
25 # ifndef _BSD_SOURCE
26 /* for mkstemp() */
27 #  define _BSD_SOURCE
28 # endif
29 # include <libgen.h>
30 # include <unistd.h>
31 #endif
32 
33 #include "file_name_utils.h"
34 
35 #include <platform/cb_malloc.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 
40 #define TMP_FILE_SUFFIX ".XXXXXX"
41 
42 
tmp_file_path(const char * tmp_dir,const char * prefix)43 char *tmp_file_path(const char *tmp_dir, const char *prefix)
44 {
45     char *file_path;
46     size_t tmp_dir_len, prefix_len, total_len;
47 #ifdef WINDOWS
48     errno_t err;
49 #else
50     int fd;
51 #endif
52 
53 
54     tmp_dir_len = strlen(tmp_dir);
55     prefix_len = strlen(prefix);
56     total_len = tmp_dir_len + 1 + prefix_len + sizeof(TMP_FILE_SUFFIX);
57     file_path = (char *) cb_malloc(total_len);
58 
59     if (file_path == NULL) {
60         return NULL;
61     }
62 
63     memcpy(file_path, tmp_dir, tmp_dir_len);
64     /* Windows specific file API functions and stdio file functions on Windows
65      * convert forward slashes to back slashes. */
66     file_path[tmp_dir_len] = '/';
67     memcpy(file_path + tmp_dir_len + 1, prefix, prefix_len);
68     memcpy(file_path + tmp_dir_len + 1 + prefix_len,
69            TMP_FILE_SUFFIX,
70            sizeof(TMP_FILE_SUFFIX));
71 
72 #ifdef WINDOWS
73     err = _mktemp_s(file_path, total_len);
74     if (err != 0) {
75         cb_free(file_path);
76         return NULL;
77     }
78 #else
79     fd = mkstemp(file_path);
80     if (fd == -1) {
81         cb_free(file_path);
82         return NULL;
83     }
84     close(fd);
85     remove(file_path);
86 #endif
87 
88     return file_path;
89 }
90 
91 
file_basename(const char * path)92 char *file_basename(const char *path)
93 {
94     char *ret;
95 #ifdef WINDOWS
96     char drive[_MAX_DRIVE];
97     char dir[_MAX_DIR];
98     char fname[_MAX_FNAME];
99     char ext[_MAX_EXT];
100 
101     _splitpath(path, drive, dir, fname, ext);
102 #else
103     char *fname;
104 
105     fname = basename((char *) path);
106 #endif
107 
108     ret = (char *) cb_malloc(strlen(fname) + 1);
109     if (ret != NULL) {
110         strcpy(ret, fname);
111     }
112 
113     return ret;
114 }
115