source: trunk/dll/pathutil.c@ 1211

Last change on this file since 1211 was 1211, checked in by John Small, 17 years ago

Ticket 187: Move data declarations/definitions out of fm3dll.h

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