source: trunk/dll/pathutil.c@ 1036

Last change on this file since 1036 was 1009, checked in by Steven Levine, 17 years ago

Add xfree xstrdup Fortify support
Add MT capable Fortify scope logic

File size: 10.1 KB
Line 
1
2/***********************************************************************
3
4 $Id: $
5
6 Path handling utility functions
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2008 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 Use xfree where appropriate
14 29 Feb 08 GKY Changes to enable user settable command line length
15
16***********************************************************************/
17
18#include <string.h>
19
20#define INCL_WIN
21#define INCL_DOS
22#define INCL_LONGLONG
23
24#include "pathutil.h"
25#include "fm3dll.h" // needs_quoting
26#include "fm3str.h"
27#include "errutil.h" // Dos_Error...
28#include "strutil.h" // GetPString
29
30static PSZ pszSrcFile = __FILE__;
31
32// #pragma data_seg(DATA1)
33
34/**
35 * Build full path name in callers buffer given directory
36 * name and filename
37 * @param pszPathName points to drive/directory if not NULL
38 * @returns pointer to full path name in caller's buffer
39 * @note OK for pszFullPathName and pszPathName to point to same buffer
40 *
41 */
42
43PSZ BldFullPathName(PSZ pszFullPathName, PSZ pszPathName, PSZ pszFileName)
44{
45 UINT c = pszPathName ? strlen(pszPathName) : 0;
46 if (c > 0) {
47 memcpy(pszFullPathName, pszPathName, c);
48 if (pszFullPathName[c - 1] != '\\')
49 pszFullPathName[c++] = '\\';
50 }
51 strcpy(pszFullPathName + c, pszFileName);
52 return pszFullPathName;
53}
54
55/**
56 * Build quoted full path name in callers buffer given
57 * directory name and filename
58 * @param pszPathName points to drive/directory if not NULL
59 * @returns pointer to quoted path name in caller's buffer
60 */
61
62PSZ BldQuotedFullPathName(PSZ pszFullPathName, PSZ pszPathName, PSZ pszFileName)
63{
64 UINT c = pszPathName ? strlen(pszPathName) : 0;
65 BOOL q = needs_quoting(pszPathName) ||
66 needs_quoting(pszFileName);
67 PSZ psz = pszFullPathName;
68
69 if (q)
70 *psz++ = '"';
71 if (c > 0) {
72 memcpy(psz, pszPathName, c);
73 psz += c;
74 if (*(psz - 1) != '\\')
75 *psz++ = '\\';
76 }
77 strcpy(psz, pszFileName);
78 if (q) {
79 psz += strlen(psz);
80 *psz++ = '"';
81 *psz = 0;
82 }
83 return pszFullPathName;
84}
85
86/**
87 * Build quoted full path name in callers buffer given a filename
88 * @returns pointer to quoted file name in caller's buffer
89 */
90
91PSZ BldQuotedFileName(PSZ pszQuotedFileName, PSZ pszFileName)
92{
93 BOOL q = needs_quoting(pszFileName);
94 PSZ psz = pszQuotedFileName;
95
96 if (q)
97 *psz++ = '"';
98 strcpy(psz, pszFileName);
99 if (q) {
100 psz += strlen(psz);
101 *psz++ = '"';
102 *psz = 0;
103 }
104 return pszQuotedFileName;
105}
106
107/** NormalizeCmdLine
108 * Checks a command line for common errors (missing quotes, missing extension,
109 * no space between exe and args etc)
110 * Command line passed as pszCmdLine_
111 * A pointer to a buffer of the size MaxComLineStrg should be supplied in
112 * pszWorkBuf. This is where the quoted etc as necessary command
113 * line string will be returned.
114 */
115
116PCSZ NormalizeCmdLine(PSZ pszWorkBuf, PSZ pszCmdLine_)
117{
118 char *szCmdLine, *szArgs;
119 char *offset = '\0', *offsetexe, *offsetcom, *offsetcmd, *offsetbtm, *offsetbat;
120 APIRET ret;
121 ULONG ulAppType;
122 char *pszChar;
123 FILEFINDBUF3 FindBuffer;
124 ULONG ulResultBufLen = sizeof(FILEFINDBUF3);
125 HDIR hdirFindHandle = HDIR_CREATE;
126 ULONG ulFindCount = 1;
127 PSZ pszNewCmdLine = pszWorkBuf;
128
129 szCmdLine = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
130 if (!szCmdLine)
131 return pszCmdLine_; //already complained
132 szArgs = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
133 if (!szArgs) {
134 xfree(szCmdLine, pszSrcFile, __LINE__);
135 return pszCmdLine_; //already complained
136 }
137 bstrip(pszCmdLine_);
138 memset(pszWorkBuf, 0, MaxComLineStrg);
139 strcpy(szCmdLine, pszCmdLine_);
140 if (szCmdLine[0] != '\0') {
141 offsetexe = strstr(strlwr(pszCmdLine_), ".exe");
142 offsetcmd = strstr(strlwr(pszCmdLine_), ".cmd");
143 offsetcom = strstr(strlwr(pszCmdLine_), ".com");
144 offsetbtm = strstr(strlwr(pszCmdLine_), ".btm");
145 offsetbat = strstr(strlwr(pszCmdLine_), ".bat");
146 if (offsetexe)
147 offset = offsetexe;
148 else {
149 if (offsetcom)
150 offset = offsetcom;
151 else {
152 if (offsetcmd)
153 offset = offsetcmd;
154 else {
155 if (offsetbtm)
156 offset = offsetbtm;
157 else {
158 if (offsetbat)
159 offset = offsetexe;
160 }
161 }
162 }
163 }
164 if (offset) {
165 szCmdLine[offset + 4 - pszCmdLine_] = '\0';
166 strcpy(szArgs, &pszCmdLine_[offset + 4 - pszCmdLine_]);
167 while (strchr(szCmdLine, '\"'))
168 remove_first_occurence_of_character("\"", szCmdLine);
169 if ((szArgs[0] == '\"' && szArgs[1] == ' ') ||
170 !strstr(pszCmdLine_, "\\:")||
171 strchr(szArgs, '\"') == strrchr(szArgs, '\"'))
172 remove_first_occurence_of_character("\"", szArgs);
173 if (strchr(szArgs, '\"') != strrchr(szArgs, '\"'))
174 saymsg(MB_OK, HWND_DESKTOP,
175 NullStr,
176 GetPString(IDS_QUOTESINARGSTEXT),
177 pszCmdLine_);
178 if (!offsetexe) {
179 ret = DosFindFirst(szCmdLine, &hdirFindHandle, FILE_NORMAL, &FindBuffer,
180 ulResultBufLen, &ulFindCount, FIL_STANDARD);
181 if (ret) {
182 pszChar = szCmdLine;
183 while (pszChar) {
184 if (*pszChar == ' ') {
185 *pszChar = '\0';
186 strcat(szCmdLine, ".exe");
187 ret = DosQueryAppType(szCmdLine, &ulAppType);
188 //printf("%d %s\n", ret, szCmdLine); fflush(stdout);
189 if (!ret) {
190 strcpy(szArgs, pszCmdLine_ + strlen(szCmdLine) - 3);
191 break;
192 }
193 }
194 strcpy(szCmdLine, pszCmdLine_);
195 pszChar++;
196 }
197 }
198 }
199 else
200 ret = DosQueryAppType(szCmdLine, &ulAppType);
201 BldQuotedFileName(pszNewCmdLine, szCmdLine);
202 //printf("%d A", ret); fflush(stdout);
203 if (ret) {
204 ret = saymsg(MB_YESNO,
205 HWND_DESKTOP,
206 NullStr,
207 GetPString(IDS_PROGRAMNOTFOUNDTEXT),
208 pszCmdLine_);
209 if (ret == MBID_YES){
210 if (szArgs[0] != ' ')
211 strcat(pszNewCmdLine, " ");
212 strcat(pszNewCmdLine, szArgs);
213 }
214 else{
215 fCancelAction = TRUE;
216 pszNewCmdLine = pszCmdLine_;
217 }
218 }
219 else{
220 if (szArgs[0] != ' ')
221 strcat(pszNewCmdLine, " ");
222 strcat(pszNewCmdLine, szArgs);
223 }
224
225 }
226 else if (szCmdLine && (!strchr(szCmdLine, '.') ||
227 strrchr(szCmdLine, '.' ) < strrchr(szCmdLine, '\\'))) {
228 if (!strchr(szCmdLine, ' ')) {
229 while (strchr(szCmdLine, '\"'))
230 remove_first_occurence_of_character("\"", szCmdLine);
231 strcat(szCmdLine, ".exe");
232 ret = DosFindFirst(szCmdLine, &hdirFindHandle, FILE_NORMAL, &FindBuffer,
233 ulResultBufLen, &ulFindCount, FIL_STANDARD);
234 //printf("%d", ret); fflush(stdout);
235 }
236 else {
237 pszChar = szCmdLine;
238 while (pszChar) {
239 while (strchr(szCmdLine, '\"'))
240 remove_first_occurence_of_character("\"", szCmdLine);
241 if (*pszChar == ' ') {
242 *pszChar = '\0';
243 strcat(szCmdLine, ".exe");
244 ret = DosQueryAppType(szCmdLine, &ulAppType);
245 //printf("%d %s\n", ret, szCmdLine); fflush(stdout);
246 if (!ret) {
247 break;
248 }
249 }
250 strcpy(szCmdLine, pszCmdLine_);
251 pszChar++;
252 }
253 }
254 if (!ret){
255 BldQuotedFileName(pszNewCmdLine, szCmdLine);
256 strcpy(szArgs, pszCmdLine_ + strlen(szCmdLine) - 3);
257 if ((szArgs[0] == '\"' && szArgs[1] == ' ') ||
258 !strstr(pszCmdLine_, "\\:" ) ||
259 strchr(szArgs, '\"') == strrchr(szArgs, '\"'))
260 remove_first_occurence_of_character("\"", szArgs);
261 if (strchr(szArgs, '\"') != strrchr(szArgs, '\"'))
262 saymsg(MB_OK, HWND_DESKTOP,
263 NullStr,
264 GetPString(IDS_QUOTESINARGSTEXT),
265 pszCmdLine_);
266 if (szArgs[0] != ' ')
267 strcat(pszNewCmdLine, " ");
268 strcat(pszNewCmdLine, szArgs);
269 }
270 else {
271 ret = saymsg(MB_OK,
272 HWND_DESKTOP,
273 NullStr,
274 GetPString(IDS_PROGRAMNOTEXE2TEXT),
275 pszCmdLine_);
276 fCancelAction = TRUE;
277 pszNewCmdLine = pszCmdLine_;
278 }
279 }
280 else {
281 pszChar = strrchr(szCmdLine, '.');
282 while (pszChar && *pszChar !=' ') {
283 pszChar++;
284 }
285 *pszChar = '\0';
286 strcpy (szArgs, pszCmdLine_ + strlen(szCmdLine));
287 while (strchr(szCmdLine, '\"'))
288 remove_first_occurence_of_character("\"", szCmdLine);
289 if ((szArgs[0] == '\"' && szArgs[1] == ' ') ||
290 !strstr(pszCmdLine_, "\\:")||
291 strchr(szArgs, '\"') == strrchr(szArgs, '\"'))
292 remove_first_occurence_of_character("\"", szArgs);
293 if (strchr(szArgs, '\"') != strrchr(szArgs, '\"'))
294 saymsg(MB_OK, HWND_DESKTOP,
295 NullStr,
296 GetPString(IDS_QUOTESINARGSTEXT),
297 pszCmdLine_);
298 ret = DosFindFirst(szCmdLine, &hdirFindHandle, FILE_NORMAL, &FindBuffer,
299 ulResultBufLen, &ulFindCount, FIL_STANDARD);
300
301 BldQuotedFileName(pszNewCmdLine, szCmdLine);
302 //printf("%d %s ", ret, szCmdLine); fflush(stdout);
303 if (ret) {
304 ret = saymsg(MB_YESNO,
305 HWND_DESKTOP,
306 NullStr,
307 GetPString(IDS_PROGRAMNOTFOUNDTEXT),
308 pszCmdLine_);
309 if (ret == MBID_YES) {
310 if (szArgs[0] != ' ')
311 strcat(pszNewCmdLine, " ");
312 strcat(pszNewCmdLine, szArgs);
313 }
314 else {
315 fCancelAction = TRUE;
316 pszWorkBuf = pszCmdLine_;
317 }
318 }
319 ret = saymsg(MB_YESNOCANCEL,
320 HWND_DESKTOP,
321 NullStr,
322 GetPString(IDS_PROGRAMNOTEXE3TEXT),
323 pszCmdLine_, pszNewCmdLine);
324 if (ret == MBID_YES){
325 if (szArgs[0] != ' ')
326 strcat(pszNewCmdLine, " ");
327 strcat(pszNewCmdLine, szArgs);
328 }
329 if (ret == MBID_CANCEL){
330 fCancelAction = TRUE;
331 pszNewCmdLine = pszCmdLine_;
332 }
333 }
334 }
335 xfree(szArgs, pszSrcFile, __LINE__);
336 xfree(szCmdLine, pszSrcFile, __LINE__);
337 return pszWorkBuf;
338}
339
340#pragma alloc_text(PATHUTIL,BldFullPathName)
341#pragma alloc_text(PATHUTIL,BldQuotedFileName)
342#pragma alloc_text(PATHUTIL,BldQuotedFullPathName)
343#pragma alloc_text(PATHUTIL,NormalizeCmdLine)
Note: See TracBrowser for help on using the repository browser.