source: trunk/dll/uudecode.c@ 1438

Last change on this file since 1438 was 1438, checked in by Gregg Young, 16 years ago

Improved drivebar changes; Added AddBackslashToPath() to remove repeatative code. replaced "
" with PCSZ variable; ANY_OBJ added the DosAlloc... (experimental)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.2 KB
Line 
1
2/***********************************************************************
3
4 $Id: uudecode.c 1438 2009-06-28 20:47:00Z gyoung $
5
6 uudecode
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2005, 2008 Steven H. Levine
10
11 06 Jun 05 SHL Indent -i2
12 06 Jun 05 SHL Drop unused code
13 17 Jul 06 SHL Use Runtime_Error
14 29 Jul 06 SHL Use xfgets
15 01 Sep 06 SHL Back to fgets for now - avoid excess error messages
16 22 Mar 07 GKY Use QWL_USER
17 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
18 07 Feb 09 GKY Allow user to turn off alert and/or error beeps in settings notebook.
19
20***********************************************************************/
21
22#include <stdlib.h>
23#include <string.h>
24#include <share.h>
25
26#define INCL_DOS
27#define INCL_WIN
28#define INCL_LONGLONG // dircnrs.h
29
30#include "fm3dll.h"
31#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
32#include "worker.h" // typedef WORKER
33#include "notebook.h" // Data declaration(s)
34#include "fm3dlg.h"
35#include "fm3str.h"
36#include "makelist.h" // AddToList
37#include "errutil.h" // Dos_Error...
38#include "strutil.h" // GetPString
39#include "defview.h"
40#include "uudecode.h"
41#include "getnames.h" // export_filename
42#include "valid.h" // IsFile
43#include "misc.h" // PaintRecessedWindow
44#include "wrappers.h" // xfgets
45#include "init.h" // Strings
46
47static PSZ pszSrcFile = __FILE__;
48
49/* prototypes */
50static BOOL decode(FILE * in, FILE * out);
51static void outdec(char *p, FILE * f, int n);
52
53/* single character decode */
54#define DEC(c) (((c) - ' ') & 077)
55
56int UUD(char *filename, CHAR * dest)
57{
58 FILE *in, *out;
59 int mode, ret = 0;
60 char buf[80];
61 char fakedest[CCHMAXPATH];
62
63 if (!dest)
64 dest = fakedest;
65 in = _fsopen(filename, "r", SH_DENYWR);
66 if (!in) {
67 saymsg(MB_CANCEL,
68 HWND_DESKTOP,
69 GetPString(IDS_ERRORTEXT),
70 GetPString(IDS_COMPCANTOPENTEXT), filename);
71 return ret;
72 }
73
74 /* search for header line */
75 for (;;) {
76 if (!fgets(buf, sizeof(buf), in)) {
77 fclose(in);
78 saymsg(MB_CANCEL,
79 HWND_DESKTOP,
80 GetPString(IDS_ERRORTEXT),
81 GetPString(IDS_UUDNOBEGINTEXT), filename);
82 return ret;
83 }
84 if (!strncmp(buf, "begin ", 6))
85 break;
86 } // for
87 *dest = 0;
88 sscanf(buf, "begin %o %259s", &mode, dest);
89 dest[CCHMAXPATH - 1] = 0;
90 {
91 /* place dest in same directory as filename by default... */
92 char build[CCHMAXPATH], *p;
93
94 strcpy(build, filename);
95 p = strrchr(build, '\\');
96 if (p) {
97 p++;
98 *p = 0;
99 }
100 else
101 strcat(build, PCSZ_BACKSLASH);
102 strncat(build, dest, CCHMAXPATH - strlen(dest));
103 strcpy(dest, build);
104 }
105
106 if (!export_filename(HWND_DESKTOP, dest, FALSE)) {
107 fclose(in);
108 return ret;
109 }
110
111 /* create output file */
112 out = _fsopen(dest, "ab+", SH_DENYWR);
113 if (!out) {
114 fclose(in);
115 saymsg(MB_CANCEL,
116 HWND_DESKTOP,
117 GetPString(IDS_ERRORTEXT),
118 GetPString(IDS_UUDCANTOPENFORTEXT), dest, filename);
119 return ret;
120 }
121
122 ret = 1;
123 decode(in, out);
124
125 xfgets(buf, sizeof(buf), in, pszSrcFile, __LINE__);
126
127 fclose(in);
128 fclose(out);
129 return ret;
130}
131
132/*
133 * copy from in to out, decoding as you go along.
134 */
135static BOOL decode(FILE * in, FILE * out)
136{
137 char buf[80];
138 char *bp;
139 int n;
140
141 for (;;) {
142 /* for each input line */
143 if (!xfgets(buf, sizeof(buf), in, pszSrcFile, __LINE__))
144 return FALSE;
145 n = DEC(buf[0]);
146 if (n <= 0)
147 break;
148 bp = &buf[1];
149 while (n > 0) {
150 outdec(bp, out, n);
151 bp += 4;
152 n -= 3;
153 }
154 }
155 return TRUE;
156}
157
158/*
159 * output a group of 3 bytes (4 input characters).
160 * the input chars are pointed to by p, they are to
161 * be output to file f. n is used to tell us not to
162 * output all of them at the end of the file.
163 */
164static void outdec(char *p, FILE * f, int n)
165{
166 INT c1, c2, c3;
167
168 c1 = DEC(*p) << 2 | (UINT) DEC(p[1]) >> 4;
169 c2 = DEC(p[1]) << 4 | (UINT) DEC(p[2]) >> 2;
170 c3 = DEC(p[2]) << 6 | DEC(p[3]);
171 if (n >= 1)
172 putc(c1, f);
173 if (n >= 2)
174 putc(c2, f);
175 if (n >= 3)
176 putc(c3, f);
177}
178
179MRESULT EXPENTRY MergeDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
180{
181 WORKER *wk;
182
183 switch (msg) {
184 case WM_INITDLG:
185 if (mp2) {
186 WinSetWindowPtr(hwnd, QWL_USER, mp2);
187 wk = (WORKER *) mp2;
188 if (wk->li && wk->li->list && wk->li->list[0]) {
189 WinSendDlgItemMsg(hwnd, MRG_TARGETNAME, EM_SETTEXTLIMIT,
190 MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
191 PostMsg(hwnd, UM_UNDO, MPVOID, MPVOID);
192 }
193 else
194 WinDismissDlg(hwnd, 0);
195 }
196 else
197 WinDismissDlg(hwnd, 0);
198 break;
199
200 case UM_UNDO:
201 WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
202 wk = WinQueryWindowPtr(hwnd, QWL_USER);
203 if (wk) {
204 INT x, numfiles = 0;
205 SHORT start;
206 CHAR *p;
207
208 WinSetDlgItemText(hwnd, MRG_TARGETNAME, wk->li->targetpath);
209 start = 0;
210 p = strrchr(wk->li->targetpath, '\\');
211 if (p)
212 start = (p + 1) - wk->li->targetpath;
213 WinSendDlgItemMsg(hwnd, MRG_TARGETNAME, EM_SETSEL,
214 MPFROM2SHORT(start, CCHMAXPATH), MPVOID);
215 for (x = 0; wk->li->list[x]; x++) {
216 if (IsFile(wk->li->list[x]) == 1) {
217 numfiles++;
218 WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_INSERTITEM,
219 MPFROM2SHORT(LIT_END, 0),
220 MPFROMP(wk->li->list[x]));
221 }
222 }
223 WinCheckButton(hwnd, MRG_BINARY, (wk->li->type == IDM_MERGEBINARY));
224 if (!numfiles) {
225 saymsg(MB_CANCEL | MB_ICONEXCLAMATION,
226 hwnd,
227 GetPString(IDS_SILLYERRORTEXT),
228 GetPString(IDS_MERGEWASTETEXT));
229 WinDismissDlg(hwnd, 0);
230 }
231 }
232 return 0;
233
234 case WM_CONTROL:
235 switch (SHORT1FROMMP(mp1)) {
236 case MRG_LISTBOX:
237 switch (SHORT2FROMMP(mp1)) {
238 case LN_ENTER:
239 {
240 SHORT x;
241 CHAR szBuffer[CCHMAXPATH];
242
243 x = (SHORT) WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_QUERYSELECTION,
244 MPFROMSHORT(LIT_FIRST), MPVOID);
245 if (x >= 0) {
246 *szBuffer = 0;
247 WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_QUERYITEMTEXT,
248 MPFROM2SHORT(x, CCHMAXPATH), MPFROMP(szBuffer));
249 if (*szBuffer)
250 QuickEdit(hwnd, szBuffer);
251 }
252 }
253 break;
254 }
255 break;
256 }
257 break;
258
259 case WM_ADJUSTWINDOWPOS:
260 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
261 break;
262
263 case UM_SETDIR:
264 PaintRecessedWindow(WinWindowFromID(hwnd, MRG_HELP), (HPS) 0, FALSE,
265 TRUE);
266 return 0;
267
268 case WM_COMMAND:
269 switch (SHORT1FROMMP(mp1)) {
270 case IDM_UNDO:
271 PostMsg(hwnd, UM_UNDO, MPVOID, MPVOID);
272 break;
273
274 case MRG_CHANGETARGET:
275 wk = WinQueryWindowPtr(hwnd, QWL_USER);
276 if (wk) {
277 CHAR filename[CCHMAXPATH];
278
279 strcpy(filename, wk->li->targetpath);
280 if (export_filename(HWND_DESKTOP, filename, FALSE) && *filename) {
281 strcpy(wk->li->targetpath, filename);
282 WinSetDlgItemText(hwnd, MRG_TARGETNAME, wk->li->targetpath);
283 }
284 }
285 break;
286
287 case MRG_REMOVE:
288 {
289 SHORT x;
290
291 x = (SHORT) WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_QUERYSELECTION,
292 MPFROMSHORT(LIT_FIRST), MPVOID);
293 if (x >= 0)
294 WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_DELETEITEM,
295 MPFROMSHORT(x), MPVOID);
296 }
297 break;
298
299 case MRG_BOTTOM:
300 case MRG_TOP:
301 {
302 SHORT x;
303 CHAR szBuffer[CCHMAXPATH];
304
305 x = (SHORT) WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_QUERYSELECTION,
306 MPFROMSHORT(LIT_FIRST), MPVOID);
307 if (x >= 0) {
308 *szBuffer = 0;
309 WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_QUERYITEMTEXT,
310 MPFROM2SHORT(x, CCHMAXPATH), MPFROMP(szBuffer));
311 if (*szBuffer) {
312 WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_DELETEITEM,
313 MPFROMSHORT(x), MPVOID);
314 if (SHORT1FROMMP(mp1) == MRG_TOP)
315 WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_INSERTITEM,
316 MPFROM2SHORT(0, 0), MPFROMP(szBuffer));
317 else
318 WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_INSERTITEM,
319 MPFROM2SHORT(LIT_END, 0), MPFROMP(szBuffer));
320 }
321 }
322 }
323 break;
324
325 case DID_CANCEL:
326 WinDismissDlg(hwnd, 0);
327 break;
328
329 case IDM_HELP:
330 if (hwndHelp)
331 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
332 MPFROM2SHORT(HELP_MERGE, 0), MPFROMSHORT(HM_RESOURCEID));
333 break;
334
335 case DID_OK:
336 wk = WinQueryWindowPtr(hwnd, QWL_USER);
337 if (wk) {
338 BOOL append, binary;
339 CHAR **list = NULL, **test, szBuffer[CCHMAXPATH];
340 UINT numfiles = 0, numalloc = 0;
341 INT error;
342 SHORT x, y;
343
344 *szBuffer = 0;
345 WinQueryDlgItemText(hwnd, MRG_TARGETNAME, CCHMAXPATH, szBuffer);
346 if (!*szBuffer) {
347 if (!fAlertBeepOff)
348 DosBeep(50, 100);
349 WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, MRG_TARGETNAME));
350 break;
351 }
352 if (DosQueryPathInfo(szBuffer,
353 FIL_QUERYFULLNAME,
354 wk->li->targetpath, CCHMAXPATH)) {
355 if (!fAlertBeepOff)
356 DosBeep(50, 100);
357 WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, MRG_TARGETNAME));
358 break;
359 }
360 WinSetDlgItemText(hwnd, MRG_TARGETNAME, szBuffer);
361 append = WinQueryButtonCheckstate(hwnd, MRG_APPEND);
362 binary = WinQueryButtonCheckstate(hwnd, MRG_BINARY);
363 wk->li->type = (append && binary) ? IDM_MERGEBINARYAPPEND :
364 (append) ? IDM_MERGETEXTAPPEND :
365 (binary) ? IDM_MERGEBINARY : IDM_MERGETEXT;
366 x = (SHORT) WinSendDlgItemMsg(hwnd,
367 MRG_LISTBOX,
368 LM_QUERYITEMCOUNT, MPVOID, MPVOID);
369 for (y = 0; y < x; y++) {
370 *szBuffer = 0;
371 WinSendDlgItemMsg(hwnd,
372 MRG_LISTBOX,
373 LM_QUERYITEMTEXT,
374 MPFROM2SHORT(y, CCHMAXPATH), MPFROMP(szBuffer));
375 if (*szBuffer) {
376 error = AddToList(szBuffer, &list, &numfiles, &numalloc);
377 if (error) {
378 Runtime_Error(pszSrcFile, __LINE__, "AddToList");
379 break;
380 }
381 }
382 }
383 if (numfiles && list && numfiles + 1 < numalloc) {
384 test =
385 xrealloc(list, sizeof(CHAR *) * (numfiles + 1), pszSrcFile,
386 __LINE__);
387 if (test)
388 list = test;
389 }
390 if (!list || !list[0]) {
391 Runtime_Error(pszSrcFile, __LINE__, NULL);
392 break;
393 }
394 else {
395 FreeList(wk->li->list);
396 wk->li->list = list;
397 }
398 }
399 WinDismissDlg(hwnd, 1);
400 break;
401 } // switch WM_COMMAND mp1
402 return 0;
403 } // switch msg
404 return WinDefDlgProc(hwnd, msg, mp1, mp2);
405}
406
407#pragma alloc_text(UUD,UUD,decode,outdec)
408#pragma alloc_text(MERGE,MergeDlgProc)
Note: See TracBrowser for help on using the repository browser.