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