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-1301 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(__WIN__)
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
47int my_getwd(char * buf, size_t size, myf MyFlags)
48{
49 char * pos;
50 DBUG_ENTER("my_getwd");
51 DBUG_PRINT("my",("buf:%p size: %u MyFlags %lu",
52 buf, (uint) size, MyFlags));
53
54 if (size < 1)
55 DBUG_RETURN(-1);
56
57 if (curr_dir[0]) /* Current pos is saved here */
58 (void) strmake(buf,&curr_dir[0],size-1);
59 else
60 {
61#if defined(HAVE_GETCWD)
62 if (size < 2)
63 DBUG_RETURN(-1);
64 if (!getcwd(buf,(uint) (size-2)) && MyFlags & MY_WME)
65 {
66 my_errno=errno;
67 my_error(EE_GETWD,MYF(ME_BELL+ME_WAITTANG),errno);
68 DBUG_RETURN(-1);
69 }
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 if (*((pos=strend(buf))-1) != FN_LIBCHAR) /* End with FN_LIBCHAR */
80 {
81 pos[0]= FN_LIBCHAR;
82 pos[1]=0;
83 }
84 (void) strmake(&curr_dir[0],buf, (size_t) (FN_REFLEN-1));
85 }
86 DBUG_RETURN(0);
87} /* my_getwd */
88
89
90/* Set new working directory */
91
92int my_setwd(const char *dir, myf MyFlags)
93{
94 int res;
95 size_t length;
96 char *start, *pos;
97 DBUG_ENTER("my_setwd");
98 DBUG_PRINT("my",("dir: '%s' MyFlags %lu", dir, MyFlags));
99
100 start=(char *) dir;
101 if (! dir[0] || (dir[0] == FN_LIBCHAR && dir[1] == 0))
102 dir=FN_ROOTDIR;
103 if ((res=chdir((char*) dir)) != 0)
104 {
105 my_errno=errno;
106 if (MyFlags & MY_WME)
107 my_error(EE_SETWD,MYF(ME_BELL+ME_WAITTANG),start,errno);
108 }
109 else
110 {
111 if (test_if_hard_path(start))
112 { /* Hard pathname */
113 pos= strmake(&curr_dir[0],start,(size_t) FN_REFLEN-1);
114 if (pos[-1] != FN_LIBCHAR)
115 {
116 length=(uint) (pos-(char*) curr_dir);
117 curr_dir[length]=FN_LIBCHAR; /* must end with '/' */
118 curr_dir[length+1]='\0';
119 }
120 }
121 else
122 curr_dir[0]='\0'; /* Don't save name */
123 }
124 DBUG_RETURN(res);
125} /* my_setwd */
126
127
128
129 /* Test if hard pathname */
130 /* Returns 1 if dirname is a hard path */
131
132int test_if_hard_path(register const char *dir_name)
133{
134 if (dir_name[0] == FN_HOMELIB && dir_name[1] == FN_LIBCHAR)
135 return (home_dir != NullS && test_if_hard_path(home_dir));
136 if (dir_name[0] == FN_LIBCHAR)
137 return (TRUE);
138#ifdef FN_DEVCHAR
139 return (strchr(dir_name,FN_DEVCHAR) != 0);
140#else
141 return FALSE;
142#endif
143} /* 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
158my_bool has_path(const char *name)
159{
160 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 ;
168}
169