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
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
[1185]24#include "fm3dll.h" // needs_quoting
[1211]25#include "notebook.h" // Data declaration(s)
26#include "init.h" // Data declaration(s)
[1185]27#include "fm3str.h"
[907]28#include "pathutil.h"
[1161]29#include "strips.h" // remove_first_occurence_of_character
[1185]30#include "valid.h" // needs_quoting
[920]31#include "errutil.h" // Dos_Error...
32#include "strutil.h" // GetPString
[1185]33#include "wrappers.h" // xmalloc
[1039]34#include "fortify.h"
[907]35
[985]36static PSZ pszSrcFile = __FILE__;
37
[907]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;
[1161]71 BOOL q = needs_quoting(pszPathName) || needs_quoting(pszFileName);
[907]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
[920]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_
[985]116 * A pointer to a buffer of the size MaxComLineStrg should be supplied in
[920]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{
[985]123 char *szCmdLine, *szArgs;
[920]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
[985]134 szCmdLine = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
135 if (!szCmdLine)
136 return pszCmdLine_; //already complained
137 szArgs = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
138 if (!szArgs) {
[1039]139 free(szCmdLine);
[985]140 return pszCmdLine_; //already complained
141 }
[920]142 bstrip(pszCmdLine_);
[985]143 memset(pszWorkBuf, 0, MaxComLineStrg);
[920]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){
[989]215 if (szArgs[0] != ' ')
216 strcat(pszNewCmdLine, " ");
217 strcat(pszNewCmdLine, szArgs);
[920]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) {
[989]315 if (szArgs[0] != ' ')
316 strcat(pszNewCmdLine, " ");
317 strcat(pszNewCmdLine, szArgs);
[920]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 }
[1039]340 free(szArgs);
341 free(szCmdLine);
[920]342 return pszWorkBuf;
343}
344
[907]345#pragma alloc_text(PATHUTIL,BldFullPathName)
346#pragma alloc_text(PATHUTIL,BldQuotedFileName)
347#pragma alloc_text(PATHUTIL,BldQuotedFullPathName)
[920]348#pragma alloc_text(PATHUTIL,NormalizeCmdLine)
Note: See TracBrowser for help on using the repository browser.