source: trunk/dll/pathutil.c

Last change on this file was 1880, checked in by Gregg Young, 10 years ago

Remove dead code and comments from remaining c files. #if 0 and #if NEVER were not addressed

  • Property svn:keywords set to Author Date Id Revision
File size: 12.3 KB
Line 
1
2/***********************************************************************
3
4 $Id: pathutil.c 1880 2015-10-12 18:26:16Z gyoung $
5
6 Path handling utility functions
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2009 Steven H. Levine
10
11 05 Jan 08 SHL Move from arccnrs.c and comp.c to here
12 06 Jan 08 GKY Add NormalizeCmdLine to check program strings on entry
13 29 Feb 08 GKY Changes to enable user settable command line length
14 15 Oct 08 GKY Fix NormalizeCmdLine to check all 5 executable extensions when no extension provided;
15 use searchapath to check for existance of file types not checked by DosQAppType;
16 close DosFind.
17 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code
18 12 Jul 09 GKY Add xDosQueryAppType and xDosAlloc... to allow FM/2 to load in high memory
19 23 Oct 10 GKY Add ForwardslashToBackslash function to streamline code
20 17 Sep 11 GKY Fix commandline quoting issues
21 01 Mar 14 JBS Ticket #524: Made "searchapath" thread-safe. Function names and signatures were changed.
22 So calls to these functions had to be changed.
23 21 Mar 14 SHL Add IsAbsolutePath
24 28 Jun 14 GKY Fix errors identified with CPPCheck;
25
26***********************************************************************/
27
28#include <stdlib.h>
29#include <string.h>
30#include <ctype.h>
31
32#define INCL_WIN
33#define INCL_DOS
34#define INCL_LONGLONG
35
36#include "fm3dll.h" // needs_quoting
37#include "notebook.h" // Data declaration(s)
38#include "init.h" // Data declaration(s)
39#include "fm3str.h"
40#include "srchpath.h" // Search*Path*ForFile
41#include "pathutil.h"
42#include "strips.h" // remove_first_occurence_of_character
43#include "valid.h" // needs_quoting
44#include "errutil.h" // Dos_Error...
45#include "strutil.h" // GetPString
46#include "wrappers.h" // xmalloc
47#include "fortify.h"
48#include "stristr.h" //stristr
49
50static PSZ pszSrcFile = __FILE__;
51
52PSZ ForwardslashToBackslash(PSZ pszPathName)
53{
54 CHAR *p;
55
56 p = pszPathName;
57 while (*p) {
58 if (*p == '/')
59 *p = '\\';
60 p++;
61 }
62 return pszPathName;
63}
64
65PSZ AddBackslashToPath(PSZ pszPathName)
66{
67 if (pszPathName[strlen(pszPathName) - 1] != '\\')
68 strcat(pszPathName, PCSZ_BACKSLASH);
69 return pszPathName;
70}
71
72/**
73 * Build full path name in callers buffer given directory
74 * name and filename
75 * @param pszPathName points to drive/directory if not NULL
76 * @returns pointer to full path name in caller's buffer
77 * @note OK for pszFullPathName and pszPathName to point to same buffer
78 *
79 */
80
81PSZ BldFullPathName(PSZ pszFullPathName, PCSZ pszPathName, PCSZ pszFileName)
82{
83 UINT c = pszPathName ? strlen(pszPathName) : 0;
84 if (c > 0) {
85 if (pszFullPathName != pszPathName)
86 memcpy(pszFullPathName, pszPathName, c);
87 if (pszFullPathName[c - 1] != '\\')
88 pszFullPathName[c++] = '\\';
89 }
90 strcpy(pszFullPathName + c, pszFileName);
91 return pszFullPathName;
92}
93
94/**
95 * Build quoted full path name in callers buffer given
96 * directory name and filename
97 * @param pszPathName points to drive/directory if not NULL
98 * @returns pointer to quoted path name in caller's buffer
99 */
100
101PSZ BldQuotedFullPathName(PSZ pszFullPathName, PCSZ pszPathName, PCSZ pszFileName)
102{
103 UINT c = pszPathName ? strlen(pszPathName) : 0;
104 BOOL q = needs_quoting(pszPathName) || needs_quoting(pszFileName);
105 PSZ psz = pszFullPathName;
106
107 if (q)
108 *psz++ = '"';
109 if (c > 0) {
110 memcpy(psz, pszPathName, c);
111 psz += c;
112 if (*(psz - 1) != '\\')
113 *psz++ = '\\';
114 }
115 strcpy(psz, pszFileName);
116 if (q) {
117 psz += strlen(psz);
118 *psz++ = '"';
119 *psz = 0;
120 }
121 return pszFullPathName;
122}
123
124/**
125 * Build quoted full path name in callers buffer given a filename
126 * @returns pointer to quoted file name in caller's buffer
127 */
128
129PSZ BldQuotedFileName(PSZ pszQuotedFileName, PCSZ pszFileName)
130{
131 BOOL q = needs_quoting(pszFileName);
132 PSZ psz = pszQuotedFileName;
133
134 if (q)
135 *psz++ = '"';
136 strcpy(psz, pszFileName);
137 if (q) {
138 psz += strlen(psz);
139 *psz++ = '"';
140 *psz = 0;
141 }
142 return pszQuotedFileName;
143}
144
145/**
146 * Return TRUE if absolute path name
147 * @param pszPathName points to path name
148 * @returns TRUE if absolute path, with or without drive letter
149 * @note Odd inputs return FALSE
150 *
151 */
152
153BOOL IsAbsolutePath(PCSZ pszPathName)
154{
155 return pszPathName &&
156 pszPathName[0] &&
157 ((pszPathName[0] == '\\' || pszPathName[0] == '/') ||
158 (toupper(pszPathName[0]) >= 'A' &&
159 toupper(pszPathName[0]) <= 'Z' &&
160 pszPathName[1] &&
161 pszPathName[1] == ':' &&
162 (pszPathName[2] == '\\' || pszPathName[2] == '/')));
163}
164
165/** NormalizeCmdLine
166 * Checks a command line for common errors (missing quotes, missing extension,
167 * no space between exe and args etc) Also check for the existance of the file
168 * and checks .com and .exe file headers.
169 * Command line passed as pszCmdLine_
170 * A pointer to a buffer of the size MaxComLineStrg should be supplied in
171 * pszWorkBuf. This is where the quoted etc as necessary command
172 * line string will be returned.
173 */
174
175PCSZ NormalizeCmdLine(PSZ pszWorkBuf, PSZ pszCmdLine_)
176{
177 char *szCmdLine, *szArgs;
178 char *offset = '\0', *offsetexe, *offsetcom, *offsetcmd, *offsetbtm, *offsetbat;
179 APIRET ret;
180 ULONG ulAppType;
181 char *pszChar;
182 PSZ pszNewCmdLine = pszWorkBuf;
183
184 szCmdLine = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
185 if (!szCmdLine)
186 return pszCmdLine_; //already complained
187 szArgs = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
188 if (!szArgs) {
189 free(szCmdLine);
190 return pszCmdLine_; //already complained
191 }
192 bstrip(pszCmdLine_);
193 memset(pszWorkBuf, 0, MaxComLineStrg);
194 strcpy(szCmdLine, pszCmdLine_);
195 if (szCmdLine[0] != '\0') {
196 offsetexe = stristr(pszCmdLine_, PCSZ_DOTEXE);
197 offsetcmd = stristr(pszCmdLine_, PCSZ_DOTCMD);
198 offsetcom = stristr(pszCmdLine_, PCSZ_DOTCOM);
199 offsetbtm = stristr(pszCmdLine_, PCSZ_DOTBTM);
200 offsetbat = stristr(pszCmdLine_, PCSZ_DOTBAT);
201 if (offsetexe)
202 offset = offsetexe;
203 else {
204 if (offsetcom)
205 offset = offsetcom;
206 else {
207 if (offsetcmd)
208 offset = offsetcmd;
209 else {
210 if (offsetbtm)
211 offset = offsetbtm;
212 else {
213 if (offsetbat)
214 offset = offsetexe;
215 }
216 }
217 }
218 }
219 if (offset) {
220 szCmdLine[offset + 4 - pszCmdLine_] = '\0';
221 strcpy(szArgs, &pszCmdLine_[offset + 4 - pszCmdLine_]);
222 while (strchr(szCmdLine, '\"'))
223 remove_first_occurence_of_character("\"", szCmdLine);
224 if ((szArgs[0] == '\"' && szArgs[1] == ' ') ||
225 (!strstr(pszCmdLine_, "\\:") && strchr(szArgs, '\"') &&
226 strchr(szArgs, '\"') == strrchr(szArgs, '\"')))
227 remove_first_occurence_of_character("\"", szArgs);
228 if (strchr(szArgs, '\"') != strrchr(szArgs, '\"'))
229 saymsg(MB_OK, HWND_DESKTOP,
230 NullStr,
231 GetPString(IDS_QUOTESINARGSTEXT),
232 pszCmdLine_);
233 if (!offsetexe && !offsetcom) {
234 if (!SearchPathForFile(PCSZ_PATH, szCmdLine, NULL))
235 ret = 0;
236 }
237 else
238 ret = xDosQueryAppType(szCmdLine, &ulAppType);
239 BldQuotedFileName(pszNewCmdLine, szCmdLine);
240 if (ret) {
241 ret = saymsg(MB_YESNO,
242 HWND_DESKTOP,
243 NullStr,
244 GetPString(IDS_PROGRAMNOTFOUNDTEXT),
245 pszCmdLine_);
246 if (ret == MBID_YES){
247 if (szArgs[0] != ' ')
248 strcat(pszNewCmdLine, " ");
249 strcat(pszNewCmdLine, szArgs);
250 }
251 else{
252 fCancelAction = TRUE;
253 pszNewCmdLine = pszCmdLine_;
254 }
255 }
256 else{
257 if (szArgs[0] != ' ')
258 strcat(pszNewCmdLine, " ");
259 strcat(pszNewCmdLine, szArgs);
260 }
261
262 }
263 // if it doesn't have an extension try it with all the standard ones and add if found
264 else if (!strchr(szCmdLine, '.') ||
265 strrchr(szCmdLine, '.' ) < strrchr(szCmdLine, '\\')) {
266 if (!strchr(szCmdLine, ' ')) {
267 // strip quotes readded by BuildQuotedFileName
268 while (strchr(szCmdLine, '\"'))
269 remove_first_occurence_of_character("\"", szCmdLine);
270 ret = xDosQueryAppType(szCmdLine, &ulAppType); // exe automatically appended
271 if (!ret)
272 strcat(szCmdLine, PCSZ_DOTEXE);
273 else {
274 strcat(szCmdLine, PCSZ_DOTCOM);
275 ret = xDosQueryAppType(szCmdLine, &ulAppType);
276 if (ret) {
277 offset = strrchr(szCmdLine, '.' );
278 *offset = 0;
279 strcat(szCmdLine, PCSZ_DOTCMD);
280 if (!SearchPathForFile(PCSZ_PATH, szCmdLine, NULL))
281 ret = 0;
282 else {
283 *offset = 0;
284 strcat(szCmdLine, PCSZ_DOTBAT);
285 if (!SearchPathForFile(PCSZ_PATH, szCmdLine, NULL))
286 ret = 0;
287 else {
288 *offset = 0;
289 strcat(szCmdLine, PCSZ_DOTBTM);
290 if (!SearchPathForFile(PCSZ_PATH, szCmdLine, NULL))
291 ret = 0;
292 }
293 }
294 }
295 }
296 }
297 else {
298 pszChar = szCmdLine;
299 while (pszChar) {
300 while (strchr(szCmdLine, '\"'))
301 remove_first_occurence_of_character("\"", szCmdLine);
302 if (*pszChar == ' ') { //test at every space for the end of the filename
303 *pszChar = '\0';
304 ret = xDosQueryAppType(szCmdLine, &ulAppType);
305 if (!ret) {
306 strcat(szCmdLine, PCSZ_DOTEXE);
307 break;
308 }
309 else {
310 strcat(szCmdLine, PCSZ_DOTCOM);
311 ret = xDosQueryAppType(szCmdLine, &ulAppType);
312 if (ret) {
313 offset = strrchr(szCmdLine, '.' );
314 *offset = 0;
315 strcat(szCmdLine, PCSZ_DOTCMD);
316 if (!SearchPathForFile(PCSZ_PATH, szCmdLine, NULL)) {
317 ret = 0;
318 break;
319 }
320 else {
321 *offset = 0;
322 strcat(szCmdLine, PCSZ_DOTBAT);
323 if (!SearchPathForFile(PCSZ_PATH, szCmdLine, NULL)) {
324 ret = 0;
325 break;
326 }
327 else {
328 *offset = 0;
329 strcat(szCmdLine, PCSZ_DOTBTM);
330 if (!SearchPathForFile(PCSZ_PATH, szCmdLine, NULL)) {
331 ret = 0;
332 break;
333 }
334 }
335 }
336 }
337 else
338 break;
339 }
340 }
341 strcpy(szCmdLine, pszCmdLine_);
342 pszChar++;
343 }
344 }
345 if (!ret){
346 BldQuotedFileName(pszNewCmdLine, szCmdLine);
347 strcpy(szArgs, pszCmdLine_ + strlen(szCmdLine) - 3);
348 if ((szArgs[0] == '\"' && szArgs[1] == ' ') ||
349 !strstr(pszCmdLine_, "\\:" ) ||
350 strchr(szArgs, '\"') == strrchr(szArgs, '\"'))
351 remove_first_occurence_of_character("\"", szArgs);
352 if (strchr(szArgs, '\"') != strrchr(szArgs, '\"'))
353 saymsg(MB_OK, HWND_DESKTOP,
354 NullStr,
355 GetPString(IDS_QUOTESINARGSTEXT),
356 pszCmdLine_);
357 if (szArgs[0] != ' ')
358 strcat(pszNewCmdLine, " ");
359 strcat(pszNewCmdLine, szArgs);
360 }
361 else { // fail if no extension can be found runemf2 requires one
362 ret = saymsg(MB_OK,
363 HWND_DESKTOP,
364 NullStr,
365 GetPString(IDS_PROGRAMNOTEXE2TEXT),
366 pszCmdLine_);
367 fCancelAction = TRUE;
368 pszNewCmdLine = pszCmdLine_;
369 }
370 }
371 else { // file has a nonstandard extension for executable
372 pszChar = strrchr(szCmdLine, '.');
373 while (pszChar && *pszChar !=' ') {
374 pszChar++;
375 }
376 *pszChar = '\0';
377 strcpy (szArgs, pszCmdLine_ + strlen(szCmdLine));
378 while (strchr(szCmdLine, '\"'))
379 remove_first_occurence_of_character("\"", szCmdLine);
380 if ((szArgs[0] == '\"' && szArgs[1] == ' ') ||
381 !strstr(pszCmdLine_, "\\:")||
382 strchr(szArgs, '\"') == strrchr(szArgs, '\"'))
383 remove_first_occurence_of_character("\"", szArgs);
384 if (strchr(szArgs, '\"') != strrchr(szArgs, '\"'))
385 saymsg(MB_OK, HWND_DESKTOP,
386 NullStr,
387 GetPString(IDS_QUOTESINARGSTEXT),
388 pszCmdLine_);
389 BldQuotedFileName(pszNewCmdLine, szCmdLine);
390 if (SearchPathForFile(PCSZ_PATH, szCmdLine, NULL)) {
391 ret = saymsg(MB_YESNO,
392 HWND_DESKTOP,
393 NullStr,
394 GetPString(IDS_PROGRAMNOTFOUNDTEXT),
395 pszCmdLine_);
396 if (ret == MBID_YES) {
397 if (szArgs[0] != ' ')
398 strcat(pszNewCmdLine, " ");
399 strcat(pszNewCmdLine, szArgs);
400 }
401 else {
402 fCancelAction = TRUE;
403 pszWorkBuf = pszCmdLine_;
404 }
405 }
406 else {
407 ret = saymsg(MB_YESNOCANCEL,
408 HWND_DESKTOP,
409 NullStr,
410 GetPString(IDS_PROGRAMNOTEXE3TEXT),
411 pszCmdLine_, pszNewCmdLine);
412 if (ret == MBID_YES){
413 if (szArgs[0] != ' ')
414 strcat(pszNewCmdLine, " ");
415 strcat(pszNewCmdLine, szArgs);
416 }
417 if (ret == MBID_CANCEL){
418 fCancelAction = TRUE;
419 pszNewCmdLine = pszCmdLine_;
420 }
421 }
422 }
423 }
424 free(szArgs);
425 free(szCmdLine);
426 return pszWorkBuf;
427}
428
429#pragma alloc_text(PATHUTIL,BldFullPathName)
430#pragma alloc_text(PATHUTIL,BldQuotedFileName)
431#pragma alloc_text(PATHUTIL,BldQuotedFullPathName)
432#pragma alloc_text(PATHUTIL,NormalizeCmdLine)
433#pragma alloc_text(PATHUTIL,IsAbsolutePath)
Note: See TracBrowser for help on using the repository browser.