source: trunk/dll/pathutil.c@ 1545

Last change on this file since 1545 was 1545, checked in by Gregg Young, 15 years ago

Added ForwardslashToBackslash function to streamline code.

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