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
RevLine 
[907]1
2/***********************************************************************
3
[1323]4 $Id: pathutil.c 1880 2015-10-12 18:26:16Z gyoung $
[907]5
6 Path handling utility functions
7
8 Copyright (c) 1993-98 M. Kimes
[1394]9 Copyright (c) 2001, 2009 Steven H. Levine
[907]10
11 05 Jan 08 SHL Move from arccnrs.c and comp.c to here
[920]12 06 Jan 08 GKY Add NormalizeCmdLine to check program strings on entry
[985]13 29 Feb 08 GKY Changes to enable user settable command line length
[1699]14 15 Oct 08 GKY Fix NormalizeCmdLine to check all 5 executable extensions when no extension provided;
[1394]15 use searchapath to check for existance of file types not checked by DosQAppType;
[1761]16 close DosFind.
[1439]17 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code
[1480]18 12 Jul 09 GKY Add xDosQueryAppType and xDosAlloc... to allow FM/2 to load in high memory
[1545]19 23 Oct 10 GKY Add ForwardslashToBackslash function to streamline code
[1632]20 17 Sep 11 GKY Fix commandline quoting issues
[1750]21 01 Mar 14 JBS Ticket #524: Made "searchapath" thread-safe. Function names and signatures were changed.
[1761]22 So calls to these functions had to be changed.
23 21 Mar 14 SHL Add IsAbsolutePath
[1782]24 28 Jun 14 GKY Fix errors identified with CPPCheck;
[907]25
26***********************************************************************/
27
[1039]28#include <stdlib.h>
[907]29#include <string.h>
[1761]30#include <ctype.h>
[907]31
32#define INCL_WIN
[920]33#define INCL_DOS
[907]34#define INCL_LONGLONG
35
[1185]36#include "fm3dll.h" // needs_quoting
[1211]37#include "notebook.h" // Data declaration(s)
38#include "init.h" // Data declaration(s)
[1185]39#include "fm3str.h"
[1750]40#include "srchpath.h" // Search*Path*ForFile
[907]41#include "pathutil.h"
[1161]42#include "strips.h" // remove_first_occurence_of_character
[1185]43#include "valid.h" // needs_quoting
[920]44#include "errutil.h" // Dos_Error...
45#include "strutil.h" // GetPString
[1185]46#include "wrappers.h" // xmalloc
[1039]47#include "fortify.h"
[1398]48#include "stristr.h" //stristr
[907]49
[985]50static PSZ pszSrcFile = __FILE__;
51
[1545]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
[1438]65PSZ AddBackslashToPath(PSZ pszPathName)
66{
67 if (pszPathName[strlen(pszPathName) - 1] != '\\')
68 strcat(pszPathName, PCSZ_BACKSLASH);
69 return pszPathName;
70}
71
[907]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
[1398]81PSZ BldFullPathName(PSZ pszFullPathName, PCSZ pszPathName, PCSZ pszFileName)
[907]82{
83 UINT c = pszPathName ? strlen(pszPathName) : 0;
84 if (c > 0) {
[1568]85 if (pszFullPathName != pszPathName)
86 memcpy(pszFullPathName, pszPathName, c);
[907]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
[1398]101PSZ BldQuotedFullPathName(PSZ pszFullPathName, PCSZ pszPathName, PCSZ pszFileName)
[907]102{
103 UINT c = pszPathName ? strlen(pszPathName) : 0;
[1161]104 BOOL q = needs_quoting(pszPathName) || needs_quoting(pszFileName);
[907]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
[1394]129PSZ BldQuotedFileName(PSZ pszQuotedFileName, PCSZ pszFileName)
[907]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
[1761]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
[920]165/** NormalizeCmdLine
166 * Checks a command line for common errors (missing quotes, missing extension,
[1248]167 * no space between exe and args etc) Also check for the existance of the file
168 * and checks .com and .exe file headers.
[920]169 * Command line passed as pszCmdLine_
[985]170 * A pointer to a buffer of the size MaxComLineStrg should be supplied in
[920]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{
[985]177 char *szCmdLine, *szArgs;
[920]178 char *offset = '\0', *offsetexe, *offsetcom, *offsetcmd, *offsetbtm, *offsetbat;
179 APIRET ret;
180 ULONG ulAppType;
181 char *pszChar;
182 PSZ pszNewCmdLine = pszWorkBuf;
183
[985]184 szCmdLine = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
185 if (!szCmdLine)
186 return pszCmdLine_; //already complained
187 szArgs = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
188 if (!szArgs) {
[1039]189 free(szCmdLine);
[985]190 return pszCmdLine_; //already complained
191 }
[920]192 bstrip(pszCmdLine_);
[985]193 memset(pszWorkBuf, 0, MaxComLineStrg);
[920]194 strcpy(szCmdLine, pszCmdLine_);
195 if (szCmdLine[0] != '\0') {
[1398]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);
[920]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] == ' ') ||
[1631]225 (!strstr(pszCmdLine_, "\\:") && strchr(szArgs, '\"') &&
226 strchr(szArgs, '\"') == strrchr(szArgs, '\"')))
[920]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_);
[1247]233 if (!offsetexe && !offsetcom) {
[1761]234 if (!SearchPathForFile(PCSZ_PATH, szCmdLine, NULL))
235 ret = 0;
[920]236 }
237 else
[1439]238 ret = xDosQueryAppType(szCmdLine, &ulAppType);
[920]239 BldQuotedFileName(pszNewCmdLine, szCmdLine);
240 if (ret) {
[1394]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);
[920]250 }
[1394]251 else{
252 fCancelAction = TRUE;
253 pszNewCmdLine = pszCmdLine_;
254 }
[920]255 }
256 else{
[1394]257 if (szArgs[0] != ' ')
258 strcat(pszNewCmdLine, " ");
259 strcat(pszNewCmdLine, szArgs);
[920]260 }
261
262 }
[1247]263 // if it doesn't have an extension try it with all the standard ones and add if found
[1782]264 else if (!strchr(szCmdLine, '.') ||
265 strrchr(szCmdLine, '.' ) < strrchr(szCmdLine, '\\')) {
[920]266 if (!strchr(szCmdLine, ' ')) {
[1394]267 // strip quotes readded by BuildQuotedFileName
[920]268 while (strchr(szCmdLine, '\"'))
269 remove_first_occurence_of_character("\"", szCmdLine);
[1439]270 ret = xDosQueryAppType(szCmdLine, &ulAppType); // exe automatically appended
[1394]271 if (!ret)
[1398]272 strcat(szCmdLine, PCSZ_DOTEXE);
[1394]273 else {
[1398]274 strcat(szCmdLine, PCSZ_DOTCOM);
[1439]275 ret = xDosQueryAppType(szCmdLine, &ulAppType);
[1394]276 if (ret) {
277 offset = strrchr(szCmdLine, '.' );
278 *offset = 0;
[1398]279 strcat(szCmdLine, PCSZ_DOTCMD);
[1750]280 if (!SearchPathForFile(PCSZ_PATH, szCmdLine, NULL))
[1394]281 ret = 0;
282 else {
283 *offset = 0;
[1398]284 strcat(szCmdLine, PCSZ_DOTBAT);
[1750]285 if (!SearchPathForFile(PCSZ_PATH, szCmdLine, NULL))
[1394]286 ret = 0;
287 else {
288 *offset = 0;
[1398]289 strcat(szCmdLine, PCSZ_DOTBTM);
[1750]290 if (!SearchPathForFile(PCSZ_PATH, szCmdLine, NULL))
[1394]291 ret = 0;
292 }
293 }
294 }
295 }
[920]296 }
297 else {
298 pszChar = szCmdLine;
299 while (pszChar) {
300 while (strchr(szCmdLine, '\"'))
301 remove_first_occurence_of_character("\"", szCmdLine);
[1247]302 if (*pszChar == ' ') { //test at every space for the end of the filename
[920]303 *pszChar = '\0';
[1439]304 ret = xDosQueryAppType(szCmdLine, &ulAppType);
[1394]305 if (!ret) {
[1398]306 strcat(szCmdLine, PCSZ_DOTEXE);
[1394]307 break;
308 }
309 else {
[1398]310 strcat(szCmdLine, PCSZ_DOTCOM);
[1439]311 ret = xDosQueryAppType(szCmdLine, &ulAppType);
[1394]312 if (ret) {
313 offset = strrchr(szCmdLine, '.' );
314 *offset = 0;
[1398]315 strcat(szCmdLine, PCSZ_DOTCMD);
[1750]316 if (!SearchPathForFile(PCSZ_PATH, szCmdLine, NULL)) {
[1394]317 ret = 0;
318 break;
319 }
320 else {
321 *offset = 0;
[1398]322 strcat(szCmdLine, PCSZ_DOTBAT);
[1750]323 if (!SearchPathForFile(PCSZ_PATH, szCmdLine, NULL)) {
[1394]324 ret = 0;
325 break;
326 }
327 else {
328 *offset = 0;
[1398]329 strcat(szCmdLine, PCSZ_DOTBTM);
[1750]330 if (!SearchPathForFile(PCSZ_PATH, szCmdLine, NULL)) {
[1394]331 ret = 0;
332 break;
333 }
334 }
335 }
336 }
337 else
338 break;
339 }
[920]340 }
341 strcpy(szCmdLine, pszCmdLine_);
342 pszChar++;
343 }
344 }
345 if (!ret){
[1394]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);
[920]360 }
[1248]361 else { // fail if no extension can be found runemf2 requires one
[1394]362 ret = saymsg(MB_OK,
363 HWND_DESKTOP,
364 NullStr,
365 GetPString(IDS_PROGRAMNOTEXE2TEXT),
366 pszCmdLine_);
367 fCancelAction = TRUE;
368 pszNewCmdLine = pszCmdLine_;
[920]369 }
370 }
[1699]371 else { // file has a nonstandard extension for executable
[920]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);
[1750]390 if (SearchPathForFile(PCSZ_PATH, szCmdLine, NULL)) {
[920]391 ret = saymsg(MB_YESNO,
392 HWND_DESKTOP,
393 NullStr,
394 GetPString(IDS_PROGRAMNOTFOUNDTEXT),
395 pszCmdLine_);
396 if (ret == MBID_YES) {
[1394]397 if (szArgs[0] != ' ')
398 strcat(pszNewCmdLine, " ");
399 strcat(pszNewCmdLine, szArgs);
[920]400 }
401 else {
402 fCancelAction = TRUE;
403 pszWorkBuf = pszCmdLine_;
404 }
405 }
[1248]406 else {
407 ret = saymsg(MB_YESNOCANCEL,
[1394]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 }
[920]421 }
422 }
423 }
[1039]424 free(szArgs);
425 free(szCmdLine);
[920]426 return pszWorkBuf;
427}
428
[907]429#pragma alloc_text(PATHUTIL,BldFullPathName)
430#pragma alloc_text(PATHUTIL,BldQuotedFileName)
431#pragma alloc_text(PATHUTIL,BldQuotedFullPathName)
[920]432#pragma alloc_text(PATHUTIL,NormalizeCmdLine)
[1761]433#pragma alloc_text(PATHUTIL,IsAbsolutePath)
Note: See TracBrowser for help on using the repository browser.