source: trunk/dll/uudecode.c@ 1228

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

Ticket 187: Moved typedef's and some #define's from fm3dll.h

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