source: trunk/dll/pathutil.c@ 1161

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

Ticket 187: Draft 1: Functions only

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