source: trunk/dll/uudecode.c@ 1214

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

Ticket 187: Move data declarations/definitions out of fm3dll.h

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