source: trunk/dll/pathutil.c@ 1039

Last change on this file since 1039 was 1039, checked in by Gregg Young, 17 years ago

Removed unnecessary xfrees and included fortify.h where needed; moved several misplaced (x)frees;

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