winnt-undo-backslashes-20030317
[openafs.git] / src / WINNT / afsd / fs_utils.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afs/param.h>
11 #include <afs/stds.h>
12
13 #include <windows.h>
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <errno.h>
17 #include <malloc.h>
18 #include <string.h>
19 #include <winioctl.h>
20 #include <winsock2.h>
21 #include <nb30.h>
22
23 #include <osi.h>
24 #include "afsd.h"
25 #include "smb.h"
26 #include "cmd.h"
27 #include <fs_utils.h>
28
29
30 long fs_ExtractDriveLetter(char *inPathp, char *outPathp)
31 {
32         if (inPathp[0] != 0 && inPathp[1] == ':') {
33                 /* there is a drive letter */
34                 *outPathp++ = *inPathp++;
35                 *outPathp++ = *inPathp++;
36                 *outPathp++ = 0;
37         }
38         else *outPathp = 0;
39
40         return 0;
41 }
42
43 /* strip the drive letter from a component */
44 long fs_StripDriveLetter(char *inPathp, char *outPathp, long outSize)
45 {
46         char tempBuffer[1000];
47         strcpy(tempBuffer, inPathp);
48         if (tempBuffer[0] != 0 && tempBuffer[1] == ':') {
49                 /* drive letter present */
50                 strcpy(outPathp, tempBuffer+2);
51         }
52         else {
53                 /* no drive letter present */
54                 strcpy(outPathp, tempBuffer);
55         }
56         return 0;
57 }
58
59 /* take a path with a drive letter, possibly relative, and return a full path
60  * without the drive letter.  This is the full path relative to the working
61  * dir for that drive letter.  The input and output paths can be the same.
62  */
63 long fs_GetFullPath(char *pathp, char *outPathp, long outSize)
64 {
65         char tpath[1000];
66         char origPath[1000];
67         char *firstp;
68         long code;
69         int pathHasDrive;
70         int doSwitch;
71         char newPath[3];
72
73         if (pathp[0] != 0 && pathp[1] == ':') {
74                 /* there's a drive letter there */
75                 firstp = pathp+2;
76                 pathHasDrive = 1;
77         }
78         else {
79                 firstp = pathp;
80                 pathHasDrive = 0;
81         }
82         
83         if (*firstp == '\\' || *firstp == '/') {
84                 /* already an absolute pathname, just copy it back */
85                 strcpy(outPathp, firstp);
86                 return 0;
87         }
88         
89         GetCurrentDirectory(sizeof(origPath), origPath);
90         
91         doSwitch = 0;
92         if (pathHasDrive && (*pathp & ~0x20) != (origPath[0] & ~0x20)) {
93                 /* a drive has been specified and it isn't our current drive.
94                  * to get path, switch to it first.  Must case-fold drive letters
95                  * for user convenience.
96                  */
97                 doSwitch = 1;
98                 newPath[0] = *pathp;
99                 newPath[1] = ':';
100                 newPath[2] = 0;
101                 if (!SetCurrentDirectory(newPath)) {
102                         code = GetLastError();
103                         return code;
104                 }
105         }
106         
107         /* now get the absolute path to the current wdir in this drive */
108         GetCurrentDirectory(sizeof(tpath), tpath);
109         strcpy(outPathp, tpath+2);      /* skip drive letter */
110         /* if there is a non-null name after the drive, append it */
111         if (*firstp != 0) {
112                 strcat(outPathp, "\\");
113                 strcat(outPathp, firstp);
114         }
115
116         /* finally, if necessary, switch back to our home drive letter */
117         if (doSwitch) {
118                 SetCurrentDirectory(origPath);
119         }
120         
121         return 0;
122 }
123
124 struct hostent *hostutil_GetHostByName(char *namep)
125 {
126         struct hostent *thp;
127         
128         thp = gethostbyname(namep);
129         return thp;
130 }
131
132 /* get hostname or addr, given addr in network byte order */
133 char *hostutil_GetNameByINet(long addr)
134 {
135         static char hostNameBuffer[256];
136         struct hostent *thp;
137         
138         thp = gethostbyaddr((char *) &addr, sizeof(long), AF_INET);
139         if (thp)
140                 strcpy(hostNameBuffer, thp->h_name);
141         else {
142                 sprintf(hostNameBuffer, "%d.%d.%d.%d",
143                         addr & 0xff,
144                         (addr >> 8) & 0xff,
145                         (addr >> 16) & 0xff,
146                         (addr >> 24) & 0xff);
147         }
148
149         /* return static buffer */
150         return hostNameBuffer;
151 }
152
153 /* is this a digit or a digit-like thing? */
154 static int ismeta(ac, abase)
155 register int abase;
156 register int ac; {
157 /*    if (ac == '-' || ac == 'x' || ac == 'X') return 1; */
158     if (ac >= '0' && ac <= '7') return 1;
159     if (abase <= 8) return 0;
160     if (ac >= '8' && ac <= '9') return 1;
161     if (abase <= 10) return 0;
162     if (ac >= 'a' && ac <= 'f') return 1;
163     if (ac >= 'A' && ac <= 'F') return 1;
164     return 0;
165 }
166
167 /* given that this is a digit or a digit-like thing, compute its value */
168 static int getmeta(ac)
169 register int ac; {
170     if (ac >= '0' && ac <= '9') return ac - '0';
171     if (ac >= 'a' && ac <= 'f') return ac - 'a' + 10;
172     if (ac >= 'A' && ac <= 'F') return ac - 'A' + 10;
173     return 0;
174 }
175
176 long util_GetInt32 (as, aval)
177 register char *as;
178 long *aval;
179 {
180     register long total;
181     register int tc;
182     int base;
183     int negative;
184
185     total = 0;  /* initialize things */
186     negative = 0;
187
188     /* skip over leading spaces */
189     while (tc = *as) {
190         if (tc != ' ' && tc != '\t') break;
191     }
192
193     /* compute sign */
194     if (*as == '-') {
195         negative = 1;
196         as++;   /* skip over character */
197     }
198
199     /* compute the base */
200     if (*as == '0') {
201         as++;
202         if (*as == 'x' || *as == 'X') {
203             base = 16;
204             as++;
205         }
206         else base = 8;
207     }
208     else base = 10;
209
210     /* compute the # itself */
211     while(tc = *as) {
212         if (!ismeta(tc, base)) return -1;
213         total *= base;
214         total += getmeta(tc);
215         as++;
216     }
217
218     if (negative) *aval = -total;
219     else *aval = total;
220     return 0;
221 }