/src/server/mysys/my_getwd.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | Copyright (c) 2000, 2010, Oracle and/or its affiliates |
3 | | |
4 | | This program is free software; you can redistribute it and/or modify |
5 | | it under the terms of the GNU General Public License as published by |
6 | | the Free Software Foundation; version 2 of the License. |
7 | | |
8 | | This program is distributed in the hope that it will be useful, |
9 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | | GNU General Public License for more details. |
12 | | |
13 | | You should have received a copy of the GNU General Public License |
14 | | along with this program; if not, write to the Free Software |
15 | | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ |
16 | | |
17 | | /* my_setwd() and my_getwd() works with intern_filenames !! */ |
18 | | |
19 | | #include "mysys_priv.h" |
20 | | #include <m_string.h> |
21 | | #include "mysys_err.h" |
22 | | #ifdef HAVE_GETWD |
23 | | #include <sys/param.h> |
24 | | #endif |
25 | | #if defined(_WIN32) |
26 | | #include <m_ctype.h> |
27 | | #include <dos.h> |
28 | | #include <direct.h> |
29 | | #endif |
30 | | |
31 | | /* Gets current working directory in buff. |
32 | | |
33 | | SYNPOSIS |
34 | | my_getwd() |
35 | | buf Buffer to store result. Can be curr_dir[]. |
36 | | size Size of buffer |
37 | | MyFlags Flags |
38 | | |
39 | | NOTES |
40 | | Directory is always ended with FN_LIBCHAR |
41 | | |
42 | | RESULT |
43 | | 0 ok |
44 | | # error |
45 | | */ |
46 | | |
47 | | int my_getwd(char * buf, size_t size, myf MyFlags) |
48 | 0 | { |
49 | 0 | char * pos; |
50 | 0 | DBUG_ENTER("my_getwd"); |
51 | 0 | DBUG_PRINT("my",("buf:%p size: %u MyFlags %lu", |
52 | 0 | buf, (uint) size, MyFlags)); |
53 | |
|
54 | 0 | if (size < 1) |
55 | 0 | DBUG_RETURN(-1); |
56 | | |
57 | 0 | if (curr_dir[0]) /* Current pos is saved here */ |
58 | 0 | (void) strmake(buf,&curr_dir[0],size-1); |
59 | 0 | else |
60 | 0 | { |
61 | 0 | #if defined(HAVE_GETCWD) |
62 | 0 | if (size < 2) |
63 | 0 | DBUG_RETURN(-1); |
64 | 0 | if (!getcwd(buf,(uint) (size-2)) && MyFlags & MY_WME) |
65 | 0 | { |
66 | 0 | my_errno=errno; |
67 | 0 | my_error(EE_GETWD,MYF(ME_BELL),errno); |
68 | 0 | DBUG_RETURN(-1); |
69 | 0 | } |
70 | | #elif defined(HAVE_GETWD) |
71 | | { |
72 | | char pathname[MAXPATHLEN]; |
73 | | getwd(pathname); |
74 | | strmake(buf,pathname,size-1); |
75 | | } |
76 | | #else |
77 | | #error "No way to get current directory" |
78 | | #endif |
79 | 0 | if (*((pos=strend(buf))-1) != FN_LIBCHAR) /* End with FN_LIBCHAR */ |
80 | 0 | { |
81 | 0 | pos[0]= FN_LIBCHAR; |
82 | 0 | pos[1]=0; |
83 | 0 | } |
84 | 0 | (void) strmake(&curr_dir[0],buf, (size_t) (FN_REFLEN-1)); |
85 | 0 | } |
86 | 0 | DBUG_RETURN(0); |
87 | 0 | } /* my_getwd */ |
88 | | |
89 | | |
90 | | /* Set new working directory */ |
91 | | |
92 | | int my_setwd(const char *dir, myf MyFlags) |
93 | 0 | { |
94 | 0 | int res; |
95 | 0 | size_t length; |
96 | 0 | char *start, *pos; |
97 | 0 | DBUG_ENTER("my_setwd"); |
98 | 0 | DBUG_PRINT("my",("dir: '%s' MyFlags %lu", dir, MyFlags)); |
99 | |
|
100 | 0 | start=(char *) dir; |
101 | 0 | if (! dir[0] || (dir[0] == FN_LIBCHAR && dir[1] == 0)) |
102 | 0 | dir=FN_ROOTDIR; |
103 | 0 | if ((res=chdir((char*) dir)) != 0) |
104 | 0 | { |
105 | 0 | my_errno=errno; |
106 | 0 | if (MyFlags & MY_WME) |
107 | 0 | my_error(EE_SETWD,MYF(ME_BELL),start,errno); |
108 | 0 | } |
109 | 0 | else |
110 | 0 | { |
111 | 0 | if (test_if_hard_path(start)) |
112 | 0 | { /* Hard pathname */ |
113 | 0 | pos= strmake(&curr_dir[0],start,(size_t) FN_REFLEN-1); |
114 | 0 | if (pos[-1] != FN_LIBCHAR) |
115 | 0 | { |
116 | 0 | length=(uint) (pos-(char*) curr_dir); |
117 | 0 | curr_dir[length]=FN_LIBCHAR; /* must end with '/' */ |
118 | 0 | curr_dir[length+1]='\0'; |
119 | 0 | } |
120 | 0 | } |
121 | 0 | else |
122 | 0 | curr_dir[0]='\0'; /* Don't save name */ |
123 | 0 | } |
124 | 0 | DBUG_RETURN(res); |
125 | 0 | } /* my_setwd */ |
126 | | |
127 | | |
128 | | |
129 | | /* Test if hard pathname */ |
130 | | /* Returns 1 if dirname is a hard path */ |
131 | | |
132 | | int test_if_hard_path(register const char *dir_name) |
133 | 0 | { |
134 | 0 | if (dir_name[0] == FN_HOMELIB && dir_name[1] == FN_LIBCHAR) |
135 | 0 | return (home_dir != NullS && test_if_hard_path(home_dir)); |
136 | 0 | if (dir_name[0] == FN_LIBCHAR) |
137 | 0 | return (TRUE); |
138 | | #ifdef FN_DEVCHAR |
139 | | return (strchr(dir_name,FN_DEVCHAR) != 0); |
140 | | #else |
141 | 0 | return FALSE; |
142 | 0 | #endif |
143 | 0 | } /* test_if_hard_path */ |
144 | | |
145 | | |
146 | | /* |
147 | | Test if a name contains an (absolute or relative) path. |
148 | | |
149 | | SYNOPSIS |
150 | | has_path() |
151 | | name The name to test. |
152 | | |
153 | | RETURN |
154 | | TRUE name contains a path. |
155 | | FALSE name does not contain a path. |
156 | | */ |
157 | | |
158 | | my_bool has_path(const char *name) |
159 | 0 | { |
160 | 0 | return MY_TEST(strchr(name, FN_LIBCHAR)) |
161 | | #if FN_LIBCHAR != '/' |
162 | | || MY_TEST(strchr(name, '/')) |
163 | | #endif |
164 | | #ifdef FN_DEVCHAR |
165 | | || MY_TEST(strchr(name, FN_DEVCHAR)) |
166 | | #endif |
167 | 0 | ; |
168 | 0 | } |