Mercurial > vim
annotate src/dosinst.h @ 6811:cc3f3d35c549 v7.4.727
patch 7.4.727
Problem: Cannot build GvimExt with MingW.
Solution: Add -lgdi32. (KF Leong)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Wed, 06 May 2015 06:51:50 +0200 |
parents | 7d1044b27eb5 |
children | b6cb94ad97a4 |
rev | line source |
---|---|
7 | 1 /* vi:set ts=8 sts=4 sw=4: |
2 * | |
3 * VIM - Vi IMproved by Bram Moolenaar | |
4 * | |
5 * Do ":help uganda" in Vim to read copying and usage conditions. | |
6 * Do ":help credits" in Vim to see a list of people who contributed. | |
7 * See README.txt for an overview of the Vim source code. | |
8 */ | |
9 /* | |
10 * dosinst.h: Common code for dosinst.c and uninstal.c | |
11 */ | |
714 | 12 |
13 /* Visual Studio 2005 has 'deprecated' many of the standard CRT functions */ | |
14 #if _MSC_VER >= 1400 | |
15 # define _CRT_SECURE_NO_DEPRECATE | |
16 # define _CRT_NONSTDC_NO_DEPRECATE | |
17 #endif | |
18 | |
7 | 19 #include <stdio.h> |
20 #include <stdlib.h> | |
21 #include <string.h> | |
22 #include <sys/stat.h> | |
23 #include <fcntl.h> | |
24 | |
25 #ifndef UNIX_LINT | |
714 | 26 # include "vimio.h" |
7 | 27 # include <ctype.h> |
28 | |
29 # ifndef __CYGWIN__ | |
30 # include <direct.h> | |
31 # endif | |
32 | |
33 # if defined(_WIN64) || defined(WIN32) | |
34 # define WIN3264 | |
35 # include <windows.h> | |
36 # include <shlobj.h> | |
37 # else | |
38 # include <dir.h> | |
39 # include <bios.h> | |
40 # include <dos.h> | |
41 # endif | |
42 #endif | |
43 | |
44 #ifdef UNIX_LINT | |
45 /* Running lint on Unix: Some things are missing. */ | |
46 char *searchpath(char *name); | |
47 #endif | |
48 | |
49 #if defined(DJGPP) || defined(UNIX_LINT) | |
50 # include <unistd.h> | |
51 # include <errno.h> | |
52 #endif | |
53 | |
54 #include "version.h" | |
55 | |
56 #if defined(DJGPP) || defined(UNIX_LINT) | |
57 # define vim_mkdir(x, y) mkdir((char *)(x), y) | |
58 #else | |
59 # if defined(WIN3264) && !defined(__BORLANDC__) | |
60 # define vim_mkdir(x, y) _mkdir((char *)(x)) | |
61 # else | |
62 # define vim_mkdir(x, y) mkdir((char *)(x)) | |
63 # endif | |
64 #endif | |
2287
573da4dac306
Make the dos installer work with more compilers.
Bram Moolenaar <bram@vim.org>
parents:
2217
diff
changeset
|
65 |
573da4dac306
Make the dos installer work with more compilers.
Bram Moolenaar <bram@vim.org>
parents:
2217
diff
changeset
|
66 #ifndef DJGPP |
573da4dac306
Make the dos installer work with more compilers.
Bram Moolenaar <bram@vim.org>
parents:
2217
diff
changeset
|
67 # define sleep(n) Sleep((n) * 1000) |
573da4dac306
Make the dos installer work with more compilers.
Bram Moolenaar <bram@vim.org>
parents:
2217
diff
changeset
|
68 #endif |
573da4dac306
Make the dos installer work with more compilers.
Bram Moolenaar <bram@vim.org>
parents:
2217
diff
changeset
|
69 |
7 | 70 /* ---------------------------------------- */ |
71 | |
72 | |
73 #define BUFSIZE 512 /* long enough to hold a file name path */ | |
74 #define NUL 0 | |
75 | |
76 #define FAIL 0 | |
77 #define OK 1 | |
78 | |
79 #ifndef FALSE | |
80 # define FALSE 0 | |
81 #endif | |
82 #ifndef TRUE | |
83 # define TRUE 1 | |
84 #endif | |
85 | |
2449
943280505f72
Fix that uninstaller isn't found on 64-bit Windows.
Bram Moolenaar <bram@vim.org>
parents:
2287
diff
changeset
|
86 /* |
943280505f72
Fix that uninstaller isn't found on 64-bit Windows.
Bram Moolenaar <bram@vim.org>
parents:
2287
diff
changeset
|
87 * Modern way of creating registry entries, also works on 64 bit windows when |
943280505f72
Fix that uninstaller isn't found on 64-bit Windows.
Bram Moolenaar <bram@vim.org>
parents:
2287
diff
changeset
|
88 * compiled as a 32 bit program. |
943280505f72
Fix that uninstaller isn't found on 64-bit Windows.
Bram Moolenaar <bram@vim.org>
parents:
2287
diff
changeset
|
89 */ |
943280505f72
Fix that uninstaller isn't found on 64-bit Windows.
Bram Moolenaar <bram@vim.org>
parents:
2287
diff
changeset
|
90 # ifndef KEY_WOW64_64KEY |
943280505f72
Fix that uninstaller isn't found on 64-bit Windows.
Bram Moolenaar <bram@vim.org>
parents:
2287
diff
changeset
|
91 # define KEY_WOW64_64KEY 0x0100 |
943280505f72
Fix that uninstaller isn't found on 64-bit Windows.
Bram Moolenaar <bram@vim.org>
parents:
2287
diff
changeset
|
92 # endif |
943280505f72
Fix that uninstaller isn't found on 64-bit Windows.
Bram Moolenaar <bram@vim.org>
parents:
2287
diff
changeset
|
93 |
7 | 94 #define VIM_STARTMENU "Programs\\Vim " VIM_VERSION_SHORT |
95 | |
96 int interactive; /* non-zero when running interactively */ | |
97 | |
98 /* | |
99 * Call malloc() and exit when out of memory. | |
100 */ | |
101 static void * | |
102 alloc(int len) | |
103 { | |
104 char *s; | |
105 | |
106 s = malloc(len); | |
107 if (s == NULL) | |
108 { | |
109 printf("ERROR: out of memory\n"); | |
110 exit(1); | |
111 } | |
112 return (void *)s; | |
113 } | |
114 | |
115 /* | |
116 * The toupper() in Bcc 5.5 doesn't work, use our own implementation. | |
117 */ | |
118 static int | |
119 mytoupper(int c) | |
120 { | |
121 if (c >= 'a' && c <= 'z') | |
122 return c - 'a' + 'A'; | |
123 return c; | |
124 } | |
125 | |
126 static void | |
127 myexit(int n) | |
128 { | |
129 if (!interactive) | |
130 { | |
131 /* Present a prompt, otherwise error messages can't be read. */ | |
132 printf("Press Enter to continue\n"); | |
133 rewind(stdin); | |
134 (void)getchar(); | |
135 } | |
136 exit(n); | |
137 } | |
138 | |
139 #ifdef WIN3264 | |
140 /* This symbol is not defined in older versions of the SDK or Visual C++ */ | |
141 | |
142 #ifndef VER_PLATFORM_WIN32_WINDOWS | |
143 # define VER_PLATFORM_WIN32_WINDOWS 1 | |
144 #endif | |
145 | |
146 static DWORD g_PlatformId; | |
147 | |
148 /* | |
149 * Set g_PlatformId to VER_PLATFORM_WIN32_NT (NT) or | |
150 * VER_PLATFORM_WIN32_WINDOWS (Win95). | |
151 */ | |
152 static void | |
153 PlatformId(void) | |
154 { | |
155 static int done = FALSE; | |
156 | |
157 if (!done) | |
158 { | |
159 OSVERSIONINFO ovi; | |
160 | |
161 ovi.dwOSVersionInfoSize = sizeof(ovi); | |
162 GetVersionEx(&ovi); | |
163 | |
164 g_PlatformId = ovi.dwPlatformId; | |
165 done = TRUE; | |
166 } | |
167 } | |
168 | |
169 # ifdef __BORLANDC__ | |
170 /* Borland defines its own searchpath() in dir.h */ | |
171 # include <dir.h> | |
172 # else | |
173 static char * | |
174 searchpath(char *name) | |
175 { | |
176 static char widename[2 * BUFSIZE]; | |
177 static char location[2 * BUFSIZE + 2]; | |
178 | |
179 /* There appears to be a bug in FindExecutableA() on Windows NT. | |
180 * Use FindExecutableW() instead... */ | |
181 PlatformId(); | |
182 if (g_PlatformId == VER_PLATFORM_WIN32_NT) | |
183 { | |
184 MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)name, -1, | |
185 (LPWSTR)widename, BUFSIZE); | |
186 if (FindExecutableW((LPCWSTR)widename, (LPCWSTR)"", | |
187 (LPWSTR)location) > (HINSTANCE)32) | |
188 { | |
189 WideCharToMultiByte(CP_ACP, 0, (LPWSTR)location, -1, | |
190 (LPSTR)widename, 2 * BUFSIZE, NULL, NULL); | |
191 return widename; | |
192 } | |
193 } | |
194 else | |
195 { | |
196 if (FindExecutableA((LPCTSTR)name, (LPCTSTR)"", | |
197 (LPTSTR)location) > (HINSTANCE)32) | |
198 return location; | |
199 } | |
200 return NULL; | |
201 } | |
202 # endif | |
203 #endif | |
204 | |
205 /* | |
206 * Call searchpath() and save the result in allocated memory, or return NULL. | |
207 */ | |
208 static char * | |
209 searchpath_save(char *name) | |
210 { | |
211 char *p; | |
212 char *s; | |
213 | |
214 p = searchpath(name); | |
215 if (p == NULL) | |
216 return NULL; | |
217 s = alloc(strlen(p) + 1); | |
218 strcpy(s, p); | |
219 return s; | |
220 } | |
221 | |
222 #ifdef WIN3264 | |
826 | 223 |
224 #ifndef CSIDL_COMMON_PROGRAMS | |
225 # define CSIDL_COMMON_PROGRAMS 0x0017 | |
226 #endif | |
227 #ifndef CSIDL_COMMON_DESKTOPDIRECTORY | |
228 # define CSIDL_COMMON_DESKTOPDIRECTORY 0x0019 | |
229 #endif | |
230 | |
7 | 231 /* |
232 * Get the path to a requested Windows shell folder. | |
233 * | |
234 * Return FAIL on error, OK on success | |
235 */ | |
236 int | |
237 get_shell_folder_path( | |
238 char *shell_folder_path, | |
239 const char *shell_folder_name) | |
240 { | |
241 /* | |
242 * The following code was successfully built with make_mvc.mak. | |
243 * The resulting executable worked on Windows 95, Millennium Edition, and | |
244 * 2000 Professional. But it was changed after testing... | |
245 */ | |
246 LPITEMIDLIST pidl = 0; /* Pointer to an Item ID list allocated below */ | |
247 LPMALLOC pMalloc; /* Pointer to an IMalloc interface */ | |
248 int csidl; | |
249 int alt_csidl = -1; | |
250 static int desktop_csidl = -1; | |
251 static int programs_csidl = -1; | |
252 int *pcsidl; | |
253 int r; | |
254 | |
255 if (strcmp(shell_folder_name, "desktop") == 0) | |
256 { | |
257 pcsidl = &desktop_csidl; | |
258 csidl = CSIDL_COMMON_DESKTOPDIRECTORY; | |
259 alt_csidl = CSIDL_DESKTOP; | |
260 } | |
261 else if (strncmp(shell_folder_name, "Programs", 8) == 0) | |
262 { | |
263 pcsidl = &programs_csidl; | |
264 csidl = CSIDL_COMMON_PROGRAMS; | |
265 alt_csidl = CSIDL_PROGRAMS; | |
266 } | |
267 else | |
268 { | |
269 printf("\nERROR (internal) unrecognised shell_folder_name: \"%s\"\n\n", | |
270 shell_folder_name); | |
271 return FAIL; | |
272 } | |
273 | |
274 /* Did this stuff before, use the same ID again. */ | |
275 if (*pcsidl >= 0) | |
276 { | |
277 csidl = *pcsidl; | |
278 alt_csidl = -1; | |
279 } | |
280 | |
281 retry: | |
282 /* Initialize pointer to IMalloc interface */ | |
283 if (NOERROR != SHGetMalloc(&pMalloc)) | |
284 { | |
285 printf("\nERROR getting interface for shell_folder_name: \"%s\"\n\n", | |
286 shell_folder_name); | |
287 return FAIL; | |
288 } | |
289 | |
290 /* Get an ITEMIDLIST corresponding to the folder code */ | |
291 if (NOERROR != SHGetSpecialFolderLocation(0, csidl, &pidl)) | |
292 { | |
293 if (alt_csidl < 0 || NOERROR != SHGetSpecialFolderLocation(0, | |
294 alt_csidl, &pidl)) | |
295 { | |
296 printf("\nERROR getting ITEMIDLIST for shell_folder_name: \"%s\"\n\n", | |
297 shell_folder_name); | |
298 return FAIL; | |
299 } | |
300 csidl = alt_csidl; | |
301 alt_csidl = -1; | |
302 } | |
303 | |
304 /* Translate that ITEMIDLIST to a string */ | |
305 r = SHGetPathFromIDList(pidl, shell_folder_path); | |
306 | |
307 /* Free the data associated with pidl */ | |
308 pMalloc->lpVtbl->Free(pMalloc, pidl); | |
309 /* Release the IMalloc interface */ | |
310 pMalloc->lpVtbl->Release(pMalloc); | |
311 | |
312 if (!r) | |
313 { | |
314 if (alt_csidl >= 0) | |
315 { | |
316 /* We probably get here for Windows 95: the "all users" | |
317 * desktop/start menu entry doesn't exist. */ | |
318 csidl = alt_csidl; | |
319 alt_csidl = -1; | |
320 goto retry; | |
321 } | |
322 printf("\nERROR translating ITEMIDLIST for shell_folder_name: \"%s\"\n\n", | |
323 shell_folder_name); | |
324 return FAIL; | |
325 } | |
326 | |
327 /* If there is an alternative: verify we can write in this directory. | |
328 * This should cause a retry when the "all users" directory exists but we | |
329 * are a normal user and can't write there. */ | |
330 if (alt_csidl >= 0) | |
331 { | |
332 char tbuf[BUFSIZE]; | |
333 FILE *fd; | |
334 | |
335 strcpy(tbuf, shell_folder_path); | |
336 strcat(tbuf, "\\vim write test"); | |
337 fd = fopen(tbuf, "w"); | |
338 if (fd == NULL) | |
339 { | |
340 csidl = alt_csidl; | |
341 alt_csidl = -1; | |
342 goto retry; | |
343 } | |
344 fclose(fd); | |
345 unlink(tbuf); | |
346 } | |
347 | |
348 /* | |
349 * Keep the found csidl for next time, so that we don't have to do the | |
350 * write test every time. | |
351 */ | |
352 if (*pcsidl < 0) | |
353 *pcsidl = csidl; | |
354 | |
355 if (strncmp(shell_folder_name, "Programs\\", 9) == 0) | |
356 strcat(shell_folder_path, shell_folder_name + 8); | |
357 | |
358 return OK; | |
359 } | |
360 #endif | |
361 | |
362 /* | |
363 * List of targets. The first one (index zero) is used for the default path | |
364 * for the batch files. | |
365 */ | |
782 | 366 #define TARGET_COUNT 9 |
7 | 367 |
368 struct | |
369 { | |
370 char *name; /* Vim exe name (without .exe) */ | |
371 char *batname; /* batch file name */ | |
372 char *lnkname; /* shortcut file name */ | |
373 char *exename; /* exe file name */ | |
374 char *exenamearg; /* exe file name when using exearg */ | |
375 char *exearg; /* argument for vim.exe or gvim.exe */ | |
376 char *oldbat; /* path to existing xxx.bat or NULL */ | |
377 char *oldexe; /* path to existing xxx.exe or NULL */ | |
378 char batpath[BUFSIZE]; /* path of batch file to create; not | |
379 created when it's empty */ | |
380 } targets[TARGET_COUNT] = | |
381 { | |
382 {"all", "batch files"}, | |
383 {"vim", "vim.bat", "Vim.lnk", | |
384 "vim.exe", "vim.exe", ""}, | |
385 {"gvim", "gvim.bat", "gVim.lnk", | |
386 "gvim.exe", "gvim.exe", ""}, | |
387 {"evim", "evim.bat", "gVim Easy.lnk", | |
388 "evim.exe", "gvim.exe", "-y"}, | |
389 {"view", "view.bat", "Vim Read-only.lnk", | |
390 "view.exe", "vim.exe", "-R"}, | |
391 {"gview", "gview.bat", "gVim Read-only.lnk", | |
392 "gview.exe", "gvim.exe", "-R"}, | |
393 {"vimdiff", "vimdiff.bat", "Vim Diff.lnk", | |
394 "vimdiff.exe","vim.exe", "-d"}, | |
395 {"gvimdiff","gvimdiff.bat", "gVim Diff.lnk", | |
396 "gvimdiff.exe","gvim.exe", "-d"}, | |
782 | 397 {"vimtutor","vimtutor.bat", "Vim tutor.lnk", |
398 "vimtutor.bat", "vimtutor.bat", ""}, | |
7 | 399 }; |
400 | |
401 #define ICON_COUNT 3 | |
402 char *(icon_names[ICON_COUNT]) = | |
403 {"gVim " VIM_VERSION_SHORT, | |
404 "gVim Easy " VIM_VERSION_SHORT, | |
405 "gVim Read only " VIM_VERSION_SHORT}; | |
406 char *(icon_link_names[ICON_COUNT]) = | |
407 {"gVim " VIM_VERSION_SHORT ".lnk", | |
408 "gVim Easy " VIM_VERSION_SHORT ".lnk", | |
409 "gVim Read only " VIM_VERSION_SHORT ".lnk"}; | |
410 | |
2287
573da4dac306
Make the dos installer work with more compilers.
Bram Moolenaar <bram@vim.org>
parents:
2217
diff
changeset
|
411 /* This is only used for dosinst.c when WIN3264 is defined and for uninstal.c |
573da4dac306
Make the dos installer work with more compilers.
Bram Moolenaar <bram@vim.org>
parents:
2217
diff
changeset
|
412 * when not being able to directly access registry entries. */ |
573da4dac306
Make the dos installer work with more compilers.
Bram Moolenaar <bram@vim.org>
parents:
2217
diff
changeset
|
413 #if (defined(DOSINST) && defined(WIN3264)) \ |
573da4dac306
Make the dos installer work with more compilers.
Bram Moolenaar <bram@vim.org>
parents:
2217
diff
changeset
|
414 || (!defined(DOSINST) && !defined(WIN3264)) |
7 | 415 /* |
416 * Run an external command and wait for it to finish. | |
417 */ | |
418 static void | |
419 run_command(char *cmd) | |
420 { | |
421 char *cmd_path; | |
422 char cmd_buf[BUFSIZE]; | |
423 char *p; | |
424 | |
425 /* On WinNT, 'start' is a shell built-in for cmd.exe rather than an | |
426 * executable (start.exe) like in Win9x. DJGPP, being a DOS program, | |
427 * is given the COMSPEC command.com by WinNT, so we have to find | |
428 * cmd.exe manually and use it. */ | |
429 cmd_path = searchpath_save("cmd.exe"); | |
430 if (cmd_path != NULL) | |
431 { | |
432 /* There is a cmd.exe, so this might be Windows NT. If it is, | |
433 * we need to call cmd.exe explicitly. If it is a later OS, | |
434 * calling cmd.exe won't hurt if it is present. | |
2217
120502692d82
Improve the MS-Windows installer.
Bram Moolenaar <bram@vim.org>
parents:
1222
diff
changeset
|
435 * Also, "start" on NT expects a window title argument. |
7 | 436 */ |
437 /* Replace the slashes with backslashes. */ | |
438 while ((p = strchr(cmd_path, '/')) != NULL) | |
439 *p = '\\'; | |
2217
120502692d82
Improve the MS-Windows installer.
Bram Moolenaar <bram@vim.org>
parents:
1222
diff
changeset
|
440 sprintf(cmd_buf, "%s /c start \"vimcmd\" /wait %s", cmd_path, cmd); |
7 | 441 free(cmd_path); |
442 } | |
443 else | |
444 { | |
445 /* No cmd.exe, just make the call and let the system handle it. */ | |
446 sprintf(cmd_buf, "start /w %s", cmd); | |
447 } | |
448 system(cmd_buf); | |
449 } | |
450 #endif | |
451 | |
452 /* | |
453 * Append a backslash to "name" if there isn't one yet. | |
454 */ | |
455 static void | |
456 add_pathsep(char *name) | |
457 { | |
458 int len = strlen(name); | |
459 | |
460 if (len > 0 && name[len - 1] != '\\' && name[len - 1] != '/') | |
461 strcat(name, "\\"); | |
462 } | |
463 | |
464 /* | |
465 * The normal chdir() does not change the default drive. This one does. | |
466 */ | |
467 /*ARGSUSED*/ | |
468 int | |
469 change_drive(int drive) | |
470 { | |
471 #ifdef WIN3264 | |
472 char temp[3] = "-:"; | |
473 temp[0] = (char)(drive + 'A' - 1); | |
474 return !SetCurrentDirectory(temp); | |
475 #else | |
476 # ifndef UNIX_LINT | |
477 union REGS regs; | |
478 | |
479 regs.h.ah = 0x0e; | |
480 regs.h.dl = drive - 1; | |
481 intdos(®s, ®s); /* set default drive */ | |
482 regs.h.ah = 0x19; | |
483 intdos(®s, ®s); /* get default drive */ | |
484 if (regs.h.al == drive - 1) | |
485 return 0; | |
486 # endif | |
487 return -1; | |
488 #endif | |
489 } | |
490 | |
491 /* | |
492 * Change directory to "path". | |
493 * Return 0 for success, -1 for failure. | |
494 */ | |
495 int | |
496 mch_chdir(char *path) | |
497 { | |
498 if (path[0] == NUL) /* just checking... */ | |
499 return 0; | |
500 if (path[1] == ':') /* has a drive name */ | |
501 { | |
502 if (change_drive(mytoupper(path[0]) - 'A' + 1)) | |
503 return -1; /* invalid drive name */ | |
504 path += 2; | |
505 } | |
506 if (*path == NUL) /* drive name only */ | |
507 return 0; | |
508 return chdir(path); /* let the normal chdir() do the rest */ | |
509 } | |
510 | |
511 /* | |
512 * Expand the executable name into a full path name. | |
513 */ | |
514 #if defined(__BORLANDC__) && !defined(WIN3264) | |
515 | |
516 /* Only Borland C++ has this. */ | |
517 # define my_fullpath(b, n, l) _fullpath(b, n, l) | |
518 | |
519 #else | |
520 static char * | |
521 my_fullpath(char *buf, char *fname, int len) | |
522 { | |
523 # ifdef WIN3264 | |
524 /* Only GetModuleFileName() will get the long file name path. | |
525 * GetFullPathName() may still use the short (FAT) name. */ | |
526 DWORD len_read = GetModuleFileName(NULL, buf, (size_t)len); | |
527 | |
528 return (len_read > 0 && len_read < (DWORD)len) ? buf : NULL; | |
529 # else | |
530 char olddir[BUFSIZE]; | |
531 char *p, *q; | |
532 int c; | |
533 char *retval = buf; | |
534 | |
1222 | 535 if (strchr(fname, ':') != NULL) /* already expanded */ |
7 | 536 { |
537 strncpy(buf, fname, len); | |
538 } | |
539 else | |
540 { | |
541 *buf = NUL; | |
542 /* | |
543 * change to the directory for a moment, | |
544 * and then do the getwd() (and get back to where we were). | |
545 * This will get the correct path name with "../" things. | |
546 */ | |
547 p = strrchr(fname, '/'); | |
548 q = strrchr(fname, '\\'); | |
549 if (q != NULL && (p == NULL || q > p)) | |
550 p = q; | |
551 q = strrchr(fname, ':'); | |
552 if (q != NULL && (p == NULL || q > p)) | |
553 p = q; | |
554 if (p != NULL) | |
555 { | |
556 if (getcwd(olddir, BUFSIZE) == NULL) | |
557 { | |
558 p = NULL; /* can't get current dir: don't chdir */ | |
559 retval = NULL; | |
560 } | |
561 else | |
562 { | |
563 if (p == fname) /* /fname */ | |
564 q = p + 1; /* -> / */ | |
565 else if (q + 1 == p) /* ... c:\foo */ | |
566 q = p + 1; /* -> c:\ */ | |
567 else /* but c:\foo\bar */ | |
568 q = p; /* -> c:\foo */ | |
569 | |
570 c = *q; /* truncate at start of fname */ | |
571 *q = NUL; | |
572 if (mch_chdir(fname)) /* change to the directory */ | |
573 retval = NULL; | |
574 else | |
575 { | |
576 fname = q; | |
577 if (c == '\\') /* if we cut the name at a */ | |
578 fname++; /* '\', don't add it again */ | |
579 } | |
580 *q = c; | |
581 } | |
582 } | |
583 if (getcwd(buf, len) == NULL) | |
584 { | |
585 retval = NULL; | |
586 *buf = NUL; | |
587 } | |
588 /* | |
589 * Concatenate the file name to the path. | |
590 */ | |
591 if (strlen(buf) + strlen(fname) >= len - 1) | |
592 { | |
593 printf("ERROR: File name too long!\n"); | |
594 myexit(1); | |
595 } | |
596 add_pathsep(buf); | |
597 strcat(buf, fname); | |
598 if (p) | |
599 mch_chdir(olddir); | |
600 } | |
601 | |
602 /* Replace forward slashes with backslashes, required for the path to a | |
603 * command. */ | |
604 while ((p = strchr(buf, '/')) != NULL) | |
605 *p = '\\'; | |
606 | |
607 return retval; | |
608 # endif | |
609 } | |
610 #endif | |
611 | |
612 /* | |
613 * Remove the tail from a file or directory name. | |
614 * Puts a NUL on the last '/' or '\'. | |
615 */ | |
616 static void | |
617 remove_tail(char *path) | |
618 { | |
619 int i; | |
620 | |
621 for (i = strlen(path) - 1; i > 0; --i) | |
622 if (path[i] == '/' || path[i] == '\\') | |
623 { | |
624 path[i] = NUL; | |
625 break; | |
626 } | |
627 } | |
628 | |
629 | |
630 char installdir[BUFSIZE]; /* top of the installation dir, where the | |
631 install.exe is located, E.g.: | |
632 "c:\vim\vim60" */ | |
633 int runtimeidx; /* index in installdir[] where "vim60" starts */ | |
634 char *sysdrive; /* system drive or "c:\" */ | |
635 | |
636 /* | |
637 * Setup for using this program. | |
638 * Sets "installdir[]". | |
639 */ | |
640 static void | |
641 do_inits(char **argv) | |
642 { | |
643 #ifdef DJGPP | |
644 /* | |
645 * Use Long File Names by default, if $LFN not set. | |
646 */ | |
647 if (getenv("LFN") == NULL) | |
648 putenv("LFN=y"); | |
649 #endif | |
650 | |
651 /* Find out the full path of our executable. */ | |
652 if (my_fullpath(installdir, argv[0], BUFSIZE) == NULL) | |
653 { | |
654 printf("ERROR: Cannot get name of executable\n"); | |
655 myexit(1); | |
656 } | |
657 /* remove the tail, the executable name "install.exe" */ | |
658 remove_tail(installdir); | |
659 | |
660 /* change to the installdir */ | |
661 mch_chdir(installdir); | |
662 | |
663 /* Find the system drive. Only used for searching the Vim executable, not | |
664 * very important. */ | |
665 sysdrive = getenv("SYSTEMDRIVE"); | |
666 if (sysdrive == NULL || *sysdrive == NUL) | |
667 sysdrive = "C:\\"; | |
668 } |