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(__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 
47 int 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 
92 int 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 
132 int 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 
158 my_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