source: trunk/dll/pathutil.c@ 1185

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

Ticket 187: Draft 2: Move remaining function declarations

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